Skip to content

Commit

Permalink
Move dropExpr upstream to glb and lub
Browse files Browse the repository at this point in the history
Avoids follow-up failures in Ycheck for the test case.

[Cherry-picked 278beb8]
  • Loading branch information
odersky authored and WojciechMazur committed Jun 28, 2024
1 parent 71cbbe1 commit 0b44bbe
Showing 1 changed file with 33 additions and 38 deletions.
71 changes: 33 additions & 38 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2230,40 +2230,35 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
else if !tp2.exists || (tp2 eq WildcardType) then tp1
else if tp1.isAny && !tp2.isLambdaSub || tp1.isAnyKind || isBottom(tp2) then tp2
else if tp2.isAny && !tp1.isLambdaSub || tp2.isAnyKind || isBottom(tp1) then tp1
else tp2 match
case tp2: LazyRef =>
glb(tp1, tp2.ref)
case _ =>
tp1 match
case tp1: LazyRef =>
glb(tp1.ref, tp2)
case _ =>
val tp1a = dropIfSuper(tp1, tp2)
if tp1a ne tp1 then glb(tp1a, tp2)
else
val tp2a = dropIfSuper(tp2, tp1)
if tp2a ne tp2 then glb(tp1, tp2a)
else tp2 match // normalize to disjunctive normal form if possible.
case tp2 @ OrType(tp21, tp22) =>
lub(tp1 & tp21, tp1 & tp22, isSoft = tp2.isSoft)
case _ =>
tp1 match
case tp1 @ OrType(tp11, tp12) =>
lub(tp11 & tp2, tp12 & tp2, isSoft = tp1.isSoft)
case tp1: ConstantType =>
tp2 match
case tp2: ConstantType =>
// Make use of the fact that the intersection of two constant types
// types which are not subtypes of each other is known to be empty.
// Note: The same does not apply to singleton types in general.
// E.g. we could have a pattern match against `x.type & y.type`
// which might succeed if `x` and `y` happen to be the same ref
// at run time. It would not work to replace that with `Nothing`.
// However, maybe we can still apply the replacement to
// types which are not explicitly written.
NothingType
case _ => andType(tp1, tp2)
else
def mergedGlb(tp1: Type, tp2: Type): Type =
val tp1a = dropIfSuper(tp1, tp2)
if tp1a ne tp1 then glb(tp1a, tp2)
else
val tp2a = dropIfSuper(tp2, tp1)
if tp2a ne tp2 then glb(tp1, tp2a)
else tp2 match // normalize to disjunctive normal form if possible.
case tp2 @ OrType(tp21, tp22) =>
lub(tp1 & tp21, tp1 & tp22, isSoft = tp2.isSoft)
case _ =>
tp1 match
case tp1 @ OrType(tp11, tp12) =>
lub(tp11 & tp2, tp12 & tp2, isSoft = tp1.isSoft)
case tp1: ConstantType =>
tp2 match
case tp2: ConstantType =>
// Make use of the fact that the intersection of two constant types
// types which are not subtypes of each other is known to be empty.
// Note: The same does not apply to singleton types in general.
// E.g. we could have a pattern match against `x.type & y.type`
// which might succeed if `x` and `y` happen to be the same ref
// at run time. It would not work to replace that with `Nothing`.
// However, maybe we can still apply the replacement to
// types which are not explicitly written.
NothingType
case _ => andType(tp1, tp2)
case _ => andType(tp1, tp2)
mergedGlb(dropExpr(tp1.stripLazyRef), dropExpr(tp2.stripLazyRef))
}

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

/** Try to produce joint arguments for a lub `A[T_1, ..., T_n] | A[T_1', ..., T_n']` using
Expand Down Expand Up @@ -2424,12 +2419,12 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
/** There's a window of vulnerability between ElimByName and Erasure where some
* ExprTypes `=> T` that appear as parameters of function types are not yet converted
* to by-name functions `() ?=> T`. These would cause an assertion violation when
* used as operands of & or |. We fix this on the fly here. As explained in
* used as operands of glb or lub. We fix this on the fly here. As explained in
* ElimByName, we can't fix it beforehand by mapping all occurrences of `=> T` to
* `() ?=> T` since that could lead to cycles.
*/
private def dropExpr(tp: Type): Type = tp match
case ExprType(rt) if Phases.elimByNamePhase <= ctx.phase && !ctx.erasedTypes =>
case ExprType(rt) if (Phases.elimByNamePhase <= ctx.phase) && !ctx.erasedTypes =>
defn.ByNameFunction(rt)
case _ =>
tp
Expand All @@ -2442,7 +2437,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
val t2 = distributeAnd(tp2, tp1)
if (t2.exists) t2
else if (isErased) erasedGlb(tp1, tp2)
else liftIfHK(dropExpr(tp1), dropExpr(tp2), op, original, _ | _)
else liftIfHK(tp1, tp2, op, original, _ | _)
// The ` | ` on variances is needed since variances are associated with bounds
// not lambdas. Example:
//
Expand Down Expand Up @@ -2486,7 +2481,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
val t2 = distributeOr(tp2, tp1, isSoft)
if (t2.exists) t2
else if (isErased) erasedLub(tp1, tp2)
else liftIfHK(dropExpr(tp1), dropExpr(tp2), OrType.balanced(_, _, soft = isSoft), _ | _, _ & _)
else liftIfHK(tp1, tp2, OrType.balanced(_, _, soft = isSoft), _ | _, _ & _)
}
}

Expand Down

0 comments on commit 0b44bbe

Please sign in to comment.