@@ -1040,7 +1040,7 @@ object Types {
1040
1040
def safe_& (that : Type )(using Context ): Type = (this , that) match {
1041
1041
case (TypeBounds (lo1, hi1), TypeBounds (lo2, hi2)) =>
1042
1042
TypeBounds (
1043
- OrType .makeHk(lo1.stripLazyRef, lo2.stripLazyRef),
1043
+ OrType .makeHk(lo1.stripLazyRef, lo2.stripLazyRef),
1044
1044
AndType .makeHk(hi1.stripLazyRef, hi2.stripLazyRef))
1045
1045
case _ =>
1046
1046
this & that
@@ -2917,8 +2917,9 @@ object Types {
2917
2917
2918
2918
def derivedAndOrType (tp1 : Type , tp2 : Type )(using Context ) =
2919
2919
if ((tp1 eq this .tp1) && (tp2 eq this .tp2)) this
2920
- else if (isAnd) AndType .make(tp1, tp2, checkValid = true )
2921
- else OrType .make(tp1, tp2)
2920
+ else this match
2921
+ case tp : OrType => OrType .make(tp1, tp2, tp.isSoft)
2922
+ case tp : AndType => AndType .make(tp1, tp2, checkValid = true )
2922
2923
}
2923
2924
2924
2925
abstract case class AndType (tp1 : Type , tp2 : Type ) extends AndOrType {
@@ -2992,6 +2993,7 @@ object Types {
2992
2993
2993
2994
abstract case class OrType (tp1 : Type , tp2 : Type ) extends AndOrType {
2994
2995
def isAnd : Boolean = false
2996
+ def isSoft : Boolean
2995
2997
private var myBaseClassesPeriod : Period = Nowhere
2996
2998
private var myBaseClasses : List [ClassSymbol ] = _
2997
2999
/** Base classes of are the intersection of the operand base classes. */
@@ -3054,30 +3056,31 @@ object Types {
3054
3056
3055
3057
def derivedOrType (tp1 : Type , tp2 : Type )(using Context ): Type =
3056
3058
if ((tp1 eq this .tp1) && (tp2 eq this .tp2)) this
3057
- else OrType .make(tp1, tp2)
3059
+ else OrType .make(tp1, tp2, isSoft )
3058
3060
3059
- override def computeHash (bs : Binders ): Int = doHash(bs, tp1, tp2)
3061
+ override def computeHash (bs : Binders ): Int =
3062
+ doHash(bs, if isSoft then 0 else 1 , tp1, tp2)
3060
3063
3061
3064
override def eql (that : Type ): Boolean = that match {
3062
- case that : OrType => tp1.eq(that.tp1) && tp2.eq(that.tp2)
3065
+ case that : OrType => tp1.eq(that.tp1) && tp2.eq(that.tp2) && isSoft == that.isSoft
3063
3066
case _ => false
3064
3067
}
3065
3068
}
3066
3069
3067
- final class CachedOrType (tp1 : Type , tp2 : Type ) extends OrType (tp1, tp2)
3070
+ final class CachedOrType (tp1 : Type , tp2 : Type , override val isSoft : Boolean ) extends OrType (tp1, tp2)
3068
3071
3069
3072
object OrType {
3070
- def apply (tp1 : Type , tp2 : Type )(using Context ): OrType = {
3073
+ def apply (tp1 : Type , tp2 : Type , soft : Boolean )(using Context ): OrType = {
3071
3074
assertUnerased()
3072
- unique(new CachedOrType (tp1, tp2))
3075
+ unique(new CachedOrType (tp1, tp2, soft ))
3073
3076
}
3074
- def make (tp1 : Type , tp2 : Type )(using Context ): Type =
3077
+ def make (tp1 : Type , tp2 : Type , soft : Boolean )(using Context ): Type =
3075
3078
if (tp1 eq tp2) tp1
3076
- else apply(tp1, tp2)
3079
+ else apply(tp1, tp2, soft )
3077
3080
3078
3081
/** Like `make`, but also supports higher-kinded types as argument */
3079
3082
def makeHk (tp1 : Type , tp2 : Type )(using Context ): Type =
3080
- TypeComparer .liftIfHK(tp1, tp2, OrType (_, _), makeHk, _ & _)
3083
+ TypeComparer .liftIfHK(tp1, tp2, OrType (_, _, soft = true ), makeHk, _ & _)
3081
3084
}
3082
3085
3083
3086
/** An extractor object to pattern match against a nullable union.
@@ -3089,7 +3092,7 @@ object Types {
3089
3092
*/
3090
3093
object OrNull {
3091
3094
def apply (tp : Type )(using Context ) =
3092
- OrType (tp, defn.NullType )
3095
+ OrType (tp, defn.NullType , soft = false )
3093
3096
def unapply (tp : Type )(using Context ): Option [Type ] =
3094
3097
if (ctx.explicitNulls) {
3095
3098
val tp1 = tp.stripNull()
@@ -3107,7 +3110,7 @@ object Types {
3107
3110
*/
3108
3111
object OrUncheckedNull {
3109
3112
def apply (tp : Type )(using Context ) =
3110
- OrType (tp, defn.UncheckedNullAliasType )
3113
+ OrType (tp, defn.UncheckedNullAliasType , soft = false )
3111
3114
def unapply (tp : Type )(using Context ): Option [Type ] =
3112
3115
if (ctx.explicitNulls) {
3113
3116
val tp1 = tp.stripUncheckedNull
0 commit comments