Skip to content

Commit 0b44bbe

Browse files
oderskyWojciechMazur
authored andcommitted
Move dropExpr upstream to glb and lub
Avoids follow-up failures in Ycheck for the test case. [Cherry-picked 278beb8]
1 parent 71cbbe1 commit 0b44bbe

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
@@ -2230,40 +2230,35 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
22302230
else if !tp2.exists || (tp2 eq WildcardType) then tp1
22312231
else if tp1.isAny && !tp2.isLambdaSub || tp1.isAnyKind || isBottom(tp2) then tp2
22322232
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
22662259
case _ => andType(tp1, tp2)
2260+
case _ => andType(tp1, tp2)
2261+
mergedGlb(dropExpr(tp1.stripLazyRef), dropExpr(tp2.stripLazyRef))
22672262
}
22682263

22692264
def widenInUnions(using Context): Boolean =
@@ -2303,7 +2298,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
23032298
if ((tp1 ne tp1w) || (tp2 ne tp2w)) lub(tp1w, tp2w, canConstrain = canConstrain, isSoft = isSoft)
23042299
else orType(tp1w, tp2w, isSoft = isSoft) // no need to check subtypes again
23052300
}
2306-
mergedLub(tp1.stripLazyRef, tp2.stripLazyRef)
2301+
mergedLub(dropExpr(tp1.stripLazyRef), dropExpr(tp2.stripLazyRef))
23072302
}
23082303

23092304
/** 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
24242419
/** There's a window of vulnerability between ElimByName and Erasure where some
24252420
* ExprTypes `=> T` that appear as parameters of function types are not yet converted
24262421
* 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
24282423
* ElimByName, we can't fix it beforehand by mapping all occurrences of `=> T` to
24292424
* `() ?=> T` since that could lead to cycles.
24302425
*/
24312426
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 =>
24332428
defn.ByNameFunction(rt)
24342429
case _ =>
24352430
tp
@@ -2442,7 +2437,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
24422437
val t2 = distributeAnd(tp2, tp1)
24432438
if (t2.exists) t2
24442439
else if (isErased) erasedGlb(tp1, tp2)
2445-
else liftIfHK(dropExpr(tp1), dropExpr(tp2), op, original, _ | _)
2440+
else liftIfHK(tp1, tp2, op, original, _ | _)
24462441
// The ` | ` on variances is needed since variances are associated with bounds
24472442
// not lambdas. Example:
24482443
//
@@ -2486,7 +2481,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
24862481
val t2 = distributeOr(tp2, tp1, isSoft)
24872482
if (t2.exists) t2
24882483
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), _ | _, _ & _)
24902485
}
24912486
}
24922487

0 commit comments

Comments
 (0)