diff --git a/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala b/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala index 57dc1bcb5af9..6c6716bb1af3 100644 --- a/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala +++ b/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala @@ -68,6 +68,7 @@ class CheckRealizable(implicit ctx: Context) { def realizability(tp: Type): Realizability = tp.dealias match { case tp: TermRef => val sym = tp.symbol + lazy val tpInfoRealizable = realizability(tp.info) if (sym.is(Stable)) realizability(tp.prefix) else { val r = @@ -80,10 +81,12 @@ class CheckRealizable(implicit ctx: Context) { else // otherwise we need to look at the info to determine realizability // roughly: it's realizable if the info does not have bad bounds - realizability(tp.info).mapError(r => new ProblemInUnderlying(tp, r)) + tpInfoRealizable.mapError(r => new ProblemInUnderlying(tp, r)) r andAlso { if (sym.isStable) sym.setFlag(Stable) // it's known to be stable and realizable realizability(tp.prefix) + } mapError { r => + if (tp.info.isStable && tpInfoRealizable == Realizable) Realizable else r } } case _: SingletonType | NoPrefix => diff --git a/tests/neg/i4031-anysel.scala b/tests/neg/i4031-anysel.scala new file mode 100644 index 000000000000..c97209733375 --- /dev/null +++ b/tests/neg/i4031-anysel.scala @@ -0,0 +1,3 @@ +object Test { + val v: Any = 1: Any#L // error +} diff --git a/tests/pos-deep-subtype/i4036.scala b/tests/pos-deep-subtype/i4036.scala new file mode 100644 index 000000000000..1784a9189fab --- /dev/null +++ b/tests/pos-deep-subtype/i4036.scala @@ -0,0 +1,62 @@ +trait A { def x: this.type = this; type T } +trait B { def y: this.type = this; def x: y.type = y; type T } +object A { + val v = new A { type T = Int } + v: v. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.type + + 1: v. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.T + + val u = new B { type T = Int } + u: u. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. + x.type + + val z = new B { type T = this.type } + z: z.T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T# + T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T +} diff --git a/tests/pos/realizable-mut.scala b/tests/pos/realizable-mut.scala new file mode 100644 index 000000000000..599fbd90cd47 --- /dev/null +++ b/tests/pos/realizable-mut.scala @@ -0,0 +1,13 @@ +object Foo { + val x = new Object + + class A(var y: x.type) + + val a = new A(x) + + val y: a.y.type = x +// 1 |val y: a.y.type = x +// | ^ +// | Object(x)(a.y) is not a legal path +// | since it refers to nonfinal variable y +}