Skip to content

Commit cccca68

Browse files
committed
Treat erased members like lazy ones
Partially address TODO on erased members by treating them like lazy values: they do not exist at runtime, and their initialization might fail, but they're realizable if their type is. I do not treat erased members as _final_ lazy ones because erased definitions are not automatically final, and it's not 100% obvious they should be (after discussion with Nicholas Stucki). Current situation: If `U <: T`, the current rules allow the following override ```scala trait A { erased def foo: T = ... } trait B extends A { erased def foo: U = ... } ``` And just like lazy values, `U` might be unrealizable even when `T` is, so it's unsafe to treat `(a: A).foo` as realizable. The above code might be used (questionably) through ```scala def takeErased(erased a: T): Any def takeBetterErased(erased a: U): String def f(a: A) = a match { case b: B => takeBetterErased(b.foo) case _ => takeErased(a.foo) } ``` It's very unclear whether that's desirable. Alternatively, concrete erased definitions might be made automatically final, and that would be picked up by `isEffectivelyFinal` without further changes.
1 parent bdfdc24 commit cccca68

File tree

2 files changed

+3
-5
lines changed

2 files changed

+3
-5
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ class CheckRealizable(implicit ctx: Context) {
8888
// Reject fields that are mutable, by-name, and similar.
8989
if (!sym.isStableMember)
9090
patchRealizability(NotStable)
91-
// 3. If the symbol isn't "lazy" and its prefix is realizable
92-
else if (!isLateInitialized(sym)) {
91+
// 3. If the symbol isn't "lazy" or erased, and its prefix is realizable
92+
else if (!isLateInitialized(sym) && !sym.is(Erased)) {
9393
// The symbol itself is stable, cache this information:
9494
sym.setFlag(Stable)
9595
// Realizability now depends on the prefix:

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

+1-3
Original file line numberDiff line numberDiff line change
@@ -475,9 +475,7 @@ object Flags {
475475

476476
/** A value that's unstable unless complemented with a Stable flag */
477477
final val UnstableValue =
478-
Mutable | Method | Erased
479-
// TODO: Erased should be treated as stable just like final lazy is.
480-
// Otherwise the usefulness of Erased is very much reduced.
478+
Mutable | Method
481479

482480
/** Flags that express the variance of a type parameter. */
483481
final val VarianceFlags = Covariant | Contravariant

0 commit comments

Comments
 (0)