diff --git a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala index 36addf639932..baa4ef57acd3 100644 --- a/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Synthesizer.scala @@ -280,10 +280,9 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): def whyNotAcceptableType(tp: Type, cls: Symbol): String = tp match case tp: HKTypeLambda if tp.resultType.isInstanceOf[HKTypeLambda] => - i"its subpart $tp is not a supported kind (either `*` or `* -> *`)" + i"its subpart `$tp` is not a supported kind (either `*` or `* -> *`)" case tp: TypeProxy => whyNotAcceptableType(tp.underlying, cls) - case OrType(tp1, tp2) => - Seq(tp1, tp2).map(whyNotAcceptableType(_, cls)).find(_.nonEmpty).getOrElse("") + case OrType(tp1, tp2) => i"its subpart `$tp` is a top-level union type." case _ => if tp.classSymbol eq cls then "" else i"a subpart reduces to the more precise ${tp.classSymbol}, expected $cls" @@ -339,7 +338,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): if acceptableMsg.isEmpty then if cls.isGenericProduct then makeProductMirror(cls) else withErrors(i"$cls is not a generic product because ${cls.whyNotGenericProduct}") - else withErrors(i"type $mirroredType is not a generic product because $acceptableMsg") + else withErrors(i"type `$mirroredType` is not a generic product because $acceptableMsg") end productMirror private def sumMirror(mirroredType: Type, formal: Type, span: Span)(using Context): TreeWithErrors = @@ -348,12 +347,11 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): val clsIsGenericSum = cls.isGenericSum def whyNotAcceptableType(tp: Type): String = tp match - case tp: TermRef => i"its subpart $tp is a term reference" + case tp: TermRef => i"its subpart `$tp` is a term reference" case tp: HKTypeLambda if tp.resultType.isInstanceOf[HKTypeLambda] => - i"its subpart $tp is not a supported kind (either `*` or `* -> *`)" + i"its subpart `$tp` is not a supported kind (either `*` or `* -> *`)" case tp: TypeProxy => whyNotAcceptableType(tp.underlying) - case OrType(tp1, tp2) => - Seq(tp1, tp2).map(whyNotAcceptableType).find(_.nonEmpty).getOrElse("") + case OrType(tp1, tp2) => i"its subpart `$tp` is a top-level union type." case _ => if tp.classSymbol eq cls then "" else i"a subpart reduces to the more precise ${tp.classSymbol}, expected $cls" @@ -416,7 +414,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context): else anonymousMirror(monoType, ExtendsSumMirror, span) withNoErrors(mirrorRef.cast(mirrorType)) else if acceptableMsg.nonEmpty then - withErrors(i"type $mirroredType is not a generic sum because $acceptableMsg") + withErrors(i"type `$mirroredType` is not a generic sum because $acceptableMsg") else if !clsIsGenericSum then withErrors(i"$cls is not a generic sum because ${cls.whyNotGenericSum}") else diff --git a/tests/neg/i14025.check b/tests/neg/i14025.check index bd29136e3ab0..3c67b954297b 100644 --- a/tests/neg/i14025.check +++ b/tests/neg/i14025.check @@ -1,8 +1,8 @@ -- Error: tests/neg/i14025.scala:1:88 ---------------------------------------------------------------------------------- 1 |val foo = summon[deriving.Mirror.Product { type MirroredType = [X] =>> [Y] =>> (X, Y) }] // error | ^ - |No given instance of type deriving.Mirror.Product{MirroredType[X] = [Y] =>> (X, Y)} was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type deriving.Mirror.Product{MirroredType[X] = [Y] =>> (X, Y)}: type [X] =>> [Y] =>> (X, Y) is not a generic product because its subpart [X] =>> [Y] =>> (X, Y) is not a supported kind (either `*` or `* -> *`) + |No given instance of type deriving.Mirror.Product{MirroredType[X] = [Y] =>> (X, Y)} was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type deriving.Mirror.Product{MirroredType[X] = [Y] =>> (X, Y)}: type `[X] =>> [Y] =>> (X, Y)` is not a generic product because its subpart `[X] =>> [Y] =>> (X, Y)` is not a supported kind (either `*` or `* -> *`) -- Error: tests/neg/i14025.scala:2:90 ---------------------------------------------------------------------------------- 2 |val bar = summon[deriving.Mirror.Sum { type MirroredType = [X] =>> [Y] =>> List[(X, Y)] }] // error | ^ - |No given instance of type deriving.Mirror.Sum{MirroredType[X] = [Y] =>> List[(X, Y)]} was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type deriving.Mirror.Sum{MirroredType[X] = [Y] =>> List[(X, Y)]}: type [X] =>> [Y] =>> List[(X, Y)] is not a generic sum because its subpart [X] =>> [Y] =>> List[(X, Y)] is not a supported kind (either `*` or `* -> *`) + |No given instance of type deriving.Mirror.Sum{MirroredType[X] = [Y] =>> List[(X, Y)]} was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type deriving.Mirror.Sum{MirroredType[X] = [Y] =>> List[(X, Y)]}: type `[X] =>> [Y] =>> List[(X, Y)]` is not a generic sum because its subpart `[X] =>> [Y] =>> List[(X, Y)]` is not a supported kind (either `*` or `* -> *`) diff --git a/tests/neg/i14823.check b/tests/neg/i14823.check index 1da3c0560d9c..4d5a64680882 100644 --- a/tests/neg/i14823.check +++ b/tests/neg/i14823.check @@ -2,5 +2,5 @@ 8 |val baz = summon[Mirror.Of[SubA[Int] | SubB[Int]]] // error | ^ |No given instance of type deriving.Mirror.Of[SubA[Int] | SubB[Int]] was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type deriving.Mirror.Of[SubA[Int] | SubB[Int]]: - | * type SubA[Int] | SubB[Int] is not a generic product because a subpart reduces to the more precise class SubA, expected class Cov - | * type SubA[Int] | SubB[Int] is not a generic sum because a subpart reduces to the more precise class SubA, expected class Cov + | * type `SubA[Int] | SubB[Int]` is not a generic product because its subpart `SubA[Int] | SubB[Int]` is a top-level union type. + | * type `SubA[Int] | SubB[Int]` is not a generic sum because its subpart `SubA[Int] | SubB[Int]` is a top-level union type. diff --git a/tests/neg/i14823a.check b/tests/neg/i14823a.check new file mode 100644 index 000000000000..9c917548d9bf --- /dev/null +++ b/tests/neg/i14823a.check @@ -0,0 +1,24 @@ +-- Error: tests/neg/i14823a.scala:16:48 -------------------------------------------------------------------------------- +16 |val foo = summon[Mirror.Of[Box[Int] | Box[Int]]] // error + | ^ + |No given instance of type deriving.Mirror.Of[Box[Int] | Box[Int]] was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type deriving.Mirror.Of[Box[Int] | Box[Int]]: + | * type `Box[Int] | Box[Int]` is not a generic product because its subpart `Box[Int] | Box[Int]` is a top-level union type. + | * type `Box[Int] | Box[Int]` is not a generic sum because its subpart `Box[Int] | Box[Int]` is a top-level union type. +-- Error: tests/neg/i14823a.scala:17:58 -------------------------------------------------------------------------------- +17 |val bar = summon[MirrorK1.Of[[X] =>> Box[Int] | Box[Int]]] // error + | ^ + |No given instance of type MirrorK1.Of[[X] =>> Box[Int] | Box[Int]] was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type MirrorK1.Of[[X] =>> Box[Int] | Box[Int]]: + | * type `[A] =>> Box[Int] | Box[Int]` is not a generic product because its subpart `Box[Int] | Box[Int]` is a top-level union type. + | * type `[A] =>> Box[Int] | Box[Int]` is not a generic sum because its subpart `Box[Int] | Box[Int]` is a top-level union type. +-- Error: tests/neg/i14823a.scala:18:63 -------------------------------------------------------------------------------- +18 |def baz = summon[deriving.Mirror.Of[Foo[String] | Foo[String]]] // error + | ^ + |No given instance of type deriving.Mirror.Of[Foo[String] | Foo[String]] was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type deriving.Mirror.Of[Foo[String] | Foo[String]]: + | * type `Foo[String] | Foo[String]` is not a generic product because its subpart `Foo[String] | Foo[String]` is a top-level union type. + | * type `Foo[String] | Foo[String]` is not a generic sum because its subpart `Foo[String] | Foo[String]` is a top-level union type. +-- Error: tests/neg/i14823a.scala:20:66 -------------------------------------------------------------------------------- +20 |def qux = summon[deriving.Mirror.Of[Option[Int] | Option[String]]] // error + | ^ + |No given instance of type deriving.Mirror.Of[Option[Int] | Option[String]] was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type deriving.Mirror.Of[Option[Int] | Option[String]]: + | * type `Option[Int] | Option[String]` is not a generic product because its subpart `Option[Int] | Option[String]` is a top-level union type. + | * type `Option[Int] | Option[String]` is not a generic sum because its subpart `Option[Int] | Option[String]` is a top-level union type. diff --git a/tests/neg/i14823a.scala b/tests/neg/i14823a.scala new file mode 100644 index 000000000000..b80f8e5062e3 --- /dev/null +++ b/tests/neg/i14823a.scala @@ -0,0 +1,20 @@ +import deriving.Mirror + +object MirrorK1: + type Of[F[_]] = Mirror { type MirroredType[A] = F[A] } + +sealed trait Box[T] +object Box + +case class Child[T]() extends Box[T] + +sealed abstract class Foo[T] +object Foo { + case class A[T]() extends Foo[T] +} + +val foo = summon[Mirror.Of[Box[Int] | Box[Int]]] // error +val bar = summon[MirrorK1.Of[[X] =>> Box[Int] | Box[Int]]] // error +def baz = summon[deriving.Mirror.Of[Foo[String] | Foo[String]]] // error + +def qux = summon[deriving.Mirror.Of[Option[Int] | Option[String]]] // error diff --git a/tests/pos/i14823.scala b/tests/pos/i14823.scala deleted file mode 100644 index 01b8a76095d5..000000000000 --- a/tests/pos/i14823.scala +++ /dev/null @@ -1,18 +0,0 @@ -import deriving.Mirror - -object MirrorK1: - type Of[F[_]] = Mirror { type MirroredType[A] = F[A] } - -sealed trait Box[T] -object Box - -case class Child[T]() extends Box[T] - -sealed abstract class Foo[T] -object Foo { - case class A[T]() extends Foo[T] -} - -val foo = summon[Mirror.Of[Box[Int] | Box[Int]]] -val bar = summon[MirrorK1.Of[[X] =>> Box[Int] | Box[Int]]] -def baz = summon[deriving.Mirror.Of[Foo[String] | Foo[String]]]