Skip to content

Commit f3f8ae6

Browse files
authored
Dealias before checking for outer references in types (#16525)
Fixes #15827
2 parents 4d9a0a0 + 71c90ff commit f3f8ae6

File tree

3 files changed

+61
-5
lines changed

3 files changed

+61
-5
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,6 @@ object ExplicitOuter {
256256
*/
257257
def referencesOuter(cls: Symbol, tree: Tree)(using Context): Boolean =
258258

259-
260259
val test = new TreeAccumulator[Boolean]:
261260
private var inInline = false
262261

@@ -302,19 +301,20 @@ object ExplicitOuter {
302301
def containsOuterRefs(t: Tree): Boolean = t match
303302
case _: This | _: Ident => isOuterRef(t.tpe)
304303
case nw: New =>
305-
val newCls = nw.tpe.classSymbol
304+
val newType = nw.tpe.dealias
305+
val newCls = newType.classSymbol
306306
isOuterSym(newCls.owner.enclosingClass) ||
307-
hasOuterPrefix(nw.tpe) ||
307+
hasOuterPrefix(newType) ||
308308
newCls.owner.isTerm && cls.isProperlyContainedIn(newCls)
309309
// newCls might get proxies for free variables. If current class is
310310
// properly contained in newCls, it needs an outer path to newCls access the
311311
// proxies and forward them to the new instance.
312312
case app: TypeApply if app.symbol.isTypeTest =>
313313
// Type tests of singletons translate to `eq` tests with references, which might require outer pointers
314-
containsOuterRefsAtTopLevel(app.args.head.tpe)
314+
containsOuterRefsAtTopLevel(app.args.head.tpe.dealias)
315315
case t: TypeTree if inInline =>
316316
// Expansions of inline methods must be able to address outer types
317-
containsOuterRefsAnywhere(t.tpe)
317+
containsOuterRefsAnywhere(t.tpe.dealias)
318318
case _ =>
319319
false
320320

compiler/test/dotc/pos-test-pickling.blacklist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ i9999.scala
4545
i6505.scala
4646
i15158.scala
4747
i15155.scala
48+
i15827.scala
4849

4950
# Opaque type
5051
i5720.scala

tests/pos/i15827.scala

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
2+
trait Mirr {
3+
type MirroredTp
4+
type Elems <: Tuple
5+
}
6+
trait MirrP extends Mirr {
7+
def fromProduct(x: Product): MirroredTp
8+
}
9+
trait MirrS extends Mirr
10+
11+
def outer3Local = {
12+
class Wrapper {
13+
object Nested {
14+
sealed trait Color
15+
}
16+
}
17+
val wrapper = new Wrapper
18+
import wrapper.Nested.Color
19+
20+
object Inner {
21+
case object Red extends Color
22+
case object Green extends Color
23+
case object Blue extends Color
24+
case class Rgb(hex: Int) extends Color
25+
case object Rgb
26+
}
27+
28+
object CallSite {
29+
def run =
30+
import Inner.*
31+
val M: (MirrS { type MirroredTp = Color; type Elems = (Inner.Red.type, Inner.Green.type, Inner.Blue.type, Inner.Rgb) }) =
32+
new MirrS {
33+
type MirroredTp = Color
34+
type Elems = (Inner.Red.type, Inner.Green.type, Inner.Blue.type, Inner.Rgb)
35+
}
36+
37+
val M_Rgb =
38+
type TRgb = Tuple.Elem[M.Elems, 3]
39+
new MirrP {
40+
type MirroredTp = TRgb
41+
type Elems = Int *: EmptyTuple
42+
43+
def fromProduct(x: Product): MirroredTp =
44+
new TRgb(x.productElement(0).asInstanceOf[Int])
45+
}: (MirrP {
46+
type MirroredTp = TRgb
47+
type Elems = Int *: EmptyTuple
48+
})
49+
}
50+
51+
CallSite.run
52+
}
53+
54+
@main def Test =
55+
outer3Local

0 commit comments

Comments
 (0)