diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 5921e5b055b7..bfffec8b7218 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -390,6 +390,7 @@ class Definitions { @tu lazy val Predef_undefined: Symbol = ScalaPredefModule.requiredMethod(nme.???) def SubTypeClass(implicit ctx: Context): ClassSymbol = ctx.requiredClass("scala.<:<") + @tu lazy val SubType_refl: Symbol = SubTypeClass.companionModule.requiredMethod(nme.refl) def DummyImplicitClass(implicit ctx: Context): ClassSymbol = ctx.requiredClass("scala.DummyImplicit") diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index cfce4d72b391..bbd4e25bf201 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -549,6 +549,7 @@ object StdNames { val productIterator: N = "productIterator" val productPrefix: N = "productPrefix" val raw_ : N = "raw" + val refl: N = "refl" val reflect: N = "reflect" val reflectiveSelectable: N = "reflectiveSelectable" val reify : N = "reify" diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 69bdf0a89877..e71731885113 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -1407,11 +1407,15 @@ trait Implicits { self: Typer => } if (ctx.reporter.hasErrors) { ctx.reporter.removeBufferedMessages - SearchFailure { - adapted.tpe match { - case _: SearchFailureType => adapted - case _ => adapted.withType(new MismatchedImplicit(ref, pt, argument)) - } + adapted.tpe match { + case _: SearchFailureType => SearchFailure(adapted) + case _ => + // 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 + SearchFailure(adapted.withType(new MismatchedImplicit(ref, pt, argument))) } } else { diff --git a/tests/neg/implicitSearch.check b/tests/neg/implicitSearch.check new file mode 100644 index 000000000000..7f73ba306cb6 --- /dev/null +++ b/tests/neg/implicitSearch.check @@ -0,0 +1,13 @@ +-- Error: tests/neg/implicitSearch.scala:13:12 ------------------------------------------------------------------------- +13 | sort(xs) // error (with a partially constructed implicit argument shown) + | ^ + | no implicit argument of type Test.Ord[List[List[T]]] was found for parameter o of method sort in object Test. + | I found: + | + | Test.listOrd[T](Test.listOrd[T](/* missing */implicitly[Test.Ord[T]])) + | + | But no implicit values were found that match type Test.Ord[T]. +-- Error: tests/neg/implicitSearch.scala:15:38 ------------------------------------------------------------------------- +15 | listOrd(listOrd(implicitly[Ord[T]] /*not found*/)) // error + | ^ + | no implicit argument of type Test.Ord[T] was found for parameter ev of method implicitly in object DottyPredef diff --git a/tests/neg/implicitSearch.scala b/tests/neg/implicitSearch.scala index a5be79474ffd..614e3f12f6f3 100644 --- a/tests/neg/implicitSearch.scala +++ b/tests/neg/implicitSearch.scala @@ -1,7 +1,5 @@ object Test { - type T = String - class Ord[T] implicit def listOrd[T](implicit o: Ord[T]): Ord[List[T]] = ??? implicit def intOrd: Ord[Int] = ??? diff --git a/tests/neg/missing-implicit3.check b/tests/neg/missing-implicit3.check new file mode 100644 index 000000000000..a33052ef6c9d --- /dev/null +++ b/tests/neg/missing-implicit3.check @@ -0,0 +1,14 @@ +-- Error: tests/neg/missing-implicit3.scala:13:36 ---------------------------------------------------------------------- +13 |val sortedFoos = sort(List(new Foo)) // error + | ^ + |no implicit argument of type ord.Ord[ord.Foo] was found for an implicit parameter of method sort in package ord. + |I found: + | + | ord.Ord.ordered[A](/* missing */implicitly[ord.Foo => Comparable[? >: ord.Foo]]) + | + |But no implicit values were found that match type ord.Foo => Comparable[? >: ord.Foo]. + | + |The following import might make progress towards fixing the problem: + | + | import ord.Ord.ordered + | diff --git a/tests/neg/missing-implicit3.scala b/tests/neg/missing-implicit3.scala new file mode 100644 index 000000000000..7affe234bbab --- /dev/null +++ b/tests/neg/missing-implicit3.scala @@ -0,0 +1,13 @@ +package ord + +trait Ord[A] + +object Ord { + given ordered[A](using A => java.lang.Comparable[? >: A]) as Ord[A] = ??? +} + +def sort[A: Ord](as: List[A]): List[A] = ??? + +class Foo + +val sortedFoos = sort(List(new Foo)) // error diff --git a/tests/neg/subtyping.check b/tests/neg/subtyping.check index 39a02066b3d0..832ff6296c52 100644 --- a/tests/neg/subtyping.check +++ b/tests/neg/subtyping.check @@ -1,18 +1,8 @@ -- Error: tests/neg/subtyping.scala:8:27 ------------------------------------------------------------------------------- 8 | implicitly[B#X <:< A#X] // error: no implicit argument | ^ - | Cannot prove that B#X <:< A#X.. - | I found: - | - | <:<.refl[Nothing] - | - | But method refl in object <:< does not match type B#X <:< A#X. + | Cannot prove that B#X <:< A#X. -- Error: tests/neg/subtyping.scala:12:27 ------------------------------------------------------------------------------ 12 | implicitly[a.T <:< a.U] // error: no implicit argument | ^ - | Cannot prove that a.T <:< a.U.. - | I found: - | - | <:<.refl[Nothing] - | - | But method refl in object <:< does not match type a.T <:< a.U. + | Cannot prove that a.T <:< a.U. diff --git a/tests/neg/summon-function.check b/tests/neg/summon-function.check new file mode 100644 index 000000000000..525b68e88c66 --- /dev/null +++ b/tests/neg/summon-function.check @@ -0,0 +1,4 @@ +-- Error: tests/neg/summon-function.scala:2:23 ------------------------------------------------------------------------- +2 | summon[Int => String] // error + | ^ + | No implicit view available from Int => String. diff --git a/tests/neg/summon-function.scala b/tests/neg/summon-function.scala new file mode 100644 index 000000000000..37981784c96a --- /dev/null +++ b/tests/neg/summon-function.scala @@ -0,0 +1,3 @@ +object Test { + summon[Int => String] // error +}