Skip to content

Commit dec36c1

Browse files
som-snytttgodzik
authored andcommitted
Respect export alias for default arg forwarder
[Cherry-picked 4db7df7]
1 parent 5553618 commit dec36c1

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

compiler/src/dotty/tools/dotc/typer/Namer.scala

+12-12
Original file line numberDiff line numberDiff line change
@@ -1176,20 +1176,21 @@ class Namer { typer: Typer =>
11761176
Yes
11771177
}
11781178

1179-
def foreachDefaultGetterOf(sym: TermSymbol, op: TermSymbol => Unit): Unit =
1179+
def foreachDefaultGetterOf(sym: TermSymbol, alias: TermName)(op: (TermSymbol, TermName) => Unit): Unit =
11801180
var n = 0
1181-
val methodName =
1182-
if sym.name == nme.apply && sym.is(Synthetic) && sym.owner.companionClass.is(Case) then
1183-
// The synthesized `apply` methods of case classes use the constructor's default getters
1184-
nme.CONSTRUCTOR
1185-
else sym.name
1181+
// The synthesized `apply` methods of case classes use the constructor's default getters
1182+
val useConstructor = sym.name == nme.apply && sym.is(Synthetic) && sym.owner.companionClass.is(Case)
1183+
val methodName = if useConstructor then nme.CONSTRUCTOR else sym.name
1184+
val aliasedName = if useConstructor then nme.CONSTRUCTOR else alias
1185+
val useAliased = !useConstructor && methodName != aliasedName
11861186
for params <- sym.paramSymss; param <- params do
11871187
if param.isTerm then
11881188
if param.is(HasDefault) then
11891189
val getterName = DefaultGetterName(methodName, n)
11901190
val getter = pathType.member(getterName).symbol
11911191
assert(getter.exists, i"$path does not have a default getter named $getterName")
1192-
op(getter.asTerm)
1192+
val targetName = if useAliased then DefaultGetterName(aliasedName, n) else getterName
1193+
op(getter.asTerm, targetName)
11931194
n += 1
11941195

11951196
/** Add a forwarder with name `alias` or its type name equivalent to `mbr`,
@@ -1310,9 +1311,8 @@ class Namer { typer: Typer =>
13101311
})
13111312
buf += ddef.withSpan(span)
13121313
if hasDefaults then
1313-
foreachDefaultGetterOf(sym.asTerm,
1314-
getter => addForwarder(
1315-
getter.name.asTermName, getter.asSeenFrom(path.tpe), span))
1314+
foreachDefaultGetterOf(sym.asTerm, alias): (getter, getterName) =>
1315+
addForwarder(getterName, getter.asSeenFrom(path.tpe), span)
13161316

13171317
// adding annotations and flags at the parameter level
13181318
// TODO: This probably needs to be filtered to avoid adding some annotation
@@ -1367,13 +1367,13 @@ class Namer { typer: Typer =>
13671367
addWildcardForwardersNamed(alias, span)
13681368

13691369
def addForwarders(sels: List[untpd.ImportSelector], seen: List[TermName]): Unit = sels match
1370-
case sel :: sels1 =>
1370+
case sel :: sels =>
13711371
if sel.isWildcard then
13721372
addWildcardForwarders(seen, sel.span)
13731373
else
13741374
if sel.rename != nme.WILDCARD then
13751375
addForwardersNamed(sel.name, sel.rename, sel.span)
1376-
addForwarders(sels1, sel.name :: seen)
1376+
addForwarders(sels, sel.name :: seen)
13771377
case _ =>
13781378

13791379
/** Avoid a clash of export forwarder `forwarder` with other forwarders in `forwarders`.

tests/run/i19587.scala

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
case class Foo(bar: String, baz: Int)
2+
object Foo:
3+
def withDefaults(bar: String = "", baz: Int = 42) = Foo(bar, baz)
4+
5+
object Test1:
6+
export Foo.withDefaults
7+
8+
object Test2:
9+
export Foo.withDefaults as fooWithDefaults
10+
11+
class Bar:
12+
infix def bar(other: Bar) = 42
13+
14+
object Baz:
15+
val b = Bar()
16+
export b.bar
17+
export b.bar as baz
18+
19+
@main def Test =
20+
// this works
21+
assert:
22+
Test1.withDefaults("test1") == Foo("test1", 42)
23+
24+
// this doesn't work
25+
assert:
26+
Test2.fooWithDefaults("test2") == Foo("test2", 42)
27+
28+
val b = Bar()
29+
println:
30+
b bar Bar()
31+
println:
32+
Baz bar Bar()
33+
println:
34+
Baz baz Bar()

0 commit comments

Comments
 (0)