From 27bd546a62732fff19a71b72aaaab43c07afc51b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 19 Mar 2021 19:04:48 +0100 Subject: [PATCH] Find implicitNotFoundMessage on types Fixes #11797 --- .../tools/dotc/typer/ErrorReporting.scala | 35 +++++++++++++------ tests/neg/i11797.check | 4 +++ tests/neg/i11797.scala | 6 ++++ 3 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 tests/neg/i11797.check create mode 100644 tests/neg/i11797.scala diff --git a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala index a87a3dfe50a6..413ae14762b8 100644 --- a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala +++ b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala @@ -375,17 +375,30 @@ class ImplicitSearchError( * def foo(implicit foo: Foo): Any = ??? */ private def userDefinedImplicitNotFoundTypeMessage: Option[String] = - pt.baseClasses.iterator - // Don't inherit "No implicit view available..." message if subtypes of Function1 are not treated as implicit conversions anymore - .filter(sym => Feature.migrateTo3 || sym != defn.Function1) - .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) - } + def recur(tp: Type): Option[String] = tp match + case tp: TypeRef => + val sym = tp.symbol + userDefinedImplicitNotFoundTypeMessage(sym).orElse(recur(tp.info)) + case tp: ClassInfo => + tp.baseClasses.iterator + .map(userDefinedImplicitNotFoundTypeMessage) + .find(_.isDefined).flatten + case tp: TypeProxy => + recur(tp.underlying) + case tp: AndType => + recur(tp.tp1).orElse(recur(tp.tp2)) + case _ => + None + recur(pt) + + private def userDefinedImplicitNotFoundTypeMessage(sym: Symbol): Option[String] = + for + rawMsg <- userDefinedMsg(sym, defn.ImplicitNotFoundAnnot) + if Feature.migrateTo3 || sym != defn.Function1 + // Don't inherit "No implicit view available..." message if subtypes of Function1 are not treated as implicit conversions anymore + yield + val substituteType = (_: Type).asSeenFrom(pt, sym) + formatAnnotationMessage(rawMsg, sym, substituteType) private def hiddenImplicitsAddendum: String = def hiddenImplicitNote(s: SearchSuccess) = diff --git a/tests/neg/i11797.check b/tests/neg/i11797.check new file mode 100644 index 000000000000..80090b6b2faf --- /dev/null +++ b/tests/neg/i11797.check @@ -0,0 +1,4 @@ +-- Error: tests/neg/i11797.scala:6:17 ---------------------------------------------------------------------------------- +6 | summon[Foo.Bar] // error + | ^ + | Oops diff --git a/tests/neg/i11797.scala b/tests/neg/i11797.scala new file mode 100644 index 000000000000..4a855beab4df --- /dev/null +++ b/tests/neg/i11797.scala @@ -0,0 +1,6 @@ +object Foo: + @annotation.implicitNotFound("Oops") + type Bar + +@main def run(): Unit = + summon[Foo.Bar] // error \ No newline at end of file