Skip to content

Commit 1a035fc

Browse files
committed
restrict mirrors of any union type
1 parent 001bfc3 commit 1a035fc

File tree

6 files changed

+55
-31
lines changed

6 files changed

+55
-31
lines changed

compiler/src/dotty/tools/dotc/typer/Synthesizer.scala

+7-9
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,9 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
280280

281281
def whyNotAcceptableType(tp: Type, cls: Symbol): String = tp match
282282
case tp: HKTypeLambda if tp.resultType.isInstanceOf[HKTypeLambda] =>
283-
i"its subpart $tp is not a supported kind (either `*` or `* -> *`)"
283+
i"its subpart `$tp` is not a supported kind (either `*` or `* -> *`)"
284284
case tp: TypeProxy => whyNotAcceptableType(tp.underlying, cls)
285-
case OrType(tp1, tp2) =>
286-
Seq(tp1, tp2).map(whyNotAcceptableType(_, cls)).find(_.nonEmpty).getOrElse("")
285+
case OrType(tp1, tp2) => i"its subpart `$tp` is a top-level union type."
287286
case _ =>
288287
if tp.classSymbol eq cls then ""
289288
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):
339338
if acceptableMsg.isEmpty then
340339
if cls.isGenericProduct then makeProductMirror(cls)
341340
else withErrors(i"$cls is not a generic product because ${cls.whyNotGenericProduct}")
342-
else withErrors(i"type $mirroredType is not a generic product because $acceptableMsg")
341+
else withErrors(i"type `$mirroredType` is not a generic product because $acceptableMsg")
343342
end productMirror
344343

345344
private def sumMirror(mirroredType: Type, formal: Type, span: Span)(using Context): TreeWithErrors =
@@ -348,12 +347,11 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
348347
val clsIsGenericSum = cls.isGenericSum
349348

350349
def whyNotAcceptableType(tp: Type): String = tp match
351-
case tp: TermRef => i"its subpart $tp is a term reference"
350+
case tp: TermRef => i"its subpart `$tp` is a term reference"
352351
case tp: HKTypeLambda if tp.resultType.isInstanceOf[HKTypeLambda] =>
353-
i"its subpart $tp is not a supported kind (either `*` or `* -> *`)"
352+
i"its subpart `$tp` is not a supported kind (either `*` or `* -> *`)"
354353
case tp: TypeProxy => whyNotAcceptableType(tp.underlying)
355-
case OrType(tp1, tp2) =>
356-
Seq(tp1, tp2).map(whyNotAcceptableType).find(_.nonEmpty).getOrElse("")
354+
case OrType(tp1, tp2) => i"its subpart `$tp` is a top-level union type."
357355
case _ =>
358356
if tp.classSymbol eq cls then ""
359357
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):
416414
else anonymousMirror(monoType, ExtendsSumMirror, span)
417415
withNoErrors(mirrorRef.cast(mirrorType))
418416
else if acceptableMsg.nonEmpty then
419-
withErrors(i"type $mirroredType is not a generic sum because $acceptableMsg")
417+
withErrors(i"type `$mirroredType` is not a generic sum because $acceptableMsg")
420418
else if !clsIsGenericSum then
421419
withErrors(i"$cls is not a generic sum because ${cls.whyNotGenericSum}")
422420
else

tests/neg/i14025.check

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
-- Error: tests/neg/i14025.scala:1:88 ----------------------------------------------------------------------------------
22
1 |val foo = summon[deriving.Mirror.Product { type MirroredType = [X] =>> [Y] =>> (X, Y) }] // error
33
| ^
4-
|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 `* -> *`)
4+
|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 `* -> *`)
55
-- Error: tests/neg/i14025.scala:2:90 ----------------------------------------------------------------------------------
66
2 |val bar = summon[deriving.Mirror.Sum { type MirroredType = [X] =>> [Y] =>> List[(X, Y)] }] // error
77
| ^
8-
|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 `* -> *`)
8+
|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 `* -> *`)

