@@ -18,6 +18,7 @@ import Denotations._
1818import Periods ._
1919import util .Stats ._
2020import util .SimpleIdentitySet
21+ import CheckRealizable .{realizability , Realizable }
2122import reporting .diagnostic .Message
2223import ast .tpd ._
2324import ast .TreeTypeMap
@@ -149,14 +150,20 @@ object Types {
149150
150151 /** Does this type denote a stable reference (i.e. singleton type)? */
151152 final def isStable (implicit ctx : Context ): Boolean = stripTypeVar match {
152- case tp : TermRef => tp.termSymbol .isStable && tp.prefix.isStable || tp.info.isStable
153+ case tp : TermRef => tp.symbol .isStable && tp.prefix.isStable || tp.info.isStable
153154 case _ : SingletonType | NoPrefix => true
154155 case tp : RefinedOrRecType => tp.parent.isStable
155156 case tp : ExprType => tp.resultType.isStable
156157 case tp : AnnotatedType => tp.parent.isStable
157158 case _ => false
158159 }
159160
161+ /** Does this type denote a realizable stable reference? Much more expensive to check
162+ * than isStable, that's why some of the checks are done later in PostTyper.
163+ */
164+ final def isStableRealizable (implicit ctx : Context ): Boolean =
165+ isStable && realizability(this ) == Realizable
166+
160167 /** Is this type a (possibly refined or applied or aliased) type reference
161168 * to the given type symbol?
162169 * @sym The symbol to compare to. It must be a class symbol or abstract type.
@@ -3573,6 +3580,17 @@ object Types {
35733580
35743581 def withName (name : Name ): this .type = { myRepr = name; this }
35753582
3583+ private [this ] var isRealizableKnown = false
3584+ private [this ] var isRealizableCache : Boolean = _
3585+
3586+ def isRealizable (implicit ctx : Context ) = {
3587+ if (! isRealizableKnown) {
3588+ isRealizableCache = realizability(info) == Realizable
3589+ isRealizableKnown = true
3590+ }
3591+ isRealizableCache
3592+ }
3593+
35763594 private [this ] var myRepr : Name = null
35773595 def repr (implicit ctx : Context ): Name = {
35783596 if (myRepr == null ) myRepr = SkolemName .fresh()
@@ -4506,6 +4524,8 @@ object Types {
45064524 else if (lo `eq` hi) lo
45074525 else Range (lower(lo), upper(hi))
45084526
4527+ protected def emptyRange = range(defn.NothingType , defn.AnyType )
4528+
45094529 protected def isRange (tp : Type ): Boolean = tp.isInstanceOf [Range ]
45104530
45114531 protected def lower (tp : Type ): Type = tp match {
@@ -4578,6 +4598,9 @@ object Types {
45784598 else tryWiden(tp, preHi)
45794599 forwarded.orElse(
45804600 range(super .derivedSelect(tp, preLo).loBound, super .derivedSelect(tp, preHi).hiBound))
4601+ case pre : SkolemType if ! pre.isRealizable =>
4602+ // If `pre` is not realizable it could would be in general unsound to use it as a path
4603+ emptyRange
45814604 case _ =>
45824605 super .derivedSelect(tp, pre) match {
45834606 case TypeBounds (lo, hi) => range(lo, hi)
@@ -4630,7 +4653,7 @@ object Types {
46304653 else tp.derivedTypeBounds(lo, hi)
46314654
46324655 override protected def derivedSuperType (tp : SuperType , thistp : Type , supertp : Type ): Type =
4633- if (isRange(thistp) || isRange(supertp)) range(defn. NothingType , defn. AnyType )
4656+ if (isRange(thistp) || isRange(supertp)) emptyRange
46344657 else tp.derivedSuperType(thistp, supertp)
46354658
46364659 override protected def derivedAppliedType (tp : AppliedType , tycon : Type , args : List [Type ]): Type =
0 commit comments