@@ -62,6 +62,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
62
62
private var myAnyKindClass : ClassSymbol = null
63
63
private var myNothingClass : ClassSymbol = null
64
64
private var myNullClass : ClassSymbol = null
65
+ private var myNotNullClass : ClassSymbol = null
65
66
private var myObjectClass : ClassSymbol = null
66
67
private var myAnyType : TypeRef = null
67
68
private var myAnyKindType : TypeRef = null
@@ -83,6 +84,10 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
83
84
if (myNullClass == null ) myNullClass = defn.NullClass
84
85
myNullClass
85
86
}
87
+ def NotNullClass : ClassSymbol =
88
+ if myNotNullClass == null then myNotNullClass = defn.NotNullClass
89
+ myNotNullClass
90
+
86
91
def ObjectClass : ClassSymbol = {
87
92
if (myObjectClass == null ) myObjectClass = defn.ObjectClass
88
93
myObjectClass
@@ -770,6 +775,15 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
770
775
if (tp2a ne tp2) // Follow the alias; this might avoid truncating the search space in the either below
771
776
return recur(tp1, tp2a)
772
777
778
+ if tp11.isRef(NotNullClass )
779
+ tp12.widen match
780
+ case OrNull (tp12a) if recur(tp12a, tp2) => return true
781
+ case _ =>
782
+ if tp12.isRef(NotNullClass )
783
+ tp11.widen match
784
+ case OrNull (tp11a) if recur(tp11a, tp2) => return true
785
+ case _ =>
786
+
773
787
// Rewrite (T111 | T112) & T12 <: T2 to (T111 & T12) <: T2 and (T112 | T12) <: T2
774
788
// and analogously for T11 & (T121 | T122) & T12 <: T2
775
789
// `&' types to the left of <: are problematic, because
@@ -1042,7 +1056,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
1042
1056
*/
1043
1057
def isNewSubType (tp1 : Type ): Boolean =
1044
1058
if (isCovered(tp1) && isCovered(tp2))
1045
- // println(s "useless subtype: $tp1 <:< $tp2")
1059
+ // println(i "useless subtype: $tp1 <:< $tp2")
1046
1060
false
1047
1061
else isSubType(tp1, tp2, approx.addLow)
1048
1062
@@ -1533,7 +1547,11 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
1533
1547
* combiners are AppliedTypes, RefinedTypes, RecTypes, And/Or-Types or AnnotatedTypes.
1534
1548
*/
1535
1549
private def isCovered (tp : Type ): Boolean = tp.dealiasKeepRefiningAnnots.stripTypeVar match {
1536
- case tp : TypeRef => tp.symbol.isClass && tp.symbol != NothingClass && tp.symbol != NullClass
1550
+ case tp : TypeRef =>
1551
+ tp.symbol.isClass
1552
+ && tp.symbol != NothingClass
1553
+ && tp.symbol != NullClass
1554
+ && tp.symbol != NotNullClass
1537
1555
case tp : AppliedType => isCovered(tp.tycon)
1538
1556
case tp : RefinedOrRecType => isCovered(tp.parent)
1539
1557
case tp : AndType => isCovered(tp.tp1) && isCovered(tp.tp2)
@@ -1701,28 +1719,27 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
1701
1719
tp11 & tp2 | tp12 & tp2
1702
1720
case _ =>
1703
1721
val tp1a = dropIfSuper(tp1, tp2)
1704
- if (tp1a ne tp1) glb(tp1a, tp2)
1705
- else {
1706
- val tp2a = dropIfSuper(tp2, tp1)
1707
- if (tp2a ne tp2) glb(tp1, tp2a)
1708
- else tp1 match {
1709
- case tp1 : ConstantType =>
1710
- tp2 match {
1711
- case tp2 : ConstantType =>
1712
- // Make use of the fact that the intersection of two constant types
1713
- // types which are not subtypes of each other is known to be empty.
1714
- // Note: The same does not apply to singleton types in general.
1715
- // E.g. we could have a pattern match against `x.type & y.type`
1716
- // which might succeed if `x` and `y` happen to be the same ref
1717
- // at run time. It would not work to replace that with `Nothing`.
1718
- // However, maybe we can still apply the replacement to
1719
- // types which are not explicitly written.
1720
- NothingType
1721
- case _ => andType(tp1, tp2)
1722
- }
1723
- case _ => andType(tp1, tp2)
1724
- }
1725
- }
1722
+ if (tp1a ne tp1) return glb(tp1a, tp2)
1723
+ val tp2a = dropIfSuper(tp2, tp1)
1724
+ if (tp2a ne tp2) return glb(tp1, tp2a)
1725
+ tp1 match
1726
+ case tp1 : ConstantType =>
1727
+ tp2 match
1728
+ case tp2 : ConstantType =>
1729
+ // Make use of the fact that the intersection of two constant types
1730
+ // types which are not subtypes of each other is known to be empty.
1731
+ // Note: The same does not apply to singleton types in general.
1732
+ // E.g. we could have a pattern match against `x.type & y.type`
1733
+ // which might succeed if `x` and `y` happen to be the same ref
1734
+ // at run time. It would not work to replace that with `Nothing`.
1735
+ // However, maybe we can still apply the replacement to
1736
+ // types which are not explicitly written.
1737
+ return NothingType
1738
+ case _ =>
1739
+ case _ =>
1740
+ if tp1.isRef(NotNullClass ) && tp2.isNull then return NothingType
1741
+ if tp2.isRef(NotNullClass ) && tp1.isNull then return NothingType
1742
+ andType(tp1, tp2)
1726
1743
}
1727
1744
}
1728
1745
}
@@ -1838,7 +1855,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
1838
1855
else if (! tp2.exists) tp1
1839
1856
else tp.derivedAndType(tp1, tp2)
1840
1857
1841
- /** If some (&-operand of) this type is a supertype of `sub` replace it with `NoType`.
1858
+ /** If some (&-operand of) `tp` is a supertype of `sub` replace it with `NoType`.
1842
1859
*/
1843
1860
private def dropIfSuper (tp : Type , sub : Type ): Type =
1844
1861
if (isSubTypeWhenFrozen(sub, tp)) NoType
0 commit comments