@@ -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
@@ -2907,8 +2907,9 @@ object Types {
2907
2907
2908
2908
def derivedAndOrType (tp1 : Type , tp2 : Type )(using Context ) =
2909
2909
if ((tp1 eq this .tp1) && (tp2 eq this .tp2)) this
2910
- else if (isAnd) AndType .make(tp1, tp2, checkValid = true )
2911
- else OrType .make(tp1, tp2)
2910
+ else this match
2911
+ case tp : OrType => OrType .make(tp1, tp2, tp.isSoft)
2912
+ case tp : AndType => AndType .make(tp1, tp2, checkValid = true )
2912
2913
}
2913
2914
2914
2915
abstract case class AndType (tp1 : Type , tp2 : Type ) extends AndOrType {
@@ -2982,6 +2983,7 @@ object Types {
2982
2983
2983
2984
abstract case class OrType (tp1 : Type , tp2 : Type ) extends AndOrType {
2984
2985
def isAnd : Boolean = false
2986
+ def isSoft : Boolean
2985
2987
private var myBaseClassesPeriod : Period = Nowhere
2986
2988
private var myBaseClasses : List [ClassSymbol ] = _
2987
2989
/** Base classes of are the intersection of the operand base classes. */
@@ -3044,30 +3046,31 @@ object Types {
3044
3046
3045
3047
def derivedOrType (tp1 : Type , tp2 : Type )(using Context ): Type =
3046
3048
if ((tp1 eq this .tp1) && (tp2 eq this .tp2)) this
3047
- else OrType .make(tp1, tp2)
3049
+ else OrType .make(tp1, tp2, isSoft )
3048
3050
3049
- override def computeHash (bs : Binders ): Int = doHash(bs, tp1, tp2)
3051
+ override def computeHash (bs : Binders ): Int =
3052
+ doHash(bs, if isSoft then 0 else 1 , tp1, tp2)
3050
3053
3051
3054
override def eql (that : Type ): Boolean = that match {
3052
- case that : OrType => tp1.eq(that.tp1) && tp2.eq(that.tp2)
3055
+ case that : OrType => tp1.eq(that.tp1) && tp2.eq(that.tp2) && isSoft == that.isSoft
3053
3056
case _ => false
3054
3057
}
3055
3058
}
3056
3059
3057
- final class CachedOrType (tp1 : Type , tp2 : Type ) extends OrType (tp1, tp2)
3060
+ final class CachedOrType (tp1 : Type , tp2 : Type , override val isSoft : Boolean ) extends OrType (tp1, tp2)
3058
3061
3059
3062
object OrType {
3060
- def apply (tp1 : Type , tp2 : Type )(using Context ): OrType = {
3063
+ def apply (tp1 : Type , tp2 : Type , soft : Boolean )(using Context ): OrType = {
3061
3064
assertUnerased()
3062
- unique(new CachedOrType (tp1, tp2))
3065
+ unique(new CachedOrType (tp1, tp2, soft ))
3063
3066
}
3064
- def make (tp1 : Type , tp2 : Type )(using Context ): Type =
3067
+ def make (tp1 : Type , tp2 : Type , soft : Boolean )(using Context ): Type =
3065
3068
if (tp1 eq tp2) tp1
3066
- else apply(tp1, tp2)
3069
+ else apply(tp1, tp2, soft )
3067
3070
3068
3071
/** Like `make`, but also supports higher-kinded types as argument */
3069
3072
def makeHk (tp1 : Type , tp2 : Type )(using Context ): Type =
3070
- TypeComparer .liftIfHK(tp1, tp2, OrType (_, _), makeHk, _ & _)
3073
+ TypeComparer .liftIfHK(tp1, tp2, OrType (_, _, soft = true ), makeHk, _ & _)
3071
3074
}
3072
3075
3073
3076
/** An extractor object to pattern match against a nullable union.
@@ -3079,7 +3082,7 @@ object Types {
3079
3082
*/
3080
3083
object OrNull {
3081
3084
def apply (tp : Type )(using Context ) =
3082
- OrType (tp, defn.NullType )
3085
+ OrType (tp, defn.NullType , soft = false )
3083
3086
def unapply (tp : Type )(using Context ): Option [Type ] =
3084
3087
if (ctx.explicitNulls) {
3085
3088
val tp1 = tp.stripNull()
@@ -3097,7 +3100,7 @@ object Types {
3097
3100
*/
3098
3101
object OrUncheckedNull {
3099
3102
def apply (tp : Type )(using Context ) =
3100
- OrType (tp, defn.UncheckedNullAliasType )
3103
+ OrType (tp, defn.UncheckedNullAliasType , soft = false )
3101
3104
def unapply (tp : Type )(using Context ): Option [Type ] =
3102
3105
if (ctx.explicitNulls) {
3103
3106
val tp1 = tp.stripUncheckedNull
0 commit comments