diff options
author | Martin Odersky <odersky@gmail.com> | 2017-01-29 17:54:30 +1100 |
---|---|---|
committer | Guillaume Martres <smarter@ubuntu.com> | 2017-01-29 14:44:30 +0100 |
commit | 56fb15888fb98e3a6a535f5734bb8ce82fcd76c3 (patch) | |
tree | c1e01cce8a76a5e66ba2a54472bc899ae41ca405 /compiler/src/dotty/tools/dotc/typer | |
parent | 6e8933ccc40bbfe1a92c32c2d8314fd6facef12a (diff) | |
download | dotty-56fb15888fb98e3a6a535f5734bb8ce82fcd76c3.tar.gz dotty-56fb15888fb98e3a6a535f5734bb8ce82fcd76c3.tar.bz2 dotty-56fb15888fb98e3a6a535f5734bb8ce82fcd76c3.zip |
Fix #1750: Handle illegal class overrides better
Illegal class overrides are fundamentally at odds with the way dotty
represents types and therefore can cause lots of low-level problems.
Two measures in this commit
First, we detect direct illegal class overrides on completion instead of
during RefChecks. Break the override by making the previously
overriding type private.
This fixes i1750.scala, but still fails for indirect overrides between
two unrelated outer traits/classes that are inherited by the same class or trait.
We fix this by catching the previously thrown ClassCastException
in both ExtractAPI and RefChecks.
Test case for indirect overrides is in i1750a.scala.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer')
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Checking.scala | 5 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/RefChecks.scala | 2 |
2 files changed, 7 insertions, 0 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 41d9f9572..321c275d7 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -338,6 +338,11 @@ object Checking { checkNoConflict(Final, Sealed) checkNoConflict(Private, Protected) checkNoConflict(Abstract, Override) + if (sym.isType && !sym.is(Deferred)) + for (cls <- sym.allOverriddenSymbols.filter(_.isClass)) { + fail(i"$sym cannot have the same name as ${cls.showLocated} -- class definitions cannot be overridden") + sym.setFlag(Private) // break the overriding relationship by making sym Private + } } /** Check the type signature of the symbol `M` defined by `tree` does not refer diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 3192546cd..e113399c5 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -289,6 +289,8 @@ object RefChecks { if (!isOverrideAccessOK) { overrideAccessError() } else if (other.isClass) { + // 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.is(Deferred) && member.isClass) { overrideError("cannot be used here - classes can only override abstract types") |