Skip to content

Commit 278beb8

Browse files
committed
Move dropExpr upstream to glb and lub
Avoids follow-up failures in Ycheck for the test case.
1 parent 1ea4c86 commit 278beb8

File tree

1 file changed

+33
-38
lines changed

1 file changed

+33
-38
lines changed

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,40 +2318,35 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
23182318
else if !tp2.exists || (tp2 eq WildcardType) then tp1
23192319
else if tp1.isAny && !tp2.isLambdaSub || tp1.isAnyKind || isBottom(tp2) then tp2
23202320
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
23542347
case _ => andType(tp1, tp2)
2348+
case _ => andType(tp1, tp2)
2349+
mergedGlb(dropExpr(tp1.stripLazyRef), dropExpr(tp2.stripLazyRef))
23552350
}
23562351

23572352
def widenInUnions(using Context): Boolean =
@@ -2390,7 +2385,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
23902385
if ((tp1 ne tp1w) || (tp2 ne tp2w)) lub(tp1w, tp2w, canConstrain = canConstrain, isSoft = isSoft)
23912386
else orType(tp1w, tp2w, isSoft = isSoft) // no need to check subtypes again
23922387
}
2393-
mergedLub(tp1.stripLazyRef, tp2.stripLazyRef)
2388+
mergedLub(dropExpr(tp1.stripLazyRef), dropExpr(tp2.stripLazyRef))
23942389
}
23952390

23962391
/** 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
25112506
/** There's a window of vulnerability between ElimByName and Erasure where some
25122507
* ExprTypes `=> T` that appear as parameters of function types are not yet converted
25132508
* 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
25152510
* ElimByName, we can't fix it beforehand by mapping all occurrences of `=> T` to
25162511
* `() ?=> T` since that could lead to cycles.
25172512
*/
25182513
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 =>
25202515
defn.ByNameFunction(rt)
25212516
case _ =>
25222517
tp
@@ -2529,7 +2524,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25292524
val t2 = distributeAnd(tp2, tp1)
25302525
if (t2.exists) t2
25312526
else if (isErased) erasedGlb(tp1, tp2)
2532-
else liftIfHK(dropExpr(tp1), dropExpr(tp2), op, original, _ | _)
2527+
else liftIfHK(tp1, tp2, op, original, _ | _)
25332528
// The ` | ` on variances is needed since variances are associated with bounds
25342529
// not lambdas. Example:
25352530
//
@@ -2574,7 +2569,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25742569
val t2 = distributeOr(tp2, tp1, isSoft)
25752570
if (t2.exists) t2
25762571
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), _ | _, _ & _)
25782573
}
25792574
}
25802575

0 commit comments

Comments
 (0)