diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index cb1aea27c444..42be822c9709 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -695,6 +695,15 @@ object RefChecks { && withMode(Mode.IgnoreCaptures)(mbrDenot.matchesLoosely(impl, alwaysCompareTypes = true))) .exists + /** Filter out symbols from `syms` that are overridden by a symbol appearing later in the list. + * Symbols that are not overridden are kept. */ + def lastOverrides(syms: List[Symbol]): List[Symbol] = + val deduplicated = + syms.foldLeft(List.empty[Symbol]): + case (acc, sym) if acc.exists(s => isOverridingPair(s, sym, clazz.thisType)) => acc + case (acc, sym) => sym :: acc + deduplicated.reverse + /** The term symbols in this class and its baseclasses that are * abstract in this class. We can't use memberNames for that since * a concrete member might have the same signature as an abstract @@ -717,7 +726,8 @@ object RefChecks { val missingMethods = grouped.toList flatMap { case (name, syms) => - syms.filterConserve(!_.isSetter) + lastOverrides(syms) + .filterConserve(!_.isSetter) .distinctBy(_.signature) // Avoid duplication for similar definitions (#19731) } diff --git a/tests/neg/i21335.check b/tests/neg/i21335.check new file mode 100644 index 000000000000..a7ee092eec0e --- /dev/null +++ b/tests/neg/i21335.check @@ -0,0 +1,8 @@ +-- Error: tests/neg/i21335.scala:7:6 ----------------------------------------------------------------------------------- +7 |class Z1 extends Bar1 // error + | ^ + | class Z1 needs to be abstract, since override def bar(): Bar1 in trait Bar1 is not defined +-- Error: tests/neg/i21335.scala:12:6 ---------------------------------------------------------------------------------- +12 |class Z2 extends Bar2 // error + | ^ + | class Z2 needs to be abstract, since def bar(): Bar2 in trait Bar2 is not defined diff --git a/tests/neg/i21335.scala b/tests/neg/i21335.scala new file mode 100644 index 000000000000..270765c80535 --- /dev/null +++ b/tests/neg/i21335.scala @@ -0,0 +1,12 @@ +trait Foo: + def bar(): Foo + +trait Bar1 extends Foo: + override def bar(): Bar1 + +class Z1 extends Bar1 // error + +trait Bar2 extends Foo: + def bar(): Bar2 + +class Z2 extends Bar2 // error