Skip to content

Commit

Permalink
Propagate implicit search errors from implicit macros
Browse files Browse the repository at this point in the history
Fixes partially scala#16835
  • Loading branch information
nicolasstucki committed Feb 6, 2023
1 parent a356581 commit ff988d6
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 3 deletions.
15 changes: 12 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,12 @@ object Implicits:

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

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

import Implicits._
Expand Down Expand Up @@ -1157,19 +1163,22 @@ trait Implicits:
if ctx.reporter.hasErrors
|| !cand.ref.symbol.isAccessibleFrom(cand.ref.prefix)
then
ctx.reporter.removeBufferedMessages
adapted.tpe match {
val res = adapted.tpe match {
case _: SearchFailureType => SearchFailure(adapted)
case error: PreviousErrorType if !adapted.symbol.isAccessibleFrom(cand.ref.prefix) =>
SearchFailure(adapted.withType(new NestedFailure(error.msg, pt)))
case _ =>
case tpe =>
// Special case for `$conforms` and `<:<.refl`. Showing them to the users brings
// no value, so we instead report a `NoMatchingImplicitsFailure`
if (adapted.symbol == defn.Predef_conforms || adapted.symbol == defn.SubType_refl)
NoMatchingImplicitsFailure
else if tpe <:< pt then
SearchFailure(adapted.withType(new ErrorReportedImplicit(ctx.reporter.allErrors.reverse, pt, argument)))
else
SearchFailure(adapted.withType(new MismatchedImplicit(ref, pt, argument)))
}
ctx.reporter.removeBufferedMessages
res
else
SearchSuccess(adapted, ref, cand.level, cand.isExtension)(ctx.typerState, ctx.gadt)
}
Expand Down
6 changes: 6 additions & 0 deletions tests/neg-macros/i16835.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

-- Error: tests/neg-macros/i16835/Test_2.scala:1:17 --------------------------------------------------------------------
1 |def test: Unit = foo // error
| ^^^
| my error
| my second error
21 changes: 21 additions & 0 deletions tests/neg-macros/i16835/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import scala.quoted.*

class Bar

inline def foo: Unit = ${ fooExpr }

def fooExpr(using Quotes): Expr[Unit] =
import quotes.reflect.*
Implicits.search(TypeRepr.of[Bar]) match
case res: ImplicitSearchSuccess => '{}
case failure: ImplicitSearchFailure =>
report.errorAndAbort(failure.explanation)


inline given bar: Bar = ${ barExpr }

def barExpr(using Quotes): Expr[Bar] =
import quotes.reflect.*
report.error(s"my error")
report.error(s"my second error")
'{ new Bar }
1 change: 1 addition & 0 deletions tests/neg-macros/i16835/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
def test: Unit = foo // error

0 comments on commit ff988d6

Please sign in to comment.