Skip to content

Commit 8244f4c

Browse files
authored
Merge branch 'master' into existentialTypesMigrateErrorMessage
2 parents 44b8b5c + 098c50a commit 8244f4c

File tree

8 files changed

+91
-14
lines changed

8 files changed

+91
-14
lines changed

compiler/src/dotty/tools/dotc/core/Symbols.scala

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -316,25 +316,35 @@ trait Symbols { this: Context =>
316316
newNakedSymbol[original.ThisName](original.coord)
317317
}
318318
val ttmap1 = ttmap.withSubstitution(originals, copies)
319-
(originals, copies).zipped foreach {(original, copy) =>
320-
copy.denot = original.denot // preliminary denotation, so that we can access symbols in subsequent transform
321-
}
322-
(originals, copies).zipped foreach {(original, copy) =>
319+
(originals, copies).zipped foreach { (original, copy) =>
323320
val odenot = original.denot
324321
val oinfo = original.info match {
325322
case ClassInfo(pre, _, parents, decls, selfInfo) =>
326323
assert(original.isClass)
327324
ClassInfo(pre, copy.asClass, parents, decls.cloneScope, selfInfo)
328325
case oinfo => oinfo
329326
}
327+
328+
val completer = new LazyType {
329+
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
330+
denot.info = oinfo // needed as otherwise we won't be able to go from Sym -> parents & etc
331+
// Note that this is a hack, but hack commonly used in Dotty
332+
// The same thing is done by other completers all the time
333+
denot.info = ttmap1.mapType(oinfo)
334+
denot.annotations = odenot.annotations.mapConserve(ttmap1.apply)
335+
}
336+
}
337+
330338
copy.denot = odenot.copySymDenotation(
331339
symbol = copy,
332340
owner = ttmap1.mapOwner(odenot.owner),
333-
initFlags = odenot.flags &~ Frozen | Fresh,
334-
info = ttmap1.mapType(oinfo),
341+
initFlags = odenot.flags &~ (Frozen | Touched) | Fresh,
342+
info = completer,
335343
privateWithin = ttmap1.mapOwner(odenot.privateWithin), // since this refers to outer symbols, need not include copies (from->to) in ownermap here.
336-
annotations = odenot.annotations.mapConserve(ttmap1.apply))
344+
annotations = odenot.annotations)
345+
337346
}
347+
338348
copies
339349
}
340350

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

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,19 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf
8181
!needsOuterAlways(cls) &&
8282
impl.existsSubTree(referencesOuter(cls, _)))
8383
ensureOuterAccessors(cls)
84-
if (hasOuter(cls)) {
84+
85+
val clsHasOuter = hasOuter(cls)
86+
if (clsHasOuter || cls.mixins.exists(needsOuterIfReferenced)) {
8587
val newDefs = new mutable.ListBuffer[Tree]
86-
if (isTrait)
87-
newDefs += DefDef(outerAccessor(cls).asTerm, EmptyTree)
88-
else {
89-
val outerParamAcc = outerParamAccessor(cls)
90-
newDefs += ValDef(outerParamAcc, EmptyTree)
91-
newDefs += DefDef(outerAccessor(cls).asTerm, ref(outerParamAcc))
88+
89+
if (clsHasOuter) {
90+
if (isTrait)
91+
newDefs += DefDef(outerAccessor(cls).asTerm, EmptyTree)
92+
else {
93+
val outerParamAcc = outerParamAccessor(cls)
94+
newDefs += ValDef(outerParamAcc, EmptyTree)
95+
newDefs += DefDef(outerAccessor(cls).asTerm, ref(outerParamAcc))
96+
}
9297
}
9398

9499
for (parentTrait <- cls.mixins) {
@@ -181,6 +186,7 @@ object ExplicitOuter {
181186
private def needsOuterAlways(cls: ClassSymbol)(implicit ctx: Context): Boolean =
182187
needsOuterIfReferenced(cls) &&
183188
(!hasLocalInstantiation(cls) || // needs outer because we might not know whether outer is referenced or not
189+
cls.mixins.exists(needsOuterIfReferenced) || // needs outer for parent traits
184190
cls.classInfo.parents.exists(parent => // needs outer to potentially pass along to parent
185191
needsOuterIfReferenced(parent.classSymbol.asClass)))
186192

tests/pos/i1812.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class FF[R] {
2+
def compose(): R = ???
3+
}
4+
5+
class Test(x: Int) extends AnyVal {
6+
def method: Unit = {
7+
class Bla
8+
class Foo extends FF[Bla] {
9+
override def compose() = super[FF].compose()
10+
}
11+
}
12+
}

tests/pos/i1812b.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class FF[R] {
2+
def compose(): R = ???
3+
}
4+
5+
class Test(x: Int) extends AnyVal {
6+
def method: Unit = {
7+
class Bla{ def bar:a.S = ???}
8+
trait TRT{ type S}
9+
val a: TRT = ???
10+
}
11+
}

tests/run/i1820.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a

tests/run/i1820.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class A {
2+
val a = "a"
3+
trait Inner {
4+
def f = println(a)
5+
def h = 3
6+
}
7+
}
8+
9+
class Inner extends Test.a.Inner
10+
11+
object Test {
12+
val a = new A
13+
14+
def main(args: Array[String]): Unit = {
15+
(new Inner).f
16+
}
17+
}

tests/run/i1820b.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a

tests/run/i1820b.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
trait A {
2+
val a = "a"
3+
trait Inner {
4+
def f = println(a)
5+
def h = 3
6+
}
7+
}
8+
9+
trait B extends A {
10+
trait Inner2 extends Inner
11+
def g = new Inner2 {}
12+
}
13+
14+
object Test {
15+
def main(args: Array[String]): Unit = {
16+
val b = new B {}
17+
b.g.f
18+
}
19+
}

0 commit comments

Comments
 (0)