Skip to content

Commit 5093126

Browse files
ennrufelixmulder
authored andcommitted
Change Ambiguous Import error in Typer to case class (#2362)
* Change Ambiguous Import error in Typer to case class * Remove stripMargin
1 parent d1754fa commit 5093126

File tree

4 files changed

+67
-15
lines changed

4 files changed

+67
-15
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
@@ -56,6 +56,7 @@ public enum ErrorMessageID {
5656
CyclicReferenceInvolvingID,
5757
CyclicReferenceInvolvingImplicitID,
5858
SuperQualMustBeParentID,
59+
AmbiguousImportID,
5960
;
6061

6162
public int errorNumber() {

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,4 +1218,39 @@ object messages {
12181218
|Attempting to define a field in a method signature after a varargs field is an error.
12191219
|""".stripMargin
12201220
}
1221+
1222+
case class AmbiguousImport(name: Names.Name, newPrec: Int, prevPrec: Int, prevCtx: Context)(implicit ctx: Context)
1223+
extends Message(AmbiguousImportID) {
1224+
1225+
import typer.Typer.BindingPrec._
1226+
1227+
/** A string which explains how something was bound; Depending on `prec` this is either
1228+
* imported by <tree>
1229+
* or defined in <symbol>
1230+
*/
1231+
private def bindingString(prec: Int, whereFound: Context, qualifier: String = "") =
1232+
if (isImportPrec(prec)) {
1233+
ex"""imported$qualifier by ${hl"${whereFound.importInfo}"}"""
1234+
} else
1235+
ex"""defined$qualifier in ${hl"${whereFound.owner.toString}"}"""
1236+
1237+
1238+
val msg =
1239+
i"""|reference to `${hl"$name"}` is ambiguous
1240+
|it is both ${bindingString(newPrec, ctx)}
1241+
|and ${bindingString(prevPrec, prevCtx, " subsequently")}"""
1242+
1243+
val kind = "Reference"
1244+
1245+
val explanation =
1246+
hl"""|The compiler can't decide which of the possible choices you
1247+
|are referencing with $name.
1248+
|Note:
1249+
|- Definitions take precedence over imports
1250+
|- Named imports take precedence over wildcard imports
1251+
|- You may replace a name when imported using
1252+
| ${"import"} scala.{ $name => ${name.show + "Tick"} }
1253+
|"""
1254+
}
1255+
12211256
}

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

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,6 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
140140
def findRef(previous: Type, prevPrec: Int, prevCtx: Context)(implicit ctx: Context): Type = {
141141
import BindingPrec._
142142

143-
/** A string which explains how something was bound; Depending on `prec` this is either
144-
* imported by <tree>
145-
* or defined in <symbol>
146-
*/
147-
def bindingString(prec: Int, whereFound: Context, qualifier: String = "") =
148-
if (prec == wildImport || prec == namedImport) {
149-
ex"""imported$qualifier by ${hl"${whereFound.importInfo}"}"""
150-
} else
151-
ex"""defined$qualifier in ${hl"${whereFound.owner.toString}"}"""
152-
153143
/** Check that any previously found result from an inner context
154144
* does properly shadow the new one from an outer context.
155145
* @param found The newly found result
@@ -170,11 +160,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
170160
}
171161
else {
172162
if (!scala2pkg && !previous.isError && !found.isError) {
173-
error(
174-
ex"""|reference to `$name` is ambiguous
175-
|it is both ${bindingString(newPrec, ctx, "")}
176-
|and ${bindingString(prevPrec, prevCtx, " subsequently")}""",
177-
tree.pos)
163+
error(AmbiguousImport(name, newPrec, prevPrec, prevCtx), tree.pos)
178164
}
179165
previous
180166
}

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,4 +328,34 @@ class ErrorMessagesTests extends ErrorMessagesTest {
328328
assertEquals("B", qual.show)
329329
assertEquals("class C", cls.show)
330330
}
331+
332+
@Test def ambiguousImport =
333+
checkMessagesAfter("frontend") {
334+
"""
335+
|object A {
336+
| class ToBeImported
337+
|}
338+
|object B {
339+
| class ToBeImported
340+
|}
341+
|class C {
342+
| import A.ToBeImported
343+
| import B.ToBeImported
344+
|
345+
| val value: ToBeImported = ???
346+
|}
347+
""".stripMargin
348+
}
349+
.expect { (ictx, messages) =>
350+
implicit val ctx: Context = ictx
351+
val defn = ictx.definitions
352+
353+
import typer.Typer.BindingPrec._
354+
355+
assertMessageCount(1, messages)
356+
val AmbiguousImport(name, newPrec, prevPrec, prevCtx) :: Nil = messages
357+
assertEquals("ToBeImported", name.show)
358+
assertEquals(namedImport, newPrec)
359+
assertEquals(namedImport, prevPrec)
360+
}
331361
}

0 commit comments

Comments
 (0)