Skip to content

Commit 5369d1a

Browse files
authored
Rollback constraints in compareAppliedTypeParamRef (#22339)
This PR adds a `rollbackConstraintsUnless` in `compareAppliedTypeParamRef`. It is required in case the call to `directionalIsSubType` introduces constraints and the call to `directionalRecur` returns `false`. Fixes #20519
2 parents af22ce2 + c71b253 commit 5369d1a

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

Diff for: compiler/src/dotty/tools/dotc/core/TypeComparer.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -1244,8 +1244,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
12441244
tl => otherTycon.appliedTo(bodyArgs(tl)))
12451245
else
12461246
otherTycon
1247-
(assumedTrue(tycon) || directionalIsSubType(tycon, adaptedTycon)) &&
1248-
directionalRecur(adaptedTycon.appliedTo(args), other)
1247+
rollbackConstraintsUnless:
1248+
(assumedTrue(tycon) || directionalIsSubType(tycon, adaptedTycon))
1249+
&& directionalRecur(adaptedTycon.appliedTo(args), other)
12491250
}
12501251
}
12511252
end compareAppliedTypeParamRef

Diff for: tests/pos/20519.scala

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Box[T](val value: T)
2+
3+
def boo[F[_], A](e: F[Box[A]]): F[A] = ???
4+
5+
type Result[G[_], B] = G[Box[B]]
6+
7+
def main =
8+
val b: Result[Option, Int] = ???
9+
val c = boo(b)
10+
c: Option[Int]

Diff for: tests/pos/20519b.scala

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
trait TCl[F[_]]
2+
3+
def boo[F[_], A](e: F[Option[A]], ev: TCl[F]): Unit = ()
4+
5+
type Result[F[_], A] = F[Option[A]]
6+
7+
@main def main =
8+
summon[Result[Option, Int] =:= Option[Option[Int]]]
9+
10+
val ev = new TCl[Option] {}
11+
12+
val b: Result[Option, Int] = None
13+
boo(b, ev)
14+
15+
val b2: Option[Option[Int]] = None
16+
boo(b2, ev)

Diff for: tests/pos/20519c.scala

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
object Main {
2+
trait TCl[F[_]]
3+
4+
implicit class Stx[F[_], A](e: F[Option[A]]) {
5+
def boo(implicit ev: TCl[F]): Unit = ()
6+
}
7+
8+
type Result[F[_], A] = F[Option[A]]
9+
10+
implicit val t: TCl[Option] = new TCl[Option] {}
11+
12+
def main(args: Array[String]): Unit = {
13+
val b: Result[Option, Int] = None
14+
b.boo
15+
16+
// works without the alias:
17+
val b2: Option[Option[Int]] = None
18+
b2.boo
19+
}
20+
}

0 commit comments

Comments
 (0)