Skip to content

Commit b1afa22

Browse files
authored
Merge pull request #15747 from dotty-staging/fix-check-conversion-specific
Better error message for "implicit search must be more specific"
2 parents 03da9dd + 37886e9 commit b1afa22

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)