Skip to content

Commit 1c1b78f

Browse files
authored
Merge pull request #2354 from ennru/ennru_AmbiguousOverload
Moved Ambiguous Overload error in Typer to case class
2 parents cfe7d70 + 65ec8ed commit 1c1b78f

File tree

4 files changed

+60
-20
lines changed

4 files changed

+60
-20
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
ReassignmentToValID,
6162
;
6263

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

Lines changed: 25 additions & 8 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 {
@@ -1193,7 +1194,6 @@ object messages {
11931194
extends Message(SuperQualMustBeParentID) {
11941195

11951196
val msg = hl"""|$qual does not name a parent of $cls"""
1196-
11971197
val kind = "Reference"
11981198

11991199
private val parents: Seq[String] = (cls.info.parents map (_.name.show)).sorted
@@ -1208,15 +1208,13 @@ object messages {
12081208
}
12091209

12101210
case class VarArgsParamMustComeLast()(implicit ctx: Context)
1211-
extends Message(IncorrectRepeatedParameterSyntaxID) {
1212-
override def msg: String = "varargs parameter must come last"
1213-
1214-
override def kind: String = "Syntax"
1215-
1216-
override def explanation: String =
1211+
extends Message(IncorrectRepeatedParameterSyntaxID) {
1212+
val msg = "varargs parameter must come last"
1213+
val kind = "Syntax"
1214+
val explanation =
12171215
hl"""|The varargs field must be the last field in the method signature.
12181216
|Attempting to define a field in a method signature after a varargs field is an error.
1219-
|""".stripMargin
1217+
|"""
12201218
}
12211219

12221220
case class AmbiguousImport(name: Names.Name, newPrec: Int, prevPrec: Int, prevCtx: Context)(implicit ctx: Context)
@@ -1253,6 +1251,25 @@ object messages {
12531251
|"""
12541252
}
12551253

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

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: 32 additions & 6 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}
@@ -359,6 +360,31 @@ class ErrorMessagesTests extends ErrorMessagesTest {
359360
assertEquals(namedImport, prevPrec)
360361
}
361362

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+
362388
@Test def reassignmentToVal =
363389
checkMessagesAfter("frontend") {
364390
"""
@@ -368,10 +394,10 @@ class ErrorMessagesTests extends ErrorMessagesTest {
368394
|}
369395
""".stripMargin
370396
}
371-
.expect { (ictx, messages) =>
372-
implicit val ctx: Context = ictx
373-
assertMessageCount(1, messages)
374-
val ReassignmentToVal(name) :: Nil = messages
375-
assertEquals("value", name.show)
376-
}
397+
.expect { (ictx, messages) =>
398+
implicit val ctx: Context = ictx
399+
assertMessageCount(1, messages)
400+
val ReassignmentToVal(name) :: Nil = messages
401+
assertEquals("value", name.show)
402+
}
377403
}

0 commit comments

Comments
 (0)