Skip to content

Commit caff1fe

Browse files
committed
Moved Ambiguous Overload error in Typer to case class
1 parent a391a58 commit caff1fe

File tree

4 files changed

+52
-6
lines changed

4 files changed

+52
-6
lines changed

compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public enum ErrorMessageID {
5757
CyclicReferenceInvolvingImplicitID,
5858
SuperQualMustBeParentID,
5959
AmbiguousImportID,
60+
AmbiguousOverloadID,
6061
;
6162

6263
public int errorNumber() {

compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import dotc.parsing.Tokens
1818
import printing.Highlighting._
1919
import printing.Formatting
2020
import ErrorMessageID._
21+
import Denotations.SingleDenotation
2122
import dotty.tools.dotc.core.SymDenotations.SymDenotation
2223

2324
object messages {
@@ -1253,4 +1254,25 @@ object messages {
12531254
|"""
12541255
}
12551256

1257+
case class AmbiguousOverload(tree: tpd.Tree, alts: List[SingleDenotation], pt: Type)(
1258+
err: typer.ErrorReporting.Errors)(
1259+
implicit ctx: Context)
1260+
extends Message(AmbiguousOverloadID) {
1261+
1262+
private def all = if (alts.length == 2) "both" else "all"
1263+
1264+
override def msg: String =
1265+
s"""|Ambiguous overload. The ${err.overloadedAltsStr(alts)}
1266+
|$all match ${err.expectedTypeStr(pt)}""".stripMargin
1267+
1268+
override def kind: String = "Reference"
1269+
1270+
override def explanation: String =
1271+
s"""|There are ${alts.length} methods that could be referenced as the compiler knows too little about the expected type.
1272+
|You may specify the expected type e.g. by
1273+
|- assigning it to a value with a specified type, or
1274+
|- adding a type ascription as in (MyClass.myMethod: String => Int)
1275+
|""".stripMargin
1276+
}
1277+
12561278
}

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,15 +1791,14 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
17911791
typr.println(i"adapt overloaded $ref with alternatives ${altDenots map (_.info)}%, %")
17921792
val alts = altDenots map (alt =>
17931793
TermRef.withSigAndDenot(ref.prefix, ref.name, alt.info.signature, alt))
1794-
def expectedStr = err.expectedTypeStr(pt)
17951794
resolveOverloaded(alts, pt) match {
17961795
case alt :: Nil =>
17971796
adapt(tree.withType(alt), pt, original)
17981797
case Nil =>
17991798
def noMatches =
18001799
errorTree(tree,
18011800
em"""none of the ${err.overloadedAltsStr(altDenots)}
1802-
|match $expectedStr""")
1801+
|match ${err.expectedTypeStr(pt)}""")
18031802
def hasEmptyParams(denot: SingleDenotation) = denot.info.paramInfoss == ListOfNil
18041803
pt match {
18051804
case pt: FunProto =>
@@ -1812,10 +1811,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
18121811
}
18131812
case alts =>
18141813
val remainingDenots = alts map (_.denot.asInstanceOf[SingleDenotation])
1815-
def all = if (remainingDenots.length == 2) "both" else "all"
1816-
errorTree(tree,
1817-
em"""Ambiguous overload. The ${err.overloadedAltsStr(remainingDenots)}
1818-
|$all match $expectedStr""")
1814+
errorTree(tree, AmbiguousOverload(tree, remainingDenots, pt)(err))
18191815
}
18201816
}
18211817

compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package reporting
44

55
import core.Contexts.Context
66
import diagnostic.messages._
7+
import dotty.tools.dotc.core.Types.WildcardType
78
import dotty.tools.dotc.parsing.Tokens
89
import org.junit.Assert._
910
import org.junit.{Ignore, Test}
@@ -358,4 +359,30 @@ class ErrorMessagesTests extends ErrorMessagesTest {
358359
assertEquals(namedImport, newPrec)
359360
assertEquals(namedImport, prevPrec)
360361
}
362+
363+
@Test def ambiugousOverloadWithWildcard =
364+
checkMessagesAfter("frontend") {
365+
"""object Context {
366+
| trait A {
367+
| def foo(s: String): String
368+
| def foo: String = foo("foo")
369+
| }
370+
| object B extends A {
371+
| def foo(s: String): String = s
372+
| }
373+
| B.foo
374+
|}
375+
""".stripMargin
376+
}
377+
.expect { (ictx, messages) =>
378+
implicit val ctx: Context = ictx
379+
val defn = ictx.definitions
380+
381+
assertMessageCount(1, messages)
382+
val AmbiguousOverload(tree, List(alt1, alt2), pt: WildcardType) :: Nil = messages
383+
assertEquals("method foo", alt1.show)
384+
assertEquals("(s: String)String", alt1.info.show)
385+
assertEquals("method foo", alt2.show)
386+
}
387+
361388
}

0 commit comments

Comments
 (0)