Skip to content

Commit 42e470f

Browse files
committed
Avoid parameter name clashes in export forwarders
1 parent 8e529b1 commit 42e470f

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

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

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,11 +1170,28 @@ class Namer { typer: Typer =>
11701170
then
11711171
(StableRealizable, ExprType(pathType.select(sym)))
11721172
else
1173-
def addPathMethodParams(pt: Type, info: Type): Type = pt match
1174-
case pt: MethodOrPoly =>
1175-
pt.derivedLambdaType(resType = addPathMethodParams(pt.resType, info))
1176-
case _ =>
1177-
info
1173+
def addPathMethodParams(pathType: Type, info: Type): Type =
1174+
def defines(pt: Type, pname: Name): Boolean = pt match
1175+
case pt: MethodOrPoly =>
1176+
pt.paramNames.contains(pname) || defines(pt.resType, pname)
1177+
case _ =>
1178+
false
1179+
def avoidNameClashes(info: Type): Type = info match
1180+
case info: MethodOrPoly =>
1181+
info.derivedLambdaType(
1182+
paramNames = info.paramNames.mapConserve {
1183+
pname => if defines(pathType, pname) then pname.freshened else pname
1184+
},
1185+
resType = avoidNameClashes(info.resType))
1186+
case info =>
1187+
info
1188+
def wrap(pt: Type, info: Type): Type = pt match
1189+
case pt: MethodOrPoly =>
1190+
pt.derivedLambdaType(resType = wrap(pt.resType, info))
1191+
case _ =>
1192+
info
1193+
wrap(pathType, avoidNameClashes(info))
1194+
11781195
val mbrInfo =
11791196
if pathMethod.exists
11801197
then addPathMethodParams(pathMethod.info, mbr.info.widenExpr)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2571,7 +2571,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
25712571
val selectors1 = typedSelectors(exp.selectors)
25722572
assignType(cpy.Export(exp)(expr1, selectors1))
25732573
case _ =>
2574-
errorTree(exp, em"exports are only allowed from objects and classes")
2574+
errorTree(exp, em"exports are only allowed from objects and classes, they can not belong to local blocks")
25752575

25762576
def typedPackageDef(tree: untpd.PackageDef)(using Context): Tree =
25772577
val pid1 = withMode(Mode.InPackageClauseName)(typedExpr(tree.pid, AnySelectionProto))
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Ops[A](xs: List[A]):
2+
def map[B](x: A => B): List[B] = ???
3+
4+
extension [B](x: List[B])
5+
private def ops = new Ops[B](x)
6+
export ops.map // `x` and `B` should not appear twice as a parameter
7+

0 commit comments

Comments
 (0)