From 57da13e36a255ca17c35bac5ea2150e32864c5c7 Mon Sep 17 00:00:00 2001 From: odersky Date: Mon, 26 Sep 2022 11:08:05 +0200 Subject: [PATCH] Regression test for #8984 Fixes #8984, in the sense that it crashed before and now an error is reported. --- tests/neg/i8984.check | 9 +++++++ tests/neg/i8984.scala | 61 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 tests/neg/i8984.check create mode 100644 tests/neg/i8984.scala diff --git a/tests/neg/i8984.check b/tests/neg/i8984.check new file mode 100644 index 000000000000..b66cee1459d6 --- /dev/null +++ b/tests/neg/i8984.check @@ -0,0 +1,9 @@ +-- [E007] Type Mismatch Error: tests/neg/i8984.scala:36:52 ------------------------------------------------------------- +36 | case Cat(_, "red", rest) => dropRedCats(rest) // error + | ^^^^ + | Found: (rest : Any) + | Required: Fix.T[F] + | + | where: F is a type in method dropRedCats with bounds >: Cat and <: [a] =>> Any + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i8984.scala b/tests/neg/i8984.scala new file mode 100644 index 000000000000..ff798d803ba3 --- /dev/null +++ b/tests/neg/i8984.scala @@ -0,0 +1,61 @@ +import scala.annotation.tailrec +type |@[F[+_], G[+_]] = [a] =>> F[a] | G[a] + +object Fix: + opaque type T[+F[+_]] = ApplyFix.T[F] + + def apply[F[+_]](f: F[Fix[F]]): T[F] = ApplyFix(f) + + extension [F[+_]](fix: T[F]) + def value: F[Fix[F]] = ApplyFix.unwrap(fix) + + object ApplyFix: + opaque type T[+F[+_]] = F[Fix[F]] + + def apply[F[+_]](f: F[Fix[F]]): T[F] = f + + def unwrap[F[+_]](v: T[F]): F[Fix[F]] = v + +type Fix[+F[+_]] = Fix.T[F] + +final case class Cat[+R](name: String, fur: String, rest: R) +object Cat: + def of[R, F[+_]](name: String, fur: String, rest: Fix[F]): Fix[F |@ Cat] = Fix(new Cat(name, fur, rest)) + +final case class Dog[+R](name: String, size: Long, rest: R) +object Dog: + def of[R, F[+_]](name: String, size: Long, rest: Fix[F]): Fix[F |@ Dog] = Fix(new Dog(name, size, rest)) + +case object End: + type f[+a] = End.type + def apply() = Fix[f](End) + +object DropRed: + @tailrec def dropRedCats[F[+a] >: Cat[a]](cats: Fix[F]): Fix[F] = + cats.value match + case Cat(_, "red", rest) => dropRedCats(rest) // error + case _ => cats + + type CatDogVector = Vector[Either[Cat[Unit], Dog[Unit]]] + type CatOrDogs[+a] = Cat[a] | Dog[a] | End.type + + extension (catDogs: Fix[CatOrDogs]) def toVector : CatDogVector = + @tailrec def go(acc: CatDogVector, catDogs: Fix[CatOrDogs]) : CatDogVector = catDogs.value match + case Cat(name, fur, rest) => go(acc :+ Left(Cat(name, fur, ())), rest) + case Dog(name, size, rest) => go(acc :+ Right(Dog(name, size, ())), rest) + case End => acc + + go(Vector(), catDogs) + + val x = + Cat.of("lilly" , "red" , + Cat.of("anya" , "red" , + Cat.of("boris" , "black", + Dog.of("mashka", 3 , + Cat.of("manya" , "red" , + End()))))) + + + def main(args: Array[String]) = + println(x.toVector) + println(dropRedCats(x).toVector)