Skip to content

Commit 744b5b0

Browse files
committed
Avoid -Ycheck error by refining <:< testing
1 parent 6c0b801 commit 744b5b0

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
417417
if (tp11.stripTypeVar eq tp12.stripTypeVar) recur(tp11, tp2)
418418
else thirdTry
419419
case tp1 @ OrType(tp11, tp12) =>
420+
420421
def joinOK = tp2.dealiasKeepRefiningAnnots match {
421422
case tp2: AppliedType if !tp2.tycon.typeSymbol.isClass =>
422423
// If we apply the default algorithm for `A[X] | B[Y] <: C[Z]` where `C` is a
@@ -427,6 +428,12 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
427428
case _ =>
428429
false
429430
}
431+
432+
def containsAnd(tp: Type): Boolean = tp.dealiasKeepRefiningAnnots match
433+
case tp: AndType => true
434+
case OrType(tp1, tp2) => containsAnd(tp1) || containsAnd(tp2)
435+
case _ => false
436+
430437
def widenOK =
431438
(tp2.widenSingletons eq tp2) &&
432439
(tp1.widenSingletons ne tp1) &&
@@ -435,7 +442,15 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] w
435442
if (tp2.atoms.nonEmpty && canCompare(tp2.atoms))
436443
tp1.atoms.nonEmpty && tp1.atoms.subsetOf(tp2.atoms)
437444
else
438-
widenOK || joinOK || recur(tp11, tp2) && recur(tp12, tp2)
445+
widenOK
446+
|| joinOK
447+
|| recur(tp11, tp2) && recur(tp12, tp2)
448+
|| containsAnd(tp1) && recur(tp1.join, tp2)
449+
// An & on the left side loses information. Compensate by also trying the join.
450+
// This is less ad-hoc than it looks since we produce joins in type inference,
451+
// and then need to check that they are indeed supertypes of the original types
452+
// under -Ycheck. Test case is i7965.scala.
453+
439454
case tp1: MatchType =>
440455
val reduced = tp1.reduced
441456
if (reduced.exists) recur(reduced, tp2) else thirdTry

tests/pos/i7965.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ trait Y
44
trait Z
55

66
abstract class Test {
7-
val x: Has[X] | (Has[Y] & Has[Z])
7+
def x: Has[X] | (Has[Y] & Has[Z])
8+
val y: Has[? >: (X & Y) | (X & Z) <: (X | Y) & (X | Z)] = x
9+
810
def foo[T <: Has[_]](has: T): T = has
911
foo(x)
1012
}

0 commit comments

Comments
 (0)