Skip to content

Commit 062d9ca

Browse files
som-snyttlrytz
authored andcommitted
Improve source check of conflicting definition
An inherited member cannot shadow a definition in scope that was defined in the current compilation unit. Aliases are given a pass of sorts. Either the member or the definition may be overloaded, which complicates both detection and mitigation. Tests are for the status quo.
1 parent 0b52243 commit 062d9ca

File tree

10 files changed

+73
-3
lines changed

10 files changed

+73
-3
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,8 +439,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
439439
if owner.is(Package) then
440440
owner.denot.asClass.membersNamed(name)
441441
.filterWithPredicate(d => !d.symbol.is(Package)
442-
&& denot.symbol.source.exists
443-
&& d.symbol.source == denot.symbol.source)
442+
&& d.symbol.source.exists
443+
&& isDefinedInCurrentUnit(d))
444444
else
445445
val scope = if owner.isClass then owner.info.decls else outer.scope
446446
scope.denotsNamed(name)
@@ -481,7 +481,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
481481
result = checkNewOrShadowed(found, Definition) // no need to go further out, we found highest prec entry
482482
found match
483483
case found: NamedType
484-
if curOwner.isClass && found.denot.exists && isInherited(found.denot) && !ctx.compilationUnit.isJava =>
484+
if curOwner.isClass && isInherited(found.denot) && !ctx.compilationUnit.isJava =>
485485
checkNoOuterDefs(found.denot, ctx, ctx)
486486
case _ =>
487487
else

tests/neg/i17433.check

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- [E049] Reference Error: tests/neg/i17433.scala:9:10 -----------------------------------------------------------------
2+
9 | def g = f(42) // error
3+
| ^
4+
| Reference to f is ambiguous.
5+
| It is both defined in package <empty>
6+
| and inherited subsequently in class D
7+
|
8+
| longer explanation available when compiling with `-explain`

tests/neg/i17433.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
class C:
3+
def f(i: Int) = i + 1
4+
def f(s: String) = s + "_1"
5+
6+
def f = 42
7+
8+
class D extends C:
9+
def g = f(42) // error
10+
11+
@main def test() = println:
12+
D().g

tests/neg/i17433c.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
package p:
3+
trait T:
4+
def t(i: Int) = i + 1
5+
def t(s: String) = s + "_1"
6+
7+
package object q extends T
8+
9+
package q:
10+
11+
class C extends T:
12+
def c = t(42) // error

tests/neg/i17433d.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
package p:
3+
trait T:
4+
def t(i: Int) = i + 1
5+
6+
package object q extends T:
7+
override def t(i: Int) = i + 2
8+
def t(s: String) = s + "_2"
9+
10+
package q:
11+
12+
class C extends T:
13+
def c = t(42) // error
File renamed without changes.
File renamed without changes.

tests/pos/i17433b/p.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
package p:
3+
trait T:
4+
def t(i: Int) = i + 1
5+
def t(s: String) = s + "_1"
6+
7+
package object q extends T

tests/pos/i17433b/q.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
package p
3+
package q
4+
5+
class C extends T:
6+
def c = t(42)

tests/pos/i17433c.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
package p:
3+
trait T:
4+
def t(i: Int) = i + 1
5+
//def t(s: String) = s + "_1" // it won't try to reconcile the overloaded member
6+
7+
package object q extends T
8+
9+
package q:
10+
11+
class C extends T:
12+
def c = t(42) // should error because this.t is not q.t, but is currently reconciled

0 commit comments

Comments
 (0)