@@ -2318,40 +2318,35 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2318
2318
else if ! tp2.exists || (tp2 eq WildcardType ) then tp1
2319
2319
else if tp1.isAny && ! tp2.isLambdaSub || tp1.isAnyKind || isBottom(tp2) then tp2
2320
2320
else if tp2.isAny && ! tp1.isLambdaSub || tp2.isAnyKind || isBottom(tp1) then tp1
2321
- else tp2 match
2322
- case tp2 : LazyRef =>
2323
- glb(tp1, tp2.ref)
2324
- case _ =>
2325
- tp1 match
2326
- case tp1 : LazyRef =>
2327
- glb(tp1.ref, tp2)
2328
- case _ =>
2329
- val tp1a = dropIfSuper(tp1, tp2)
2330
- if tp1a ne tp1 then glb(tp1a, tp2)
2331
- else
2332
- val tp2a = dropIfSuper(tp2, tp1)
2333
- if tp2a ne tp2 then glb(tp1, tp2a)
2334
- else tp2 match // normalize to disjunctive normal form if possible.
2335
- case tp2 @ OrType (tp21, tp22) =>
2336
- lub(tp1 & tp21, tp1 & tp22, isSoft = tp2.isSoft)
2337
- case _ =>
2338
- tp1 match
2339
- case tp1 @ OrType (tp11, tp12) =>
2340
- lub(tp11 & tp2, tp12 & tp2, isSoft = tp1.isSoft)
2341
- case tp1 : ConstantType =>
2342
- tp2 match
2343
- case tp2 : ConstantType =>
2344
- // Make use of the fact that the intersection of two constant types
2345
- // types which are not subtypes of each other is known to be empty.
2346
- // Note: The same does not apply to singleton types in general.
2347
- // E.g. we could have a pattern match against `x.type & y.type`
2348
- // which might succeed if `x` and `y` happen to be the same ref
2349
- // at run time. It would not work to replace that with `Nothing`.
2350
- // However, maybe we can still apply the replacement to
2351
- // types which are not explicitly written.
2352
- NothingType
2353
- case _ => andType(tp1, tp2)
2321
+ else
2322
+ def mergedGlb (tp1 : Type , tp2 : Type ): Type =
2323
+ val tp1a = dropIfSuper(tp1, tp2)
2324
+ if tp1a ne tp1 then glb(tp1a, tp2)
2325
+ else
2326
+ val tp2a = dropIfSuper(tp2, tp1)
2327
+ if tp2a ne tp2 then glb(tp1, tp2a)
2328
+ else tp2 match // normalize to disjunctive normal form if possible.
2329
+ case tp2 @ OrType (tp21, tp22) =>
2330
+ lub(tp1 & tp21, tp1 & tp22, isSoft = tp2.isSoft)
2331
+ case _ =>
2332
+ tp1 match
2333
+ case tp1 @ OrType (tp11, tp12) =>
2334
+ lub(tp11 & tp2, tp12 & tp2, isSoft = tp1.isSoft)
2335
+ case tp1 : ConstantType =>
2336
+ tp2 match
2337
+ case tp2 : ConstantType =>
2338
+ // Make use of the fact that the intersection of two constant types
2339
+ // types which are not subtypes of each other is known to be empty.
2340
+ // Note: The same does not apply to singleton types in general.
2341
+ // E.g. we could have a pattern match against `x.type & y.type`
2342
+ // which might succeed if `x` and `y` happen to be the same ref
2343
+ // at run time. It would not work to replace that with `Nothing`.
2344
+ // However, maybe we can still apply the replacement to
2345
+ // types which are not explicitly written.
2346
+ NothingType
2354
2347
case _ => andType(tp1, tp2)
2348
+ case _ => andType(tp1, tp2)
2349
+ mergedGlb(dropExpr(tp1.stripLazyRef), dropExpr(tp2.stripLazyRef))
2355
2350
}
2356
2351
2357
2352
def widenInUnions (using Context ): Boolean =
@@ -2390,7 +2385,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2390
2385
if ((tp1 ne tp1w) || (tp2 ne tp2w)) lub(tp1w, tp2w, canConstrain = canConstrain, isSoft = isSoft)
2391
2386
else orType(tp1w, tp2w, isSoft = isSoft) // no need to check subtypes again
2392
2387
}
2393
- mergedLub(tp1.stripLazyRef, tp2.stripLazyRef)
2388
+ mergedLub(dropExpr( tp1.stripLazyRef), dropExpr( tp2.stripLazyRef) )
2394
2389
}
2395
2390
2396
2391
/** Try to produce joint arguments for a lub `A[T_1, ..., T_n] | A[T_1', ..., T_n']` using
@@ -2511,12 +2506,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2511
2506
/** There's a window of vulnerability between ElimByName and Erasure where some
2512
2507
* ExprTypes `=> T` that appear as parameters of function types are not yet converted
2513
2508
* to by-name functions `() ?=> T`. These would cause an assertion violation when
2514
- * used as operands of & or | . We fix this on the fly here. As explained in
2509
+ * used as operands of glb or lub . We fix this on the fly here. As explained in
2515
2510
* ElimByName, we can't fix it beforehand by mapping all occurrences of `=> T` to
2516
2511
* `() ?=> T` since that could lead to cycles.
2517
2512
*/
2518
2513
private def dropExpr (tp : Type ): Type = tp match
2519
- case ExprType (rt) if Phases .elimByNamePhase <= ctx.phase && ! ctx.erasedTypes =>
2514
+ case ExprType (rt) if ( Phases .elimByNamePhase <= ctx.phase) && ! ctx.erasedTypes =>
2520
2515
defn.ByNameFunction (rt)
2521
2516
case _ =>
2522
2517
tp
@@ -2529,7 +2524,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2529
2524
val t2 = distributeAnd(tp2, tp1)
2530
2525
if (t2.exists) t2
2531
2526
else if (isErased) erasedGlb(tp1, tp2)
2532
- else liftIfHK(dropExpr( tp1), dropExpr( tp2) , op, original, _ | _)
2527
+ else liftIfHK(tp1, tp2, op, original, _ | _)
2533
2528
// The ` | ` on variances is needed since variances are associated with bounds
2534
2529
// not lambdas. Example:
2535
2530
//
@@ -2574,7 +2569,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2574
2569
val t2 = distributeOr(tp2, tp1, isSoft)
2575
2570
if (t2.exists) t2
2576
2571
else if (isErased) erasedLub(tp1, tp2)
2577
- else liftIfHK(dropExpr( tp1), dropExpr( tp2) , OrType .balanced(_, _, soft = isSoft), _ | _, _ & _)
2572
+ else liftIfHK(tp1, tp2, OrType .balanced(_, _, soft = isSoft), _ | _, _ & _)
2578
2573
}
2579
2574
}
2580
2575
0 commit comments