Skip to content

Commit fd6b48f

Browse files
authored
Merge pull request #15164 from szymon-rd/fix/15128
Add error reporting for mirror synthesis
2 parents 9dbe2d3 + 3186b03 commit fd6b48f

37 files changed

+255
-116
lines changed

compiler/src/dotty/tools/dotc/transform/SymUtils.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ object SymUtils:
146146
if (!self.is(Sealed))
147147
s"it is not a sealed ${self.kindString}"
148148
else if (!self.isOneOf(AbstractOrTrait))
149-
s"it is not an abstract class"
149+
"it is not an abstract class"
150150
else {
151151
val children = self.children
152152
val companionMirror = self.useCompanionAsSumMirror

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -257,24 +257,26 @@ class ImplicitSearchError(
257257
++ ErrorReporting.matchReductionAddendum(pt)
258258
}
259259

260-
private def formatMsg(shortForm: String)(headline: String = shortForm) = arg match {
260+
private def formatMsg(shortForm: String)(headline: String = shortForm) = arg match
261261
case arg: Trees.SearchFailureIdent[?] =>
262-
shortForm
262+
arg.tpe match
263+
case _: NoMatchingImplicits => headline
264+
case tpe: SearchFailureType =>
265+
i"$headline. ${tpe.explanation}"
266+
case _ => headline
263267
case _ =>
264-
arg.tpe match {
268+
arg.tpe match
265269
case tpe: SearchFailureType =>
266270
val original = arg match
267271
case Inlined(call, _, _) => call
268272
case _ => arg
269-
270273
i"""$headline.
271274
|I found:
272275
|
273276
| ${original.show.replace("\n", "\n ")}
274277
|
275278
|But ${tpe.explanation}."""
276-
}
277-
}
279+
case _ => headline
278280

279281
/** Format `raw` implicitNotFound or implicitAmbiguous argument, replacing
280282
* all occurrences of `${X}` where `X` is in `paramNames` with the
@@ -302,12 +304,10 @@ class ImplicitSearchError(
302304
private def location(preposition: String) = if (where.isEmpty) "" else s" $preposition $where"
303305

304306
private def defaultAmbiguousImplicitMsg(ambi: AmbiguousImplicits) =
305-
formatMsg(s"ambiguous given instances: ${ambi.explanation}${location("of")}")(
306-
s"ambiguous given instances of type ${pt.show} found${location("for")}"
307-
)
307+
s"Ambiguous given instances: ${ambi.explanation}${location("of")}"
308308

309309
private def defaultImplicitNotFoundMessage =
310-
ex"no given instance of type $pt was found${location("for")}"
310+
ex"No given instance of type $pt was found${location("for")}"
311311

312312
/** Construct a custom error message given an ambiguous implicit
313313
* candidate `alt` and a user defined message `raw`.

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,18 @@ object Implicits:
549549
override def msg(using Context) = _msg
550550
def explanation(using Context) = msg.toString
551551

552+
/** A search failure type for failed synthesis of terms for special types */
553+
class SynthesisFailure(reasons: List[String], val expectedType: Type) extends SearchFailureType:
554+
def argument = EmptyTree
555+
556+
private def formatReasons =
557+
if reasons.length > 1 then
558+
reasons.mkString("\n\t* ", "\n\t* ", "")
559+
else
560+
reasons.mkString
561+
562+
def explanation(using Context) = em"Failed to synthesize an instance of type ${clarify(expectedType)}: ${formatReasons}"
563+
552564
end Implicits
553565

554566
import Implicits._
@@ -854,7 +866,12 @@ trait Implicits:
854866
if fail.isAmbiguous then failed
855867
else
856868
if synthesizer == null then synthesizer = Synthesizer(this)
857-
synthesizer.uncheckedNN.tryAll(formal, span).orElse(failed)
869+
val (tree, errors) = synthesizer.uncheckedNN.tryAll(formal, span)
870+
if errors.nonEmpty then
871+
SearchFailure(new SynthesisFailure(errors, formal), span).tree
872+
else
873+
tree.orElse(failed)
874+
858875

859876
/** Search an implicit argument and report error if not found */
860877
def implicitArgTree(formal: Type, span: Span)(using Context): Tree = {

0 commit comments

Comments
 (0)