Skip to content

Commit c112791

Browse files
committed
Better error message for "implicit search must be more specific" situation
We now mention this as an addendum rather than as the error outright. The previous case gave very obscure error messages since we did not know why an implicit conversion should be tried in the first place.
1 parent 09ca850 commit c112791

File tree

4 files changed

+31
-8
lines changed

4 files changed

+31
-8
lines changed

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -721,12 +721,6 @@ object Checking {
721721
else "Cannot override non-inline parameter with an inline parameter",
722722
p1.srcPos)
723723

724-
def checkConversionsSpecific(to: Type, pos: SrcPos)(using Context): Unit =
725-
if to.isRef(defn.AnyValClass, skipRefined = false)
726-
|| to.isRef(defn.ObjectClass, skipRefined = false)
727-
then
728-
report.error(em"the result of an implicit conversion must be more specific than $to", pos)
729-
730724
def checkValue(tree: Tree)(using Context): Unit =
731725
val sym = tree.tpe.termSymbol
732726
if sym.isNoValue && !ctx.isJava then

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,14 @@ object Implicits:
503503
@sharable val ImplicitSearchTooLargeFailure: SearchFailure =
504504
SearchFailure(ImplicitSearchTooLarge, NoSpan)(using NoContext)
505505

506+
/** A failure value indicating that an implicit search for a conversion was not tried */
507+
class TooUnspecific(target: Type) extends NoMatchingImplicits(NoType, EmptyTree, OrderingConstraint.empty):
508+
override def whyNoConversion(using Context): String =
509+
i"""
510+
|Note that implicit conversions were not tried because the result of an implicit conversion
511+
|must be more specific than $target"""
512+
override def toString = s"TooUnspecific"
513+
506514
/** An ambiguous implicits failure */
507515
class AmbiguousImplicits(val alt1: SearchSuccess, val alt2: SearchSuccess, val expectedType: Type, val argument: Tree) extends SearchFailureType {
508516
def explanation(using Context): String =

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3980,8 +3980,11 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
39803980
case None => tree
39813981
else tree // other adaptations for selections are handled in typedSelect
39823982
case _ if ctx.mode.is(Mode.ImplicitsEnabled) && tree.tpe.isValueType =>
3983-
checkConversionsSpecific(pt, tree.srcPos)
3984-
inferView(tree, pt) match
3983+
if pt.isRef(defn.AnyValClass, skipRefined = false)
3984+
|| pt.isRef(defn.ObjectClass, skipRefined = false)
3985+
then
3986+
recover(TooUnspecific(pt))
3987+
else inferView(tree, pt) match
39853988
case SearchSuccess(found, _, _, isExtension) =>
39863989
if isExtension then found
39873990
else

tests/neg/i6336.check

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-- [E007] Type Mismatch Error: tests/neg/i6336.scala:2:18 --------------------------------------------------------------
2+
2 | val a: AnyVal = "foo" // error
3+
| ^^^^^
4+
| Found: ("foo" : String)
5+
| Required: AnyVal
6+
| Note that implicit conversions were not tried because the result of an implicit conversion
7+
| must be more specific than AnyVal
8+
|
9+
| longer explanation available when compiling with `-explain`
10+
-- [E007] Type Mismatch Error: tests/neg/i6336.scala:3:18 --------------------------------------------------------------
11+
3 | val b: AnyRef = 1 // error
12+
| ^
13+
| Found: (1 : Int)
14+
| Required: AnyRef
15+
| Note that implicit conversions were not tried because the result of an implicit conversion
16+
| must be more specific than AnyRef
17+
|
18+
| longer explanation available when compiling with `-explain`

0 commit comments

Comments
 (0)