Skip to content

Commit 81b4e5c

Browse files
committed
Add error message hint when extension imports are used as normal methods
1 parent 164eea5 commit 81b4e5c

File tree

9 files changed

+55
-51
lines changed

9 files changed

+55
-51
lines changed

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,7 +1336,8 @@ class ConstrProxyShadows(proxy: TermRef, shadowed: Type, shadowedIsApply: Boolea
13361336
|or use a full prefix for ${shadowed.termSymbol.name} if you mean the latter."""
13371337
end ConstrProxyShadows
13381338

1339-
class AmbiguousReference(name: Name, newPrec: BindingPrec, prevPrec: BindingPrec, prevCtx: Context)(using Context)
1339+
class AmbiguousReference(
1340+
name: Name, newPrec: BindingPrec, prevPrec: BindingPrec, prevCtx: Context, isExtension: => Boolean = false)(using Context)
13401341
extends ReferenceMsg(AmbiguousReferenceID), NoDisambiguation {
13411342

13421343
/** A string which explains how something was bound; Depending on `prec` this is either
@@ -1358,10 +1359,17 @@ class AmbiguousReference(name: Name, newPrec: BindingPrec, prevPrec: BindingPrec
13581359
i"""$howVisible$qualifier in ${whereFound.owner}"""
13591360
}
13601361

1362+
def importHint =
1363+
if (newPrec == BindingPrec.NamedImport || newPrec == BindingPrec.WildImport)
1364+
&& prevPrec == newPrec
1365+
&& isExtension
1366+
then i"\n\n Hint: This error may arise if extension method `$name` is called as a normal method."
1367+
else ""
1368+
13611369
def msg(using Context) =
13621370
i"""|Reference to $name is ambiguous.
13631371
|It is both ${bindingString(newPrec, ctx)}
1364-
|and ${bindingString(prevPrec, prevCtx, " subsequently")}"""
1372+
|and ${bindingString(prevPrec, prevCtx, " subsequently")}$importHint"""
13651373

13661374
def explain(using Context) =
13671375
val precedent =

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
233233
found
234234
else
235235
if !scala2pkg && !previous.isError && !found.isError then
236-
fail(AmbiguousReference(name, newPrec, prevPrec, prevCtx))
236+
fail(AmbiguousReference(name, newPrec, prevPrec, prevCtx,
237+
isExtension = previous.termSymbol.is(ExtensionMethod) && found.termSymbol.is(ExtensionMethod)))
237238
previous
238239

239240
/** Assemble and check alternatives to an imported reference. This implies:

tests/neg/i13558.scala

Lines changed: 0 additions & 31 deletions
This file was deleted.

tests/neg/i16920.check

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
-- [E008] Not Found Error: tests/neg/i16920.scala:20:11 ----------------------------------------------------------------
2-
20 | "five".wow // error
1+
-- [E008] Not Found Error: tests/neg/i16920.scala:19:11 ----------------------------------------------------------------
2+
19 | "five".wow // error
33
| ^^^^^^^^^^
44
| value wow is not a member of String.
55
| An extension method was tried, but could not be fully constructed:
@@ -10,8 +10,8 @@
1010
|
1111
| Found: ("five" : String)
1212
| Required: Int
13-
-- [E008] Not Found Error: tests/neg/i16920.scala:28:6 -----------------------------------------------------------------
14-
28 | 5.wow // error
13+
-- [E008] Not Found Error: tests/neg/i16920.scala:27:6 -----------------------------------------------------------------
14+
27 | 5.wow // error
1515
| ^^^^^
1616
| value wow is not a member of Int.
1717
| An extension method was tried, but could not be fully constructed:
@@ -22,8 +22,8 @@
2222
|
2323
| Found: (5 : Int)
2424
| Required: Boolean
25-
-- [E008] Not Found Error: tests/neg/i16920.scala:29:11 ----------------------------------------------------------------
26-
29 | "five".wow // error
25+
-- [E008] Not Found Error: tests/neg/i16920.scala:28:11 ----------------------------------------------------------------
26+
28 | "five".wow // error
2727
| ^^^^^^^^^^
2828
| value wow is not a member of String.
2929
| An extension method was tried, but could not be fully constructed:
@@ -34,8 +34,8 @@
3434
|
3535
| Found: ("five" : String)
3636
| Required: Boolean
37-
-- [E008] Not Found Error: tests/neg/i16920.scala:36:6 -----------------------------------------------------------------
38-
36 | 5.wow // error
37+
-- [E008] Not Found Error: tests/neg/i16920.scala:35:6 -----------------------------------------------------------------
38+
35 | 5.wow // error
3939
| ^^^^^
4040
| value wow is not a member of Int.
4141
| An extension method was tried, but could not be fully constructed:
@@ -48,8 +48,8 @@
4848
| both Three.wow(5)
4949
| and Two.wow(5)
5050
| are possible expansions of 5.wow
51-
-- [E008] Not Found Error: tests/neg/i16920.scala:44:11 ----------------------------------------------------------------
52-
44 | "five".wow // error
51+
-- [E008] Not Found Error: tests/neg/i16920.scala:43:11 ----------------------------------------------------------------
52+
43 | "five".wow // error
5353
| ^^^^^^^^^^
5454
| value wow is not a member of String.
5555
| An extension method was tried, but could not be fully constructed:
@@ -60,8 +60,8 @@
6060
|
6161
| Found: ("five" : String)
6262
| Required: Int
63-
-- [E008] Not Found Error: tests/neg/i16920.scala:51:11 ----------------------------------------------------------------
64-
51 | "five".wow // error
63+
-- [E008] Not Found Error: tests/neg/i16920.scala:50:11 ----------------------------------------------------------------
64+
50 | "five".wow // error
6565
| ^^^^^^^^^^
6666
| value wow is not a member of String.
6767
| An extension method was tried, but could not be fully constructed:
@@ -72,8 +72,8 @@
7272
|
7373
| Found: ("five" : String)
7474
| Required: Int
75-
-- [E008] Not Found Error: tests/neg/i16920.scala:58:6 -----------------------------------------------------------------
76-
58 | 5.wow // error
75+
-- [E008] Not Found Error: tests/neg/i16920.scala:57:6 -----------------------------------------------------------------
76+
57 | 5.wow // error
7777
| ^^^^^
7878
| value wow is not a member of Int.
7979
| An extension method was tried, but could not be fully constructed:

tests/neg/i16920.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import language.experimental.relaxedExtensionImports
21

32
object One:
43
extension (s: String)

tests/neg/sip54.check

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-- [E049] Reference Error: tests/neg/sip54.scala:12:8 ------------------------------------------------------------------
2+
12 |val _ = meth(foo)() // error // error
3+
| ^^^^
4+
| Reference to meth is ambiguous.
5+
| It is both imported by import A._
6+
| and imported subsequently by import B._
7+
|
8+
| Hint: This error may arise if extension method `meth` is called as a normal method.
9+
|
10+
| longer explanation available when compiling with `-explain`
11+
-- [E007] Type Mismatch Error: tests/neg/sip54.scala:12:13 -------------------------------------------------------------
12+
12 |val _ = meth(foo)() // error // error
13+
| ^^^
14+
| Found: (foo : Foo)
15+
| Required: Bar
16+
|
17+
| longer explanation available when compiling with `-explain`

tests/neg/sip54.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Foo
2+
class Bar
3+
object A:
4+
extension (foo: Foo) def meth(): Foo = foo
5+
object B:
6+
extension (bar: Bar) def meth(): Bar = bar
7+
8+
import A.*
9+
import B.*
10+
11+
val foo = new Foo
12+
val _ = meth(foo)() // error // error

tests/pos/i13558.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
package testcode
2-
import language.experimental.relaxedExtensionImports
32

43
class A
54

tests/pos/i16920.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import language.experimental.relaxedExtensionImports
21

32
object One:
43
extension (s: String)

0 commit comments

Comments
 (0)