Skip to content

Commit d072148

Browse files
committed
Turn mismatch given errors into given not found errors for $conforms[Nothing] and <:<.refl[Nothing]
Fixes #8053 When a given candidate turns out to not be applicable we used to report that there is a mismatch between the candidate type and the expected type. The goal is to report an error as precise as possible to the user. However, in some cases showing the inferred candidate brings no value to the user, especially when the candidate is uninhabited. I’ve changed the failure to be a `NoMatchingImplicitsFailure` instead of a mismatch when `$conforms[Nothing]` or `<:<.refl` are inferred because these values are uninhabited and might be confusing for end users.
1 parent 16b74d8 commit d072148

8 files changed

+52
-19
lines changed

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,11 +1407,15 @@ trait Implicits { self: Typer =>
14071407
}
14081408
if (ctx.reporter.hasErrors) {
14091409
ctx.reporter.removeBufferedMessages
1410-
SearchFailure {
1411-
adapted.tpe match {
1412-
case _: SearchFailureType => adapted
1413-
case _ => adapted.withType(new MismatchedImplicit(ref, pt, argument))
1414-
}
1410+
adapted.tpe match {
1411+
case _: SearchFailureType => SearchFailure(adapted)
1412+
case _ =>
1413+
// Special case for `$conforms[Nothing]` and `<:<.refl[Nothing]`. Showing them
1414+
// up to the users brings no value, so we instead report a `NoMatchingImplicitsFailure`
1415+
if (adapted.show == "$conforms[Nothing]" || adapted.show == "<:<.refl[Nothing]")
1416+
NoMatchingImplicitsFailure
1417+
else
1418+
SearchFailure(adapted.withType(new MismatchedImplicit(ref, pt, argument)))
14151419
}
14161420
}
14171421
else {

tests/neg/implicitSearch.check

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-- Error: tests/neg/implicitSearch.scala:13:12 -------------------------------------------------------------------------
2+
13 | sort(xs) // error (with a partially constructed implicit argument shown)
3+
| ^
4+
| no implicit argument of type Test.Ord[List[List[T]]] was found for parameter o of method sort in object Test.
5+
| I found:
6+
|
7+
| Test.listOrd[T](Test.listOrd[T](/* missing */implicitly[Test.Ord[T]]))
8+
|
9+
| But no implicit values were found that match type Test.Ord[T].
10+
-- Error: tests/neg/implicitSearch.scala:15:38 -------------------------------------------------------------------------
11+
15 | listOrd(listOrd(implicitly[Ord[T]] /*not found*/)) // error
12+
| ^
13+
| no implicit argument of type Test.Ord[T] was found for parameter ev of method implicitly in object DottyPredef

tests/neg/implicitSearch.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
object Test {
22

3-
type T = String
4-
53
class Ord[T]
64
implicit def listOrd[T](implicit o: Ord[T]): Ord[List[T]] = ???
75
implicit def intOrd: Ord[Int] = ???

tests/neg/missing-implicit3.check

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-- Error: tests/neg/missing-implicit3.scala:3:37 -----------------------------------------------------------------------
2+
3 |val sortedFoos = List(new Foo).sorted // error
3+
| ^
4+
| No implicit Ordering defined for B
5+
|
6+
| where: B is a type variable with constraint >: Foo
7+
| ..
8+
| I found:
9+
|
10+
| scala.math.Ordering.ordered[A](/* missing */implicitly[scala.math.Ordering.AsComparable[B]])
11+
|
12+
| But no implicit values were found that match type scala.math.Ordering.AsComparable[B].
13+
|
14+
| One of the following imports might make progress towards fixing the problem:
15+
|
16+
| import math.Ordering.comparatorToOrdering
17+
| import math.Ordering.ordered
18+
|

tests/neg/missing-implicit3.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Foo
2+
3+
val sortedFoos = List(new Foo).sorted // error

tests/neg/subtyping.check

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,8 @@
11
-- Error: tests/neg/subtyping.scala:8:27 -------------------------------------------------------------------------------
22
8 | implicitly[B#X <:< A#X] // error: no implicit argument
33
| ^
4-
| Cannot prove that B#X <:< A#X..
5-
| I found:
6-
|
7-
| <:<.refl[Nothing]
8-
|
9-
| But method refl in object <:< does not match type B#X <:< A#X.
4+
| Cannot prove that B#X <:< A#X.
105
-- Error: tests/neg/subtyping.scala:12:27 ------------------------------------------------------------------------------
116
12 | implicitly[a.T <:< a.U] // error: no implicit argument
127
| ^
13-
| Cannot prove that a.T <:< a.U..
14-
| I found:
15-
|
16-
| <:<.refl[Nothing]
17-
|
18-
| But method refl in object <:< does not match type a.T <:< a.U.
8+
| Cannot prove that a.T <:< a.U.

tests/neg/summon-function.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- Error: tests/neg/summon-function.scala:2:23 -------------------------------------------------------------------------
2+
2 | summon[Int => String] // error
3+
| ^
4+
| No implicit view available from Int => String.

tests/neg/summon-function.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test {
2+
summon[Int => String] // error
3+
}

0 commit comments

Comments
 (0)