diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 182351bfe7c4..c4116d8a056e 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -376,6 +376,17 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer case denot => !denot.hasAltWith(isCurrent) def checkNoOuterDefs(denot: Denotation, last: Context, prevCtx: Context): Unit = + def sameTermOrType(d1: SingleDenotation, d2: Denotation) = + d2.containsSym(d1.symbol) || d2.hasUniqueSym && { + val sym1 = d1.symbol + val sym2 = d2.symbol + if sym1.isTerm then + sym1.isStableMember && + sym2.isStableMember && + sym1.owner.thisType.select(name, sym1) =:= sym2.owner.thisType.select(name, sym2) + else + (sym1.isAliasType || sym2.isAliasType) && d1.info =:= d2.info + } val outer = last.outer val owner = outer.owner if (owner eq last.owner) && (outer.scope eq last.scope) then @@ -385,7 +396,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer val competing = scope.denotsNamed(name).filterWithFlags(required, excluded) if competing.exists then val symsMatch = competing - .filterWithPredicate(sd => denot.containsSym(sd.symbol)) + .filterWithPredicate(sd => sameTermOrType(sd, denot)) .exists if !symsMatch && !suppressErrors then report.errorOrMigrationWarning( diff --git a/tests/pos/t11921.scala b/tests/pos/t11921.scala new file mode 100644 index 000000000000..a040fefabeab --- /dev/null +++ b/tests/pos/t11921.scala @@ -0,0 +1,16 @@ +object t1: + class C + class A: + val c: B.c.type = B.c + object B: + val c = new C + val a = new A: + def m = c // not ambiguous, `this.c` and `B.c` are compatible paths + +object t2: + class C[T]: + type TT = T + object O: + type TT = String + class D extends C[TT]: + def n(x: TT) = x // `TT` is not ambiguous, `this.TT` and `O.TT` are aliases