@@ -2230,40 +2230,35 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2230
2230
else if ! tp2.exists || (tp2 eq WildcardType ) then tp1
2231
2231
else if tp1.isAny && ! tp2.isLambdaSub || tp1.isAnyKind || isBottom(tp2) then tp2
2232
2232
else if tp2.isAny && ! tp1.isLambdaSub || tp2.isAnyKind || isBottom(tp1) then tp1
2233
- else tp2 match
2234
- case tp2 : LazyRef =>
2235
- glb(tp1, tp2.ref)
2236
- case _ =>
2237
- tp1 match
2238
- case tp1 : LazyRef =>
2239
- glb(tp1.ref, tp2)
2240
- case _ =>
2241
- val tp1a = dropIfSuper(tp1, tp2)
2242
- if tp1a ne tp1 then glb(tp1a, tp2)
2243
- else
2244
- val tp2a = dropIfSuper(tp2, tp1)
2245
- if tp2a ne tp2 then glb(tp1, tp2a)
2246
- else tp2 match // normalize to disjunctive normal form if possible.
2247
- case tp2 @ OrType (tp21, tp22) =>
2248
- lub(tp1 & tp21, tp1 & tp22, isSoft = tp2.isSoft)
2249
- case _ =>
2250
- tp1 match
2251
- case tp1 @ OrType (tp11, tp12) =>
2252
- lub(tp11 & tp2, tp12 & tp2, isSoft = tp1.isSoft)
2253
- case tp1 : ConstantType =>
2254
- tp2 match
2255
- case tp2 : ConstantType =>
2256
- // Make use of the fact that the intersection of two constant types
2257
- // types which are not subtypes of each other is known to be empty.
2258
- // Note: The same does not apply to singleton types in general.
2259
- // E.g. we could have a pattern match against `x.type & y.type`
2260
- // which might succeed if `x` and `y` happen to be the same ref
2261
- // at run time. It would not work to replace that with `Nothing`.
2262
- // However, maybe we can still apply the replacement to
2263
- // types which are not explicitly written.
2264
- NothingType
2265
- case _ => andType(tp1, tp2)
2233
+ else
2234
+ def mergedGlb (tp1 : Type , tp2 : Type ): Type =
2235
+ val tp1a = dropIfSuper(tp1, tp2)
2236
+ if tp1a ne tp1 then glb(tp1a, tp2)
2237
+ else
2238
+ val tp2a = dropIfSuper(tp2, tp1)
2239
+ if tp2a ne tp2 then glb(tp1, tp2a)
2240
+ else tp2 match // normalize to disjunctive normal form if possible.
2241
+ case tp2 @ OrType (tp21, tp22) =>
2242
+ lub(tp1 & tp21, tp1 & tp22, isSoft = tp2.isSoft)
2243
+ case _ =>
2244
+ tp1 match
2245
+ case tp1 @ OrType (tp11, tp12) =>
2246
+ lub(tp11 & tp2, tp12 & tp2, isSoft = tp1.isSoft)
2247
+ case tp1 : ConstantType =>
2248
+ tp2 match
2249
+ case tp2 : ConstantType =>
2250
+ // Make use of the fact that the intersection of two constant types
2251
+ // types which are not subtypes of each other is known to be empty.
2252
+ // Note: The same does not apply to singleton types in general.
2253
+ // E.g. we could have a pattern match against `x.type & y.type`
2254
+ // which might succeed if `x` and `y` happen to be the same ref
2255
+ // at run time. It would not work to replace that with `Nothing`.
2256
+ // However, maybe we can still apply the replacement to
2257
+ // types which are not explicitly written.
2258
+ NothingType
2266
2259
case _ => andType(tp1, tp2)
2260
+ case _ => andType(tp1, tp2)
2261
+ mergedGlb(dropExpr(tp1.stripLazyRef), dropExpr(tp2.stripLazyRef))
2267
2262
}
2268
2263
2269
2264
def widenInUnions (using Context ): Boolean =
@@ -2303,7 +2298,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2303
2298
if ((tp1 ne tp1w) || (tp2 ne tp2w)) lub(tp1w, tp2w, canConstrain = canConstrain, isSoft = isSoft)
2304
2299
else orType(tp1w, tp2w, isSoft = isSoft) // no need to check subtypes again
2305
2300
}
2306
- mergedLub(tp1.stripLazyRef, tp2.stripLazyRef)
2301
+ mergedLub(dropExpr( tp1.stripLazyRef), dropExpr( tp2.stripLazyRef) )
2307
2302
}
2308
2303
2309
2304
/** Try to produce joint arguments for a lub `A[T_1, ..., T_n] | A[T_1', ..., T_n']` using
@@ -2424,12 +2419,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2424
2419
/** There's a window of vulnerability between ElimByName and Erasure where some
2425
2420
* ExprTypes `=> T` that appear as parameters of function types are not yet converted
2426
2421
* to by-name functions `() ?=> T`. These would cause an assertion violation when
2427
- * used as operands of & or | . We fix this on the fly here. As explained in
2422
+ * used as operands of glb or lub . We fix this on the fly here. As explained in
2428
2423
* ElimByName, we can't fix it beforehand by mapping all occurrences of `=> T` to
2429
2424
* `() ?=> T` since that could lead to cycles.
2430
2425
*/
2431
2426
private def dropExpr (tp : Type ): Type = tp match
2432
- case ExprType (rt) if Phases .elimByNamePhase <= ctx.phase && ! ctx.erasedTypes =>
2427
+ case ExprType (rt) if ( Phases .elimByNamePhase <= ctx.phase) && ! ctx.erasedTypes =>
2433
2428
defn.ByNameFunction (rt)
2434
2429
case _ =>
2435
2430
tp
@@ -2442,7 +2437,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2442
2437
val t2 = distributeAnd(tp2, tp1)
2443
2438
if (t2.exists) t2
2444
2439
else if (isErased) erasedGlb(tp1, tp2)
2445
- else liftIfHK(dropExpr( tp1), dropExpr( tp2) , op, original, _ | _)
2440
+ else liftIfHK(tp1, tp2, op, original, _ | _)
2446
2441
// The ` | ` on variances is needed since variances are associated with bounds
2447
2442
// not lambdas. Example:
2448
2443
//
@@ -2486,7 +2481,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2486
2481
val t2 = distributeOr(tp2, tp1, isSoft)
2487
2482
if (t2.exists) t2
2488
2483
else if (isErased) erasedLub(tp1, tp2)
2489
- else liftIfHK(dropExpr( tp1), dropExpr( tp2) , OrType .balanced(_, _, soft = isSoft), _ | _, _ & _)
2484
+ else liftIfHK(tp1, tp2, OrType .balanced(_, _, soft = isSoft), _ | _, _ & _)
2490
2485
}
2491
2486
}
2492
2487
0 commit comments