tests/neg/i14823.check

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
8 |val baz = summon[Mirror.Of[SubA[Int] | SubB[Int]]] // error
33
| ^
44
|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]]:
5-
| * type SubA[Int] | SubB[Int] is not a generic product because a subpart reduces to the more precise class SubA, expected class Cov
6-
| * type SubA[Int] | SubB[Int] is not a generic sum because a subpart reduces to the more precise class SubA, expected class Cov
5+
| * type `SubA[Int] | SubB[Int]` is not a generic product because its subpart `SubA[Int] | SubB[Int]` is a top-level union type.
6+
| * type `SubA[Int] | SubB[Int]` is not a generic sum because its subpart `SubA[Int] | SubB[Int]` is a top-level union type.

tests/neg/i14823a.check

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
-- Error: tests/neg/i14823a.scala:16:48 --------------------------------------------------------------------------------
2+
16 |val foo = summon[Mirror.Of[Box[Int] | Box[Int]]] // error
3+
| ^
4+
|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]]:
5+
| * type `Box[Int] | Box[Int]` is not a generic product because its subpart `Box[Int] | Box[Int]` is a top-level union type.
6+
| * type `Box[Int] | Box[Int]` is not a generic sum because its subpart `Box[Int] | Box[Int]` is a top-level union type.
7+
-- Error: tests/neg/i14823a.scala:17:58 --------------------------------------------------------------------------------
8+
17 |val bar = summon[MirrorK1.Of[[X] =>> Box[Int] | Box[Int]]] // error
9+
| ^
10+
|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]]:
11+
| * type `[A] =>> Box[Int] | Box[Int]` is not a generic product because its subpart `Box[Int] | Box[Int]` is a top-level union type.
12+
| * type `[A] =>> Box[Int] | Box[Int]` is not a generic sum because its subpart `Box[Int] | Box[Int]` is a top-level union type.
13+
-- Error: tests/neg/i14823a.scala:18:63 --------------------------------------------------------------------------------
14+
18 |def baz = summon[deriving.Mirror.Of[Foo[String] | Foo[String]]] // error
15+
| ^
16+
|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]]:
17+
| * type `Foo[String] | Foo[String]` is not a generic product because its subpart `Foo[String] | Foo[String]` is a top-level union type.
18+
| * type `Foo[String] | Foo[String]` is not a generic sum because its subpart `Foo[String] | Foo[String]` is a top-level union type.
19+
-- Error: tests/neg/i14823a.scala:20:66 --------------------------------------------------------------------------------
20+
20 |def qux = summon[deriving.Mirror.Of[Option[Int] | Option[String]]] // error
21+
| ^
22+
|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]]:
23+
| * type `Option[Int] | Option[String]` is not a generic product because its subpart `Option[Int] | Option[String]` is a top-level union type.
24+
| * type `Option[Int] | Option[String]` is not a generic sum because its subpart `Option[Int] | Option[String]` is a top-level union type.

tests/neg/i14823a.scala

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import deriving.Mirror
2+
3+
object MirrorK1:
4+
type Of[F[_]] = Mirror { type MirroredType[A] = F[A] }
5+
6+
sealed trait Box[T]
7+
object Box
8+
9+
case class Child[T]() extends Box[T]
10+
11+
sealed abstract class Foo[T]
12+
object Foo {
13+
case class A[T]() extends Foo[T]
14+
}
15+
16+
val foo = summon[Mirror.Of[Box[Int] | Box[Int]]] // error
17+
val bar = summon[MirrorK1.Of[[X] =>> Box[Int] | Box[Int]]] // error
18+
def baz = summon[deriving.Mirror.Of[Foo[String] | Foo[String]]] // error
19+
20+
def qux = summon[deriving.Mirror.Of[Option[Int] | Option[String]]] // error

tests/pos/i14823.scala

-18
This file was deleted.

0 commit comments

Comments
 (0)