Skip to content

Commit c657700

Browse files
committed
Don't lose info in bounds when pruning
1 parent a7ef3e2 commit c657700

File tree

2 files changed

+20
-19
lines changed

2 files changed

+20
-19
lines changed

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

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -495,30 +495,31 @@ trait ConstraintHandling[AbstractContext] {
495495
*
496496
* @return The pruned type if all `addLess` calls succeed, `NoType` otherwise.
497497
*/
498-
def prune(bound: Type): Type = bound match {
499-
case bound: AndType =>
500-
val p1 = prune(bound.tp1)
501-
val p2 = prune(bound.tp2)
502-
if (p1.exists && p2.exists) bound.derivedAndType(p1, p2)
498+
def prune(bnd: Type): Type = bnd match {
499+
case bnd: AndType if !fromBelow =>
500+
val p1 = prune(bnd.tp1)
501+
val p2 = prune(bnd.tp2)
502+
if (p1.exists && p2.exists) bnd.derivedAndType(p1, p2)
503503
else NoType
504-
case bound: OrType =>
505-
val p1 = prune(bound.tp1)
506-
val p2 = prune(bound.tp2)
507-
if (p1.exists && p2.exists) bound.derivedOrType(p1, p2)
504+
case bnd: OrType if fromBelow =>
505+
val p1 = prune(bnd.tp1)
506+
val p2 = prune(bnd.tp2)
507+
if (p1.exists && p2.exists) bnd.derivedOrType(p1, p2)
508508
else NoType
509-
case bound: TypeVar if constraint contains bound.origin =>
510-
prune(bound.underlying)
511-
case bound: TypeParamRef =>
512-
constraint.entry(bound) match {
513-
case NoType => pruneLambdaParams(bound)
509+
case bnd: TypeVar if constraint contains bnd.origin =>
510+
prune(bnd.underlying)
511+
case bnd: TypeParamRef if bnd ne param =>
512+
constraint.entry(bnd) match {
513+
case NoType => pruneLambdaParams(bnd)
514514
case _: TypeBounds =>
515-
if (!addParamBound(bound)) NoType
515+
assertFail(i"pruning $param $bound $fromBelow $bnd")
516+
if (!addParamBound(bnd)) NoType
516517
else if (fromBelow) defn.NothingType
517518
else defn.AnyType
518519
case inst =>
519520
prune(inst)
520521
}
521-
case bound: ExprType =>
522+
case bnd: ExprType =>
522523
// ExprTypes are not value types, so type parameters should not
523524
// be instantiated to ExprTypes. A scenario where such an attempted
524525
// instantiation can happen is if we unify (=> T) => () with A => ()
@@ -530,7 +531,7 @@ trait ConstraintHandling[AbstractContext] {
530531
// the resulting types down) and is largely unknown terrain.
531532
NoType
532533
case _ =>
533-
pruneLambdaParams(bound)
534+
pruneLambdaParams(bnd)
534535
}
535536

536537
def kindCompatible(tp1: Type, tp2: Type): Boolean =

tests/neg/i6565.scala renamed to tests/pos/i6565.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ lazy val ok: Lifted[String] = { // ok despite map returning a union
1212
point("a").map(_ => if true then "foo" else error) // ok
1313
}
1414

15-
lazy val bad: Lifted[String] = { // found Lifted[Object]
16-
point("a").flatMap(_ => point("b").map(_ => if true then "foo" else error)) // error
15+
lazy val nowAlsoOK: Lifted[String] = {
16+
point("a").flatMap(_ => point("b").map(_ => if true then "foo" else error))
1717
}

0 commit comments

Comments
 (0)