diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 9d8fdcc006c9..02a432d1fd9e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -366,11 +366,16 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer // Does reference `tp` refer only to inherited symbols? def isInherited(denot: Denotation) = def isCurrent(mbr: SingleDenotation): Boolean = - !mbr.symbol.exists || mbr.symbol.owner == ctx.owner + !mbr.symbol.exists || mbr.symbol.owner == ctx.owner || ctx.owner.is(Package) denot match case denot: SingleDenotation => !isCurrent(denot) case denot => !denot.hasAltWith(isCurrent) + /* It is an error if an identifier x is available as an inherited member in an inner scope + * and the same name x is defined in an outer scope in the same source file, unless + * the inherited member (has an overloaded alternative that) coincides with + * (an overloaded alternative of) the definition x. + */ def checkNoOuterDefs(denot: Denotation, last: Context, prevCtx: Context): Unit = def sameTermOrType(d1: SingleDenotation, d2: Denotation) = d2.containsSym(d1.symbol) || d2.hasUniqueSym && { @@ -387,9 +392,15 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer val owner = outer.owner if (owner eq last.owner) && (outer.scope eq last.scope) then checkNoOuterDefs(denot, outer, prevCtx) - else if !owner.is(Package) then - val scope = if owner.isClass then owner.info.decls else outer.scope - val competing = scope.denotsNamed(name).filterWithFlags(required, excluded) + else if !owner.isRoot then + val found = + if owner.is(Package) then + owner.denot.asClass.membersNamed(name) + .filterWithPredicate(d => !d.symbol.is(Package) && d.symbol.source == denot.symbol.source) + else + val scope = if owner.isClass then owner.info.decls else outer.scope + scope.denotsNamed(name) + val competing = found.filterWithFlags(required, excluded | Synthetic) if competing.exists then val symsMatch = competing .filterWithPredicate(sd => sameTermOrType(sd, denot)) diff --git a/tests/neg/ambiref.check b/tests/neg/ambiref.check index 5d701b3b3b71..32b4078f1346 100644 --- a/tests/neg/ambiref.check +++ b/tests/neg/ambiref.check @@ -30,3 +30,19 @@ | and inherited subsequently in class E | | longer explanation available when compiling with `-explain` +-- [E049] Reference Error: tests/neg/ambiref.scala:43:10 --------------------------------------------------------------- +43 | println(global) // error + | ^^^^^^ + | Reference to global is ambiguous. + | It is both defined in package + | and inherited subsequently in object D + | + | longer explanation available when compiling with `-explain` +-- [E049] Reference Error: tests/neg/ambiref.scala:49:16 --------------------------------------------------------------- +49 | def t = new T { } // error + | ^ + | Reference to T is ambiguous. + | It is both defined in package p + | and inherited subsequently in class C + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/ambiref.scala b/tests/neg/ambiref.scala index e7a5d5efbd7e..bb48997cd465 100644 --- a/tests/neg/ambiref.scala +++ b/tests/neg/ambiref.scala @@ -40,4 +40,24 @@ val global = 0 class C: val global = 1 object D extends C: - println(global) // OK, since global is defined in package \ No newline at end of file + println(global) // error + +package p: + class T + trait P { trait T } + class C extends P: + def t = new T { } // error + +package scala: + trait P { trait Option[+A] } + class C extends P: + def t = new Option[String] { } // OK, competing scala.Option is not defined in the same compilation unit + +object test5: + class Mu // generates a synthetic companion object with an apply method + trait A { + val Mu = 1 + } + trait B extends A { + def t = Mu // don't warn about synthetic companion + } diff --git a/tests/pos-special/fatal-warnings/i9260.scala b/tests/pos-special/fatal-warnings/i9260.scala index df548f393eea..0392c1c96fa8 100644 --- a/tests/pos-special/fatal-warnings/i9260.scala +++ b/tests/pos-special/fatal-warnings/i9260.scala @@ -10,7 +10,7 @@ end AstImpl object untpd extends AstImpl[Null]: - def DefDef(ast: Ast): DefDef = ast match + def DefDef(ast: this.Ast): DefDef = ast match case ast: DefDef => ast end untpd diff --git a/tests/run/protectedacc.scala b/tests/run/protectedacc.scala index a08e7201fd15..85aa3438faa3 100644 --- a/tests/run/protectedacc.scala +++ b/tests/run/protectedacc.scala @@ -134,7 +134,7 @@ package p { abstract class X[T] extends PolyA[T] { - trait Inner extends B { + trait Inner extends this.B { def self: T; def self2: Node; def getB: Inner;