diff --git a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala index d25e095b3325..802bb5a6b3ea 100644 --- a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala +++ b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala @@ -250,7 +250,7 @@ class ImplicitSearchError( */ private def userDefinedMsg(sym: Symbol, cls: Symbol) = for { ann <- sym.getAnnotation(cls) - Trees.Literal(Constant(msg: String)) <- ann.argument(0) + msg <- ann.argumentConstantString(0) } yield msg private def location(preposition: String) = if (where.isEmpty) "" else s" $preposition $where" @@ -313,7 +313,7 @@ class ImplicitSearchError( * * def foo(implicit @annotation.implicitNotFound("Foo is missing") foo: Foo): Any = ??? */ - private def userDefinedImplicitNotFoundParamMessage = paramSymWithMethodCallTree.flatMap { (sym, applTree) => + private def userDefinedImplicitNotFoundParamMessage: Option[String] = paramSymWithMethodCallTree.flatMap { (sym, applTree) => userDefinedMsg(sym, defn.ImplicitNotFoundAnnot).map { rawMsg => val (fn, targs, _) = tpd.decomposeCall(applTree) val methodOwner = fn.symbol.owner @@ -332,8 +332,12 @@ class ImplicitSearchError( * * def foo(implicit foo: Foo): Any = ??? */ - private def userDefinedImplicitNotFoundTypeMessage = - val classSym = pt.classSymbol + private def userDefinedImplicitNotFoundTypeMessage: Option[String] = + pt.baseClasses.iterator + .map(userDefinedImplicitNotFoundTypeMessage(_)) + .find(_.isDefined).flatten + + private def userDefinedImplicitNotFoundTypeMessage(classSym: ClassSymbol): Option[String] = userDefinedMsg(classSym, defn.ImplicitNotFoundAnnot).map { rawMsg => val substituteType = (_: Type).asSeenFrom(pt, classSym) formatAnnotationMessage(rawMsg, classSym, substituteType) diff --git a/tests/neg/i10098.check b/tests/neg/i10098.check new file mode 100644 index 000000000000..06d0c62b69c0 --- /dev/null +++ b/tests/neg/i10098.check @@ -0,0 +1,16 @@ +-- Error: tests/neg/i10098.scala:20:32 --------------------------------------------------------------------------------- +20 | implicitly[Bar12[Int, String]] // error + | ^ + | There's no Foo2[String, Int] +-- Error: tests/neg/i10098.scala:21:32 --------------------------------------------------------------------------------- +21 | implicitly[Bar21[Int, String]] // error + | ^ + | There's no Foo1[String, Int] +-- Error: tests/neg/i10098.scala:22:32 --------------------------------------------------------------------------------- +22 | implicitly[Baz12[Int, String]] // error + | ^ + | There's no Baz12[Int, String] +-- Error: tests/neg/i10098.scala:23:32 --------------------------------------------------------------------------------- +23 | implicitly[Baz21[Int, String]] // error + | ^ + | There's no Baz21[Int, String] diff --git a/tests/neg/i10098.scala b/tests/neg/i10098.scala new file mode 100644 index 000000000000..aedf1422b378 --- /dev/null +++ b/tests/neg/i10098.scala @@ -0,0 +1,24 @@ +import annotation.implicitNotFound + +@implicitNotFound("There's no Foo1[${A}, ${B}]") +trait Foo1[A, B] + +@implicitNotFound("There's no Foo2[${A}, ${B}]") +trait Foo2[A, B] + +trait Bar12[C, D] extends Foo1[D, C] with Foo2[D, C] + +trait Bar21[C, D] extends Foo2[D, C] with Foo1[D, C] + +@implicitNotFound("There's no Baz12[${C}, ${D}]") +trait Baz12[C, D] extends Foo1[D, C] with Foo2[D, C] + +@implicitNotFound("There's no Baz21[${C}, ${D}]") +trait Baz21[C, D] extends Foo2[D, C] with Foo1[D, C] + +object Test { + implicitly[Bar12[Int, String]] // error + implicitly[Bar21[Int, String]] // error + implicitly[Baz12[Int, String]] // error + implicitly[Baz21[Int, String]] // error +} diff --git a/tests/neg/i4986c.scala b/tests/neg/i4986c.scala index 2176c6019c0a..f41948c19169 100644 --- a/tests/neg/i4986c.scala +++ b/tests/neg/i4986c.scala @@ -16,7 +16,7 @@ class Outer[A] { trait X$Y -@implicitNotFound("There's no U[${X}, ${Y}, ${Z}]") +@implicitNotFound(msg = "There's no U[${X}, ${Y}, ${Z}]") trait U[X, Y[_], Z[_, ZZ]] { class I[R] { def m[S](implicit @implicitNotFound("${X}; ${Y}; ${ Z }; ${R}; ${S}; ${XX}") i: Int) = ??? @@ -24,7 +24,7 @@ trait U[X, Y[_], Z[_, ZZ]] { } class Test[A] { - def f(implicit @implicitNotFound("Missing X$Y for Test[${A}]") xy: X$Y) = ??? + def f(implicit @implicitNotFound(msg = "Missing X$Y for Test[${A}]") xy: X$Y) = ??? def g[B: Outer] = ??? def h[B](implicit outer: Outer[B]) = ??? def i[B](implicit @implicitNotFound("Missing implicit outer param of type Outer[${B}] for Test[${A}]") outer: Outer[B]) = ???