Skip to content

Commit

Permalink
Avoid parameter name clashes in export forwarders
Browse files Browse the repository at this point in the history
  • Loading branch information
odersky committed Feb 19, 2022
1 parent 8e529b1 commit 42e470f
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
27 changes: 22 additions & 5 deletions compiler/src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1170,11 +1170,28 @@ class Namer { typer: Typer =>
then
(StableRealizable, ExprType(pathType.select(sym)))
else
def addPathMethodParams(pt: Type, info: Type): Type = pt match
case pt: MethodOrPoly =>
pt.derivedLambdaType(resType = addPathMethodParams(pt.resType, info))
case _ =>
info
def addPathMethodParams(pathType: Type, info: Type): Type =
def defines(pt: Type, pname: Name): Boolean = pt match
case pt: MethodOrPoly =>
pt.paramNames.contains(pname) || defines(pt.resType, pname)
case _ =>
false
def avoidNameClashes(info: Type): Type = info match
case info: MethodOrPoly =>
info.derivedLambdaType(
paramNames = info.paramNames.mapConserve {
pname => if defines(pathType, pname) then pname.freshened else pname
},
resType = avoidNameClashes(info.resType))
case info =>
info
def wrap(pt: Type, info: Type): Type = pt match
case pt: MethodOrPoly =>
pt.derivedLambdaType(resType = wrap(pt.resType, info))
case _ =>
info
wrap(pathType, avoidNameClashes(info))

val mbrInfo =
if pathMethod.exists
then addPathMethodParams(pathMethod.info, mbr.info.widenExpr)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2571,7 +2571,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
val selectors1 = typedSelectors(exp.selectors)
assignType(cpy.Export(exp)(expr1, selectors1))
case _ =>
errorTree(exp, em"exports are only allowed from objects and classes")
errorTree(exp, em"exports are only allowed from objects and classes, they can not belong to local blocks")

def typedPackageDef(tree: untpd.PackageDef)(using Context): Tree =
val pid1 = withMode(Mode.InPackageClauseName)(typedExpr(tree.pid, AnySelectionProto))
Expand Down
7 changes: 7 additions & 0 deletions tests/pos/export-in-extension-rename.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Ops[A](xs: List[A]):
def map[B](x: A => B): List[B] = ???

extension [B](x: List[B])
private def ops = new Ops[B](x)
export ops.map // `x` and `B` should not appear twice as a parameter

0 comments on commit 42e470f

Please sign in to comment.