aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src/dotty')
-rw-r--r--compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala12
-rw-r--r--compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala17
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Checking.scala5
-rw-r--r--compiler/src/dotty/tools/dotc/typer/RefChecks.scala2
4 files changed, 31 insertions, 5 deletions
diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
index 1fffe6841..7f44af486 100644
--- a/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
+++ b/compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
@@ -6,6 +6,7 @@ import core._, core.Decorators._
import Annotations._, Contexts._, Flags._, Phases._, Trees._, Types._, Symbols._
import Names._, NameOps._, StdNames._
import typer.Inliner
+import typer.ErrorReporting.cyclicErrorMsg
import dotty.tools.io.Path
import java.io.PrintWriter
@@ -190,7 +191,16 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
def apiClassStructure(csym: ClassSymbol): api.Structure = {
val cinfo = csym.classInfo
- val bases = linearizedAncestorTypes(cinfo)
+ val bases =
+ try linearizedAncestorTypes(cinfo)
+ catch {
+ case ex: CyclicReference =>
+ // See neg/i1750a for an example where a cyclic error can arise.
+ // The root cause in this example is an illegal "override" of an inner trait
+ ctx.error(cyclicErrorMsg(ex), csym.pos)
+ defn.ObjectType :: Nil
+ }
+
val apiBases = bases.map(apiType)
// Synthetic methods that are always present do not affect the API
diff --git a/compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala b/compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala
index 650a03054..1f1f371a6 100644
--- a/compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala
+++ b/compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala
@@ -6,6 +6,7 @@ import Flags._, Symbols._, Contexts._, Types._, Scopes._, Decorators._
import util.HashSet
import collection.mutable
import collection.immutable.BitSet
+import typer.ErrorReporting.cyclicErrorMsg
import scala.annotation.tailrec
/** A module that can produce a kind of iterator (`Cursor`),
@@ -122,10 +123,18 @@ object OverridingPairs {
if (nextEntry ne null) {
nextEntry = decls.lookupNextEntry(nextEntry)
if (nextEntry ne null) {
- overridden = nextEntry.sym
- if (overriding.owner != overridden.owner && matches(overriding, overridden)) {
- visited += overridden
- if (!hasCommonParentAsSubclass(overriding.owner, overridden.owner)) return
+ try {
+ overridden = nextEntry.sym
+ if (overriding.owner != overridden.owner && matches(overriding, overridden)) {
+ visited += overridden
+ if (!hasCommonParentAsSubclass(overriding.owner, overridden.owner)) return
+ }
+ }
+ catch {
+ case ex: CyclicReference =>
+ // See neg/i1750a for an example where a cyclic error can arise.
+ // The root cause in this example is an illegal "override" of an inner trait
+ ctx.error(cyclicErrorMsg(ex), base.pos)
}
} else {
curEntry = curEntry.prev
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")