Skip to content

Commit be87f24

Browse files
EugeneFlesselleWojciechMazur
authored andcommitted
Do not propagate TypeErrors of ops from TypeComparer#tryAlso
In pos-deep-subtype/i21015.scala:30, we ask the TypeComparer if `M1[Int] <:< M1[A]` `isMatchingApply` first tries `isSubArgs` which succeeds, but then also checks if a weaker constraint is generated by `recur(tp1.superTypeNormalized, tp2.superTypeNormalized)`. The latter throws a `RecursionOverflow` which, before the changes, bypassed the former successful check, and failed the overall subtype test. Fix #21015 [Cherry-picked 2d0e373]
1 parent 1fb6922 commit be87f24

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1851,7 +1851,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
18511851
// check whether `op2` generates a weaker constraint than `op1`
18521852
val leftConstraint = constraint
18531853
constraint = preConstraint
1854-
if !(op && subsumes(leftConstraint, constraint, preConstraint)) then
1854+
val res = try op catch case _: TypeError => false
1855+
if !(res && subsumes(leftConstraint, constraint, preConstraint)) then
18551856
if constr != noPrinter && !subsumes(constraint, leftConstraint, preConstraint) then
18561857
constr.println(i"CUT - prefer $leftConstraint over $constraint")
18571858
constraint = leftConstraint

tests/pos-deep-subtype/i21015.scala

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
type Init[Coll[_], A, T <: Tuple] = T match
3+
case EmptyTuple => A
4+
case head *: rest => InitCons[Coll, A, head, rest]
5+
6+
type InitCons[Coll[_], A, H, Rest <: Tuple] = H match
7+
case Int => Init[Coll, Coll[A], Rest]
8+
case _ => Unit
9+
10+
def fillVector[A, T <: Tuple](dims: T)(x: => A): Init[Vector, A, T] =
11+
dims match
12+
case _: EmptyTuple => x
13+
case (p : (head *: rest)) =>
14+
val (head *: rest) = p
15+
head match
16+
case size: Int => fillVector(rest)(Vector.fill(size)(x))
17+
case _ => ()
18+
19+
20+
object Minimization:
21+
22+
type M1[A] = Int match
23+
case 1 => M2[A]
24+
25+
type M2[A] = Int match
26+
case 2 => M1[Option[A]]
27+
28+
def m1[A](x: A): M1[A] = ???
29+
30+
val _: M1[Int] = m1(1) // was error
31+
val _: M1[Int] = m1[Int](1) // ok
32+
val _: M1[Int] =
33+
val x = m1(1)
34+
x // ok
35+
36+
end Minimization

0 commit comments

Comments
 (0)