From 05cb6297074c658d2b3a8577a7a70d9ecbd65d67 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" <p.giarrusso@gmail.com> Date: Sun, 2 Dec 2018 15:06:33 +0100 Subject: [PATCH 1/4] Show that Any#L is still rejected when written by the user This tests that b3dd07cc068d4ad6f74ba4321b325170653d3cb6 is not *too* liberal. --- tests/neg/i4031-anysel.scala | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/neg/i4031-anysel.scala 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 +} From 632f79269f6a0fcb53d6941fe2214154b72707e2 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" <p.giarrusso@gmail.com> Date: Wed, 16 Jan 2019 16:24:34 +0100 Subject: [PATCH 2/4] Singletons of mutable vars with singleton types are realizable Such a "variable" can only have one value, so this is okay. This goes back to 9125f580d44462fbb0f81ce8cdd7344e5cee51d1. --- .../src/dotty/tools/dotc/core/CheckRealizable.scala | 5 ++++- tests/pos/realizable-mut.scala | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tests/pos/realizable-mut.scala 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/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 +} From d3ac612bc245b614953b69732a06da1e03e56758 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" <p.giarrusso@gmail.com> Date: Tue, 10 Apr 2018 20:54:03 +0200 Subject: [PATCH 3/4] Add stress-test for realizability checking I wrote this because I feared (incorrectly) exponential slowdowns in realizability checking for this code. But debugging suggests that the complexity of realizability checking is constant in the size of these expressions (even after I disable caching of `Stable`). Beware 1: these expressions almost smash the stack by sheer size. Beware 2: this fails with `-Yno-deep-subtypes`, but simply because the checking heuristics assumes people don't try to do this. Beware 3: this also depends on unstable members with singletons types being stable. --- tests/pos-deep-subtype/i4036.scala | 64 ++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 tests/pos-deep-subtype/i4036.scala diff --git a/tests/pos-deep-subtype/i4036.scala b/tests/pos-deep-subtype/i4036.scala new file mode 100644 index 000000000000..df06ad9b3b3c --- /dev/null +++ b/tests/pos-deep-subtype/i4036.scala @@ -0,0 +1,64 @@ +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.x.x.x.x.x.x.x.x.x.x.x.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.x.x.x.x.x.x.x.x.x.x.x.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 +} From 0ee31f4e6f3c654b1aa2bf230aa31b91784fe2b5 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" <p.giarrusso@gmail.com> Date: Thu, 17 Jan 2019 01:10:40 +0100 Subject: [PATCH 4/4] Stop stack overflows in testing Stack consumption grew apparently. --- tests/pos-deep-subtype/i4036.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/pos-deep-subtype/i4036.scala b/tests/pos-deep-subtype/i4036.scala index df06ad9b3b3c..1784a9189fab 100644 --- a/tests/pos-deep-subtype/i4036.scala +++ b/tests/pos-deep-subtype/i4036.scala @@ -14,7 +14,6 @@ object A { x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. - x.x.x.x.x.x.x.x.x.x.x.x.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. @@ -29,7 +28,6 @@ object A { x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x. - x.x.x.x.x.x.x.x.x.x.x.x.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 }