Skip to content

Commit

Permalink
heuristic for forwarded class parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
lrytz committed Dec 13, 2022
1 parent 12c758e commit 189fc85
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
19 changes: 18 additions & 1 deletion src/compiler/scala/tools/nsc/typechecker/Contexts.scala
Expand Up @@ -1466,10 +1466,27 @@ trait Contexts { self: Analyzer =>
}
if (!defSym.exists) cx = cx.outer // push further outward
}
def forwardedClassParam = lastDef.isParamAccessor && {
val parentClass = lastDef.owner
val templateCtx = thisContext.nextEnclosing(c => c.tree.isInstanceOf[Template] && c.owner.isNonBottomSubClass(parentClass))
templateCtx.owner.superClass == parentClass && {
templateCtx.tree.asInstanceOf[Template].parents.headOption.collect {
case Apply(_, args) => args
} match {
case Some(args) =>
// named args? repeated args?
args.zip(parentClass.primaryConstructor.paramss.headOption.getOrElse(Nil)).exists {
case (arg: Ident, param) => param.name == lastDef.name && arg.symbol == defSym
case _ => false
}
case _ => false
}
}
}
if ((defSym.isAliasType || lastDef.isAliasType) && pre.memberType(defSym) =:= lastPre.memberType(lastDef))
defSym = NoSymbol
if (defSym.isStable && lastDef.isStable &&
(lastPre.memberType(lastDef).termSymbol == defSym || pre.memberType(defSym).termSymbol == lastDef))
(lastPre.memberType(lastDef).termSymbol == defSym || pre.memberType(defSym).termSymbol == lastDef || forwardedClassParam))
defSym = NoSymbol
foundInPrefix = inPrefix && defSym.exists
foundInSuper = foundInPrefix && defSym.owner != cx.owner
Expand Down
9 changes: 8 additions & 1 deletion test/files/neg/t11921-alias.check
Expand Up @@ -12,4 +12,11 @@ If shadowing was intended, write `this.c`.
Or use `-Ylegacy-binding` to enable the previous behavior everywhere.
def n = c // ambiguous
^
2 errors
t11921-alias.scala:65: error: reference to name is ambiguous;
it is both defined in method m and available as value name in class A
Since 2.13.11, symbols inherited from a superclass no longer shadow symbols defined in an outer scope.
If shadowing was intended, write `this.name`.
Or use `-Ylegacy-binding` to enable the previous behavior everywhere.
println(name)
^
3 errors
19 changes: 19 additions & 0 deletions test/files/neg/t11921-alias.scala
Expand Up @@ -47,3 +47,22 @@ object t5 {
}
}
}

object t6 {
class C(val name: String)
object Test {
def m(name: String) = new C(name) {
println(name)
}
}
}

object t7 {
abstract class A(val name: String)
class C(name: String) extends A(name)
object Test {
def m(name: String) = new C(name) {
println(name)
}
}
}

0 comments on commit 189fc85

Please sign in to comment.