Skip to content

Commit f93f00f

Browse files
committed
Bring back ambiguity filter when report implicit not found
This reverts one part of scala#20261. When we fail with both an ambiguity on one implicit argument and another error on another we prefer the other error. I added a comment why this is needed. Fixes scala#20354
1 parent 1276034 commit f93f00f

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4113,7 +4113,14 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
41134113
* `SearchFailureType`.
41144114
*/
41154115
def issueErrors(fun: Tree, args: List[Tree]): Tree =
4116-
def firstFailure = args.tpes.find(_.isInstanceOf[SearchFailureType]).getOrElse(NoType)
4116+
// Prefer other errors over ambiguities. If nested in outer searches a missing
4117+
// implicit can be healed by simply dropping this alternative and tryng something
4118+
// else. But an ambiguity is sticky and propagates outwards. If we have both
4119+
// a missing implicit on one argument and an ambiguity on another the whole
4120+
// branch should be classified as a missing implicit.
4121+
val firstNonAmbiguous = args.tpes.find(tp => tp.isError && !tp.isInstanceOf[AmbiguousImplicits])
4122+
def firstError = args.tpes.find(_.isInstanceOf[SearchFailureType]).getOrElse(NoType)
4123+
def firstFailure = firstNonAmbiguous.getOrElse(firstError)
41174124
val errorType =
41184125
firstFailure match
41194126
case tp: AmbiguousImplicits =>

tests/run/i20354.scala

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
trait CmdLineParser { outer =>
2+
3+
trait Opt[+T] {
4+
val default: T
5+
val names: Set[String]
6+
val help: String
7+
}
8+
9+
trait IntOpt extends Opt[Int] {
10+
val parser = outer // <=== comment out this line, we get "true true"
11+
}
12+
}
13+
14+
object FirstParser extends CmdLineParser {
15+
object OptMinSuccess extends IntOpt {
16+
val default = 100
17+
val names = Set("bla")
18+
val help = "bla"
19+
}
20+
21+
val opts = List(OptMinSuccess)
22+
}
23+
24+
object SecondParser extends CmdLineParser {
25+
object OptMinSuccess extends IntOpt {
26+
val default = 50
27+
val names = Set("bla")
28+
val help = "help"
29+
}
30+
}
31+
@main def Test =
32+
33+
val a = SecondParser.OptMinSuccess.isInstanceOf[FirstParser.IntOpt]
34+
35+
println(a)
36+
37+
(SecondParser.OptMinSuccess: SecondParser.IntOpt) match {
38+
case _: FirstParser.IntOpt => println("true")
39+
case _ => println("false")
40+
}

0 commit comments

Comments
 (0)