Skip to content

Commit 5677126

Browse files
committed
improve error message
1 parent 75f5088 commit 5677126

File tree

3 files changed

+35
-22
lines changed

3 files changed

+35
-22
lines changed

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

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
302302
case ClassSymbol(cls) => cls
303303
case GenericTuple(arity, _) =>
304304
if arity <= Definitions.MaxTupleArity then defn.TupleType(arity).nn.classSymbol
305-
else defn.TupleXXLClass
305+
else defn.PairClass
306306

307307
object MirrorSource:
308308
def tuple(tps: List[Type]): MirrorSource.GenericTuple = MirrorSource.GenericTuple(tps.size, tps)
@@ -340,22 +340,25 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
340340
else None
341341

342342
/** do all parts match the class symbol? */
343-
def whyNotAcceptableType(tp: Type, msrc: MirrorSource): String = tp match
344-
case tp: HKTypeLambda if tp.resultType.isInstanceOf[HKTypeLambda] =>
345-
i"its subpart $tp is not a supported kind (either `*` or `* -> *`)"
346-
case OrType(tp1, tp2) =>
347-
Seq(tp1, tp2).map(whyNotAcceptableType(_, msrc)).find(_.nonEmpty).getOrElse("")
348-
case GenericTupleType(args) if args.size <= Definitions.MaxTupleArity =>
349-
val tup = MirrorSource.tuple(args)
350-
if tup.equiv(msrc) then ""
351-
else i"a subpart reduces to the unrelated tuple ${tup.asClass}, expected ${msrc.asClass}"
352-
case tp: TypeProxy => whyNotAcceptableType(tp.underlying, msrc)
353-
case _ =>
354-
mirrorSource(tp) match
355-
case Some(msrc2) =>
356-
if msrc2.equiv(msrc) then ""
357-
else i"a subpart reduces to the more precise ${msrc2.asClass}, expected ${msrc.asClass}"
358-
case _ => "???" // caught early by initial `mirrorSource` that made `msrc`
343+
def whyNotAcceptableType(tp: Type, msrc: MirrorSource): String =
344+
def compareMirrorSrc(msrc1: MirrorSource): String =
345+
if msrc1.equiv(msrc) then ""
346+
else i"a subpart reduces to the unrelated ${msrc1.asClass}, expected ${msrc.asClass}"
347+
tp match
348+
case tp: HKTypeLambda if tp.resultType.isInstanceOf[HKTypeLambda] =>
349+
i"its subpart $tp is not a supported kind (either `*` or `* -> *`)"
350+
case OrType(tp1, tp2) =>
351+
Seq(tp1, tp2).map(whyNotAcceptableType(_, msrc)).find(_.nonEmpty).getOrElse("")
352+
case GenericTupleType(args) =>
353+
val maxArity = Definitions.MaxTupleArity
354+
val tup = MirrorSource.tuple(args)
355+
if tup.arity <= maxArity then compareMirrorSrc(tup)
356+
else i"a subpart `$tp` reduces to a tuple with arity ${tup.arity}, expected arity <= $maxArity"
357+
case tp: TypeProxy => whyNotAcceptableType(tp.underlying, msrc)
358+
case _ =>
359+
mirrorSource(tp) match
360+
case Some(msrc2) => compareMirrorSrc(msrc2)
361+
case _ => i"a subpart `$tp` does not reduce to a class or generic tuple type"
359362

360363
/** widen TermRef to see if they are an alias to an enum singleton */
361364
def isEnumSingletonRef(tp: Type)(using Context): Boolean = tp match
@@ -417,9 +420,9 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
417420
makeProductMirror(msrc)
418421
else
419422
withErrors(i"$cls is not a generic product because ${msrc.asClass.whyNotGenericProduct}")
420-
else withErrors(i"type `$mirroredType` is not a generic product because $acceptableMsg")
423+
else withErrors(i"type $mirroredType is not a generic product because $acceptableMsg")
421424
case None =>
422-
withErrors(i"type `$mirroredType` does not reduce to a class or generic tuple type")
425+
withErrors(i"type $mirroredType does not reduce to a class or generic tuple type")
423426
end productMirror
424427

425428
private def sumMirror(mirroredType: Type, formal: Type, span: Span)(using Context): TreeWithErrors =
@@ -436,7 +439,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
436439
Seq(tp1, tp2).map(whyNotAcceptableType).find(_.nonEmpty).getOrElse("")
437440
case _ =>
438441
if tp.classSymbol eq cls then ""
439-
else i"a subpart reduces to the more precise ${tp.classSymbol}, expected $cls"
442+
else i"a subpart reduces to the unrelated ${tp.classSymbol}, expected $cls"
440443

441444

442445
val acceptableMsg = whyNotAcceptableType(mirroredType)

tests/neg/i14127.check

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- Error: tests/neg/i14127.scala:6:55 ----------------------------------------------------------------------------------
2+
6 | *: Int *: Int *: Int *: Int *: Int *: EmptyTuple)]] // error
3+
| ^
4+
|No given instance of type deriving.Mirror.Of[(Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
5+
| Int
6+
|, Int, Int)] was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type deriving.Mirror.Of[(Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
7+
| Int
8+
|, Int, Int)]:
9+
| * type (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) is not a generic product because a subpart `(Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)` reduces to a tuple with arity 23, expected arity <= 22
10+
| * class *: is not a generic sum because it does not have subclasses

tests/neg/i14823.check

Lines changed: 2 additions & 2 deletions
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 a subpart reduces to the unrelated class SubA, expected class Cov
6+
| * type SubA[Int] | SubB[Int] is not a generic sum because a subpart reduces to the unrelated class SubA, expected class Cov

0 commit comments

Comments
 (0)