From c71b2539f97562fe5614e11930a6780d96ee6a97 Mon Sep 17 00:00:00 2001 From: Matt Bovel Date: Fri, 10 Jan 2025 16:32:36 +0000 Subject: [PATCH] Rollback constraints in compareAppliedTypeParamRef Co-authored-by: Guillaume Martres --- .../dotty/tools/dotc/core/TypeComparer.scala | 5 +++-- tests/pos/20519.scala | 10 ++++++++++ tests/pos/20519b.scala | 16 +++++++++++++++ tests/pos/20519c.scala | 20 +++++++++++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 tests/pos/20519.scala create mode 100644 tests/pos/20519b.scala create mode 100644 tests/pos/20519c.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 8414c3795f49..bbe157d4a29b 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -1244,8 +1244,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling tl => otherTycon.appliedTo(bodyArgs(tl))) else otherTycon - (assumedTrue(tycon) || directionalIsSubType(tycon, adaptedTycon)) && - directionalRecur(adaptedTycon.appliedTo(args), other) + rollbackConstraintsUnless: + (assumedTrue(tycon) || directionalIsSubType(tycon, adaptedTycon)) + && directionalRecur(adaptedTycon.appliedTo(args), other) } } end compareAppliedTypeParamRef diff --git a/tests/pos/20519.scala b/tests/pos/20519.scala new file mode 100644 index 000000000000..866e24e8fb6f --- /dev/null +++ b/tests/pos/20519.scala @@ -0,0 +1,10 @@ +class Box[T](val value: T) + +def boo[F[_], A](e: F[Box[A]]): F[A] = ??? + +type Result[G[_], B] = G[Box[B]] + +def main = + val b: Result[Option, Int] = ??? + val c = boo(b) + c: Option[Int] diff --git a/tests/pos/20519b.scala b/tests/pos/20519b.scala new file mode 100644 index 000000000000..4dadf2aa70b6 --- /dev/null +++ b/tests/pos/20519b.scala @@ -0,0 +1,16 @@ +trait TCl[F[_]] + +def boo[F[_], A](e: F[Option[A]], ev: TCl[F]): Unit = () + +type Result[F[_], A] = F[Option[A]] + +@main def main = + summon[Result[Option, Int] =:= Option[Option[Int]]] + + val ev = new TCl[Option] {} + + val b: Result[Option, Int] = None + boo(b, ev) + + val b2: Option[Option[Int]] = None + boo(b2, ev) diff --git a/tests/pos/20519c.scala b/tests/pos/20519c.scala new file mode 100644 index 000000000000..91eb33a7b892 --- /dev/null +++ b/tests/pos/20519c.scala @@ -0,0 +1,20 @@ +object Main { + trait TCl[F[_]] + + implicit class Stx[F[_], A](e: F[Option[A]]) { + def boo(implicit ev: TCl[F]): Unit = () + } + + type Result[F[_], A] = F[Option[A]] + + implicit val t: TCl[Option] = new TCl[Option] {} + + def main(args: Array[String]): Unit = { + val b: Result[Option, Int] = None + b.boo + + // works without the alias: + val b2: Option[Option[Int]] = None + b2.boo + } +}