@@ -18,6 +18,7 @@ import Denotations._
18
18
import Periods ._
19
19
import util .Stats ._
20
20
import util .SimpleIdentitySet
21
+ import CheckRealizable .{realizability , Realizable }
21
22
import reporting .diagnostic .Message
22
23
import ast .tpd ._
23
24
import ast .TreeTypeMap
@@ -149,14 +150,20 @@ object Types {
149
150
150
151
/** Does this type denote a stable reference (i.e. singleton type)? */
151
152
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
153
154
case _ : SingletonType | NoPrefix => true
154
155
case tp : RefinedOrRecType => tp.parent.isStable
155
156
case tp : ExprType => tp.resultType.isStable
156
157
case tp : AnnotatedType => tp.parent.isStable
157
158
case _ => false
158
159
}
159
160
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
+
160
167
/** Is this type a (possibly refined or applied or aliased) type reference
161
168
* to the given type symbol?
162
169
* @sym The symbol to compare to. It must be a class symbol or abstract type.
@@ -3573,6 +3580,17 @@ object Types {
3573
3580
3574
3581
def withName (name : Name ): this .type = { myRepr = name; this }
3575
3582
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
+
3576
3594
private [this ] var myRepr : Name = null
3577
3595
def repr (implicit ctx : Context ): Name = {
3578
3596
if (myRepr == null ) myRepr = SkolemName .fresh()
@@ -4506,6 +4524,8 @@ object Types {
4506
4524
else if (lo `eq` hi) lo
4507
4525
else Range (lower(lo), upper(hi))
4508
4526
4527
+ protected def emptyRange = range(defn.NothingType , defn.AnyType )
4528
+
4509
4529
protected def isRange (tp : Type ): Boolean = tp.isInstanceOf [Range ]
4510
4530
4511
4531
protected def lower (tp : Type ): Type = tp match {
@@ -4578,6 +4598,9 @@ object Types {
4578
4598
else tryWiden(tp, preHi)
4579
4599
forwarded.orElse(
4580
4600
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
4581
4604
case _ =>
4582
4605
super .derivedSelect(tp, pre) match {
4583
4606
case TypeBounds (lo, hi) => range(lo, hi)
@@ -4630,7 +4653,7 @@ object Types {
4630
4653
else tp.derivedTypeBounds(lo, hi)
4631
4654
4632
4655
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
4634
4657
else tp.derivedSuperType(thistp, supertp)
4635
4658
4636
4659
override protected def derivedAppliedType (tp : AppliedType , tycon : Type , args : List [Type ]): Type =
0 commit comments