Skip to content

Commit 66f335c

Browse files
authored
Merge pull request #8805 from DieBauer/fix/issue-8748
Fix #8748: Verify symbol is a param by querying the reftree
2 parents 5f2f66a + ca5b28f commit 66f335c

File tree

5 files changed

+29
-8
lines changed

5 files changed

+29
-8
lines changed

compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class TreeTypeMap(
9191
case id: Ident if tpd.needsSelect(id.tpe) =>
9292
ref(id.tpe.asInstanceOf[TermRef]).withSpan(id.span)
9393
case ddef @ DefDef(name, tparams, vparamss, tpt, _) =>
94-
val (tmap1, tparams1) = transformDefs(ddef.tparams)
94+
val (tmap1, tparams1) = transformDefs(tparams)
9595
val (tmap2, vparamss1) = tmap1.transformVParamss(vparamss)
9696
val res = cpy.DefDef(ddef)(name, tparams1, vparamss1, tmap2.transform(tpt), tmap2.transform(ddef.rhs))
9797
res.symbol.setParamssFromDefs(tparams1, vparamss1)

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ object HoistSuperArgs {
3333
*
3434
* An argument is complex if it contains a method or template definition, a this or a new,
3535
* or it contains an identifier which needs a `this` prefix to be accessed. This is the case
36-
* if the identifer neither a global reference nor a reference to a parameter of the enclosing class.
36+
* if the identifier has neither a global reference nor a reference to a parameter of the enclosing class.
3737
* @see needsHoist for an implementation.
3838
*
3939
* A hoisted argument definition gets the parameters of the class it is hoisted from
@@ -116,21 +116,26 @@ 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: Type) = tp match {
121+
case ntp: NamedType =>
122+
(ntp.symbol.owner == cls || ntp.symbol.owner == constr) && ntp.symbol.isParamOrAccessor
123+
case _ => false
124+
}
125+
119126
// begin hoistSuperArg
120127
arg match {
121128
case Apply(fn, arg1 :: Nil) if fn.symbol == defn.cbnArg =>
122129
cpy.Apply(arg)(fn, hoistSuperArg(arg1, cdef) :: Nil)
123-
case _ if (arg.existsSubTree(needsHoist)) =>
130+
case _ if arg.existsSubTree(needsHoist) =>
124131
val superMeth = newSuperArgMethod(arg.tpe)
125132
val superArgDef = polyDefDef(superMeth, trefs => vrefss => {
126133
val paramSyms = trefs.map(_.typeSymbol) ::: vrefss.flatten.map(_.symbol)
127134
val tmap = new TreeTypeMap(
128135
typeMap = new TypeMap {
129136
lazy val origToParam = origParams.zip(paramSyms).toMap
130137
def apply(tp: Type) = tp match {
131-
case tp: NamedType
132-
if (tp.symbol.owner == cls || tp.symbol.owner == constr) &&
133-
tp.symbol.isParamOrAccessor =>
138+
case tp: NamedType if needsRewire(tp) =>
134139
origToParam.get(tp.symbol) match {
135140
case Some(mappedSym) => if (tp.symbol.isType) mappedSym.typeRef else mappedSym.termRef
136141
case None => mapOver(tp)
@@ -140,7 +145,7 @@ class HoistSuperArgs extends MiniPhase with IdentityDenotTransformer { thisPhase
140145
}
141146
},
142147
treeMap = {
143-
case tree: RefTree if paramSyms.contains(tree.symbol) =>
148+
case tree: RefTree if needsRewire(tree.tpe) =>
144149
cpy.Ident(tree)(tree.name).withType(tree.tpe)
145150
case tree =>
146151
tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import MegaPhase.MiniPhase
1010
import config.Printers.transforms
1111

1212
/** Add accessors for all protected accesses. An accessor is needed if
13-
* according to the rules of the JVM a protected class member is not accesissible
13+
* according to the rules of the JVM a protected class member is not accessible
1414
* from the point of access, but is accessible if the access is from an enclosing
1515
* class. In this point a public access method is placed in that enclosing class.
1616
*/

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)