@@ -50,7 +50,15 @@ object CheckRealizable {
50
50
private val LateInitialized = Lazy | Erased
51
51
}
52
52
53
- /** Compute realizability status */
53
+ /** Compute realizability status.
54
+ *
55
+ * A type T is realizable iff it is inhabited by non-null values. This ensures that its type members have good bounds
56
+ * (in the sense from DOT papers). A type projection T#L is legal if T is realizable, and can be understood as
57
+ * Scala 2's `v.L forSome { val v: T }`.
58
+ *
59
+ * In general, a realizable type can have multiple inhabitants, hence it need not be stable (in the sense of
60
+ * Type.isStable).
61
+ */
54
62
class CheckRealizable (implicit ctx : Context ) {
55
63
import CheckRealizable ._
56
64
@@ -66,6 +74,15 @@ class CheckRealizable(implicit ctx: Context) {
66
74
67
75
/** The realizability status of given type `tp`*/
68
76
def realizability (tp : Type ): Realizability = tp.dealias match {
77
+ /*
78
+ * A `TermRef` for a path `p` is realizable if
79
+ * - `p`'s type is stable and realizable, or
80
+ * - its underlying path is idempotent (that is, *stable*), total, and not null.
81
+ * We don't check yet the "not null" clause: that will require null-safety checking.
82
+ *
83
+ * We assume that stability of tp.prefix is checked elsewhere, since that's necessary for the path to be legal in
84
+ * the first place.
85
+ */
69
86
case tp : TermRef =>
70
87
val sym = tp.symbol
71
88
lazy val tpInfoRealizable = realizability(tp.info)
@@ -86,7 +103,11 @@ class CheckRealizable(implicit ctx: Context) {
86
103
if (sym.isStableMember) sym.setFlag(StableRealizable ) // it's known to be stable and realizable
87
104
realizability(tp.prefix)
88
105
} mapError { r =>
89
- if (tp.info.isStable && tpInfoRealizable == Realizable ) Realizable else r
106
+ // A mutable path is in fact stable and realizable if it has a realizable singleton type.
107
+ if (tp.info.isStable && tpInfoRealizable == Realizable ) {
108
+ sym.setFlag(StableRealizable )
109
+ Realizable
110
+ } else r
90
111
}
91
112
}
92
113
case _ : SingletonType | NoPrefix =>
0 commit comments