From a24218a1434d368f8a3a68f4162a8c24cae91bc3 Mon Sep 17 00:00:00 2001 From: Abel Nieto Date: Mon, 26 Nov 2018 17:17:48 -0500 Subject: [PATCH 1/3] Fix #5521: prefix not checked in realizability check We were forgetting to check the prefix in the uncached case. --- .../src/dotty/tools/dotc/core/CheckRealizable.scala | 7 +++++-- tests/neg/i5521.scala | 12 ++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 tests/neg/i5521.scala diff --git a/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala b/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala index 774cc233bff8..13ed730d5729 100644 --- a/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala +++ b/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala @@ -77,8 +77,11 @@ class CheckRealizable(implicit ctx: Context) { else if (!isLateInitialized(sym)) realizability(tp.prefix) else if (!sym.isEffectivelyFinal) new NotFinal(sym) else realizability(tp.info).mapError(r => new ProblemInUnderlying(tp.info, r)) - if (r == Realizable) sym.setFlag(Stable) - r + val r1 = if (r == Realizable) { + sym.setFlag(Stable) + realizability(tp.prefix) + } else r + r1 } case _: SingletonType | NoPrefix => Realizable diff --git a/tests/neg/i5521.scala b/tests/neg/i5521.scala new file mode 100644 index 000000000000..9edb43605036 --- /dev/null +++ b/tests/neg/i5521.scala @@ -0,0 +1,12 @@ +class Hello { + class Foo { + class Bar + final lazy val s: Bar = ??? + } + + lazy val foo: Foo = ??? + + val x: foo.s.type = ??? // error: `foo` must be final since it's a lazy val + val x2: foo.s.type = ??? // error: `foo` must be final since it's a lazy val +} + From b66bcfe519325098d55012bc3ed549114a46f40a Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Thu, 29 Nov 2018 23:56:26 +0100 Subject: [PATCH 2/3] Don't check prefix twice This change also caches stability for the affected code path. --- compiler/src/dotty/tools/dotc/core/CheckRealizable.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala b/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala index 13ed730d5729..57ad3bb08351 100644 --- a/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala +++ b/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala @@ -74,7 +74,7 @@ class CheckRealizable(implicit ctx: Context) { else { val r = if (!sym.isStable) NotStable - else if (!isLateInitialized(sym)) realizability(tp.prefix) + else if (!isLateInitialized(sym)) Realizable else if (!sym.isEffectivelyFinal) new NotFinal(sym) else realizability(tp.info).mapError(r => new ProblemInUnderlying(tp.info, r)) val r1 = if (r == Realizable) { From 0eea5b3f7c96dc905fc861bac337236495e76d7f Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Fri, 30 Nov 2018 00:00:16 +0100 Subject: [PATCH 3/3] Clean up with andAlso combinator --- compiler/src/dotty/tools/dotc/core/CheckRealizable.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala b/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala index 57ad3bb08351..788b6d474999 100644 --- a/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala +++ b/compiler/src/dotty/tools/dotc/core/CheckRealizable.scala @@ -77,11 +77,10 @@ class CheckRealizable(implicit ctx: Context) { else if (!isLateInitialized(sym)) Realizable else if (!sym.isEffectivelyFinal) new NotFinal(sym) else realizability(tp.info).mapError(r => new ProblemInUnderlying(tp.info, r)) - val r1 = if (r == Realizable) { + r andAlso { sym.setFlag(Stable) realizability(tp.prefix) - } else r - r1 + } } case _: SingletonType | NoPrefix => Realizable