Skip to content

Commit 66187b1

Browse files
committed
fix error messages
1 parent 9cb0649 commit 66187b1

File tree

3 files changed

+36
-25
lines changed

3 files changed

+36
-25
lines changed

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

+32-21
Original file line numberDiff line numberDiff line change
@@ -278,12 +278,15 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
278278

279279
private def productMirror(mirroredType: Type, formal: Type, span: Span)(using Context): TreeWithErrors =
280280

281-
/** do all parts match the class symbol? */
282-
def acceptable(tp: Type, cls: Symbol): Boolean = tp match
283-
case tp: HKTypeLambda if tp.resultType.isInstanceOf[HKTypeLambda] => false
284-
case tp: TypeProxy => acceptable(tp.underlying, cls)
285-
case OrType(tp1, tp2) => acceptable(tp1, cls) && acceptable(tp2, cls)
286-
case _ => tp.classSymbol eq cls
281+
def whyNotAcceptableType(tp: Type, cls: Symbol): String = tp match
282+
case tp: HKTypeLambda if tp.resultType.isInstanceOf[HKTypeLambda] =>
283+
i"its subpart $tp is not a supported kind (either `*` or `* -> *`)"
284+
case tp: TypeProxy => whyNotAcceptableType(tp.underlying, cls)
285+
case OrType(tp1, tp2) =>
286+
Seq(tp1, tp2).map(whyNotAcceptableType(_, cls)).find(_.nonEmpty).getOrElse("")
287+
case _ =>
288+
if tp.classSymbol eq cls then ""
289+
else i"a subpart reduces to the more precise ${tp.classSymbol}, expected $cls"
287290

288291
def makeProductMirror(cls: Symbol): TreeWithErrors =
289292
val accessors = cls.caseAccessors.filterNot(_.isAllOf(PrivateLocal))
@@ -323,28 +326,33 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
323326
withNoErrors(modulePath.cast(mirrorType))
324327
else
325328
val cls = mirroredType.classSymbol
326-
val clsIsGenericProduct = cls.isGenericProduct
327-
if acceptable(mirroredType, cls) && clsIsGenericProduct then
328-
makeProductMirror(cls)
329-
else if !clsIsGenericProduct then
330-
(EmptyTree, List(i"$cls is not a generic product because ${cls.whyNotGenericProduct}"))
331-
else
332-
EmptyTreeNoError
329+
val acceptableMsg = whyNotAcceptableType(mirroredType, cls)
330+
if acceptableMsg.isEmpty then
331+
if cls.isGenericProduct then makeProductMirror(cls)
332+
else withErrors(i"$cls is not a generic product because ${cls.whyNotGenericProduct}")
333+
else withErrors(i"type $mirroredType is not a generic product because $acceptableMsg")
333334
end productMirror
334335

335336
private def sumMirror(mirroredType: Type, formal: Type, span: Span)(using Context): TreeWithErrors =
336337

337338
val cls = mirroredType.classSymbol
338339
val clsIsGenericSum = cls.isGenericSum
339340

340-
def acceptable(tp: Type): Boolean = tp match
341-
case tp: TermRef => false
342-
case tp: HKTypeLambda if tp.resultType.isInstanceOf[HKTypeLambda] => false
343-
case tp: TypeProxy => acceptable(tp.underlying)
344-
case OrType(tp1, tp2) => acceptable(tp1) && acceptable(tp2)
345-
case _ => tp.classSymbol eq cls
341+
def whyNotAcceptableType(tp: Type): String = tp match
342+
case tp: TermRef => i"its subpart $tp is a term reference"
343+
case tp: HKTypeLambda if tp.resultType.isInstanceOf[HKTypeLambda] =>
344+
i"its subpart $tp is not a supported kind (either `*` or `* -> *`)"
345+
case tp: TypeProxy => whyNotAcceptableType(tp.underlying)
346+
case OrType(tp1, tp2) =>
347+
Seq(tp1, tp2).map(whyNotAcceptableType).find(_.nonEmpty).getOrElse("")
348+
case _ =>
349+
if tp.classSymbol eq cls then ""
350+
else i"a subpart reduces to the more precise ${tp.classSymbol}, expected $cls"
351+
352+
353+
val acceptableMsg = whyNotAcceptableType(mirroredType)
346354

347-
if acceptable(mirroredType) && clsIsGenericSum then
355+
if acceptableMsg.isEmpty && clsIsGenericSum then
348356
val elemLabels = cls.children.map(c => ConstantType(Constant(c.name.toString)))
349357

350358
def solve(sym: Symbol): Type = sym match
@@ -398,8 +406,10 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
398406
if cls.useCompanionAsSumMirror then companionPath(mirroredType, span)
399407
else anonymousMirror(monoType, ExtendsSumMirror, span)
400408
withNoErrors(mirrorRef.cast(mirrorType))
409+
else if acceptableMsg.nonEmpty then
410+
withErrors(i"type $mirroredType is not a generic sum because $acceptableMsg")
401411
else if !clsIsGenericSum then
402-
(EmptyTree, List(i"$cls is not a generic sum because ${cls.whyNotGenericSum}"))
412+
withErrors(i"$cls is not a generic sum because ${cls.whyNotGenericSum}")
403413
else
404414
EmptyTreeNoError
405415
end sumMirror
@@ -584,6 +594,7 @@ object Synthesizer:
584594
/** Tuple used to store the synthesis result with a list of errors. */
585595
type TreeWithErrors = (Tree, List[String])
586596
private def withNoErrors(tree: Tree): TreeWithErrors = (tree, List.empty)
597+
private def withErrors(errors: String*): TreeWithErrors = (EmptyTree, errors.toList)
587598

588599
private val EmptyTreeNoError: TreeWithErrors = withNoErrors(EmptyTree)
589600

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)}: class Tuple2 is not a generic product
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
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-
| * class Cov is not a generic product
6-
| * class Cov is not a generic sum because it is not a sealed class
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

0 commit comments

Comments
 (0)