Skip to content

Commit 4db7df7

Browse files
committed
Respect export alias for default arg forwarder
1 parent 96a3c11 commit 4db7df7

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
@@ -1223,20 +1223,21 @@ class Namer { typer: Typer =>
12231223
Yes
12241224
}
12251225

1226-
def foreachDefaultGetterOf(sym: TermSymbol, op: TermSymbol => Unit): Unit =
1226+
def foreachDefaultGetterOf(sym: TermSymbol, alias: TermName)(op: (TermSymbol, TermName) => Unit): Unit =
12271227
var n = 0
1228-
val methodName =
1229-
if sym.name == nme.apply && sym.is(Synthetic) && sym.owner.companionClass.is(Case) then
1230-
// The synthesized `apply` methods of case classes use the constructor's default getters
1231-
nme.CONSTRUCTOR
1232-
else sym.name
1228+
// The synthesized `apply` methods of case classes use the constructor's default getters
1229+
val useConstructor = sym.name == nme.apply && sym.is(Synthetic) && sym.owner.companionClass.is(Case)
1230+
val methodName = if useConstructor then nme.CONSTRUCTOR else sym.name
1231+
val aliasedName = if useConstructor then nme.CONSTRUCTOR else alias
1232+
val useAliased = !useConstructor && methodName != aliasedName
12331233
for params <- sym.paramSymss; param <- params do
12341234
if param.isTerm then
12351235
if param.is(HasDefault) then
12361236
val getterName = DefaultGetterName(methodName, n)
12371237
val getter = pathType.member(getterName).symbol
12381238
assert(getter.exists, i"$path does not have a default getter named $getterName")
1239-
op(getter.asTerm)
1239+
val targetName = if useAliased then DefaultGetterName(aliasedName, n) else getterName
1240+
op(getter.asTerm, targetName)
12401241
n += 1
12411242

12421243
/** Add a forwarder with name `alias` or its type name equivalent to `mbr`,
@@ -1358,9 +1359,8 @@ class Namer { typer: Typer =>
13581359
})
13591360
buf += ddef.withSpan(span)
13601361
if hasDefaults then
1361-
foreachDefaultGetterOf(sym.asTerm,
1362-
getter => addForwarder(
1363-
getter.name.asTermName, getter.asSeenFrom(path.tpe), span))
1362+
foreachDefaultGetterOf(sym.asTerm, alias): (getter, getterName) =>
1363+
addForwarder(getterName, getter.asSeenFrom(path.tpe), span)
13641364

13651365
// adding annotations and flags at the parameter level
13661366
// TODO: This probably needs to be filtered to avoid adding some annotation
@@ -1415,13 +1415,13 @@ class Namer { typer: Typer =>
14151415
addWildcardForwardersNamed(alias, span)
14161416

14171417
def addForwarders(sels: List[untpd.ImportSelector], seen: List[TermName]): Unit = sels match
1418-
case sel :: sels1 =>
1418+
case sel :: sels =>
14191419
if sel.isWildcard then
14201420
addWildcardForwarders(seen, sel.span)
14211421
else
14221422
if !sel.isUnimport then
14231423
addForwardersNamed(sel.name, sel.rename, sel.span)
1424-
addForwarders(sels1, sel.name :: seen)
1424+
addForwarders(sels, sel.name :: seen)
14251425
case _ =>
14261426

14271427
/** 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)