Skip to content

Commit 518d6da

Browse files
committed
Verify symbol is a param by querying the reftree
In the HoistSuperArgs phase we have established which tree should be hoisted, and replace all references in the Tree with params that are accessible in the hoisted tree. When the Tree contains an anonymous class without parameters, the paramSyms of that class refer to the created 'fresh' super symbol (e.g. `B$superArg$1`), while the RefTree symbol belongs to the superclass `B`. This meant that the conditional was never satisfied, and the type was never replaced by the primary constructor argument of the generated superArg class. In the current design `treeMap` is called before `typeMap` on a given tree, thus the code in `treeMap` was never executed. This is mitigated by rewriting the check, to only take params or accessors into account in the scope of the hoisted tree.
1 parent ecf134d commit 518d6da

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

compiler/src/dotty/tools/dotc/transform/HoistSuperArgs.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ class HoistSuperArgs extends MiniPhase with IdentityDenotTransformer { thisPhase
116116
case _ => false
117117
}
118118

119+
/** Only rewire types that are owned by the current Hoister and is an param or accessor */
120+
def needsRewire(tp: NamedType) =
121+
(tp.symbol.owner == cls || tp.symbol.owner == constr) && tp.symbol.isParamOrAccessor
122+
119123
// begin hoistSuperArg
120124
arg match {
121125
case Apply(fn, arg1 :: Nil) if fn.symbol == defn.cbnArg =>
@@ -140,7 +144,7 @@ class HoistSuperArgs extends MiniPhase with IdentityDenotTransformer { thisPhase
140144
}
141145
},
142146
treeMap = {
143-
case tree: RefTree if paramSyms.contains(tree.symbol) =>
147+
case tree: RefTree if needsRewire(tree.tpe.asInstanceOf[NamedType]) =>
144148
cpy.Ident(tree)(tree.name).withType(tree.tpe)
145149
case tree =>
146150
tree

tests/pos/i8748.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class A(a: String) extends B(new C {
2+
override def get(): String = a
3+
})
4+
5+
class B(c: C)
6+
7+
trait C {
8+
def get(): String
9+
}

tests/pos/i8786.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class B(y: Int) extends A(new C(y){})
2+
3+
class A(c: C)
4+
5+
abstract class C(y: Int) {
6+
def x: Int = y
7+
}

0 commit comments

Comments
 (0)