diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 5c079ae05b83..000764d43c2b 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -305,7 +305,7 @@ object RefChecks { def info = self.memberInfo(sym1) val infoStr = if (sym1.isAliasType) i", which equals ${info.bounds.hi}" - else if (sym1.isAbstractOrParamType) i" with bounds$info" + else if (sym1.isAbstractOrParamType && info != TypeBounds.empty) i" with bounds$info" else if (sym1.is(Module)) "" else if (sym1.isTerm) i" of type $info" else "" @@ -430,6 +430,10 @@ object RefChecks { // direct overrides were already checked on completion (see Checking.chckWellFormed) // the test here catches indirect overriddes between two inherited base types. overrideError("cannot be used here - class definitions cannot be overridden") + else if (other.isOpaqueAlias) + // direct overrides were already checked on completion (see Checking.chckWellFormed) + // the test here catches indirect overriddes between two inherited base types. + overrideError("cannot be used here - opaque type aliases cannot be overridden") else if (!other.is(Deferred) && member.isClass) overrideError("cannot be used here - classes can only override abstract types") else if other.isEffectivelyFinal then // (1.2) diff --git a/tests/neg/i14659.scala b/tests/neg/i14659.scala new file mode 100644 index 000000000000..6c467386f7e1 --- /dev/null +++ b/tests/neg/i14659.scala @@ -0,0 +1,13 @@ +trait Foo { + opaque type Out = Int + def out1: Out + def out2: Out = out1 +} + +object Bar extends Foo { + override opaque type Out = String // error + override def out1 = "abc" +} + +@main def run() = + val x = Bar.out2 \ No newline at end of file