Skip to content

Commit ff988d6

Browse files
committed
Propagate implicit search errors from implicit macros
Fixes partially #16835
1 parent a356581 commit ff988d6

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,12 @@ object Implicits:
567567

568568
def msg(using Context) = em"Failed to synthesize an instance of type ${clarify(expectedType)}:${formatReasons}"
569569

570+
class ErrorReportedImplicit(errors: List[Diagnostic.Error],
571+
val expectedType: Type,
572+
val argument: Tree) extends SearchFailureType {
573+
def msg(using Context): Message =
574+
em"${errors.map(_.msg).mkString("\n")}"
575+
}
570576
end Implicits
571577

572578
import Implicits._
@@ -1157,19 +1163,22 @@ trait Implicits:
11571163
if ctx.reporter.hasErrors
11581164
|| !cand.ref.symbol.isAccessibleFrom(cand.ref.prefix)
11591165
then
1160-
ctx.reporter.removeBufferedMessages
1161-
adapted.tpe match {
1166+
val res = adapted.tpe match {
11621167
case _: SearchFailureType => SearchFailure(adapted)
11631168
case error: PreviousErrorType if !adapted.symbol.isAccessibleFrom(cand.ref.prefix) =>
11641169
SearchFailure(adapted.withType(new NestedFailure(error.msg, pt)))
1165-
case _ =>
1170+
case tpe =>
11661171
// Special case for `$conforms` and `<:<.refl`. Showing them to the users brings
11671172
// no value, so we instead report a `NoMatchingImplicitsFailure`
11681173
if (adapted.symbol == defn.Predef_conforms || adapted.symbol == defn.SubType_refl)
11691174
NoMatchingImplicitsFailure
1175+
else if tpe <:< pt then
1176+
SearchFailure(adapted.withType(new ErrorReportedImplicit(ctx.reporter.allErrors.reverse, pt, argument)))
11701177
else
11711178
SearchFailure(adapted.withType(new MismatchedImplicit(ref, pt, argument)))
11721179
}
1180+
ctx.reporter.removeBufferedMessages
1181+
res
11731182
else
11741183
SearchSuccess(adapted, ref, cand.level, cand.isExtension)(ctx.typerState, ctx.gadt)
11751184
}

tests/neg-macros/i16835.check

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
-- Error: tests/neg-macros/i16835/Test_2.scala:1:17 --------------------------------------------------------------------
3+
1 |def test: Unit = foo // error
4+
| ^^^
5+
| my error
6+
| my second error

tests/neg-macros/i16835/Macro_1.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import scala.quoted.*
2+
3+
class Bar
4+
5+
inline def foo: Unit = ${ fooExpr }
6+
7+
def fooExpr(using Quotes): Expr[Unit] =
8+
import quotes.reflect.*
9+
Implicits.search(TypeRepr.of[Bar]) match
10+
case res: ImplicitSearchSuccess => '{}
11+
case failure: ImplicitSearchFailure =>
12+
report.errorAndAbort(failure.explanation)
13+
14+
15+
inline given bar: Bar = ${ barExpr }
16+
17+
def barExpr(using Quotes): Expr[Bar] =
18+
import quotes.reflect.*
19+
report.error(s"my error")
20+
report.error(s"my second error")
21+
'{ new Bar }

tests/neg-macros/i16835/Test_2.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
def test: Unit = foo // error

0 commit comments

Comments
 (0)