summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-11-07 20:02:30 +0000
committerMartin Odersky <odersky@gmail.com>2009-11-07 20:02:30 +0000
commit2ac62aa9e91b58314e18641b1b831afb7d80741c (patch)
tree3e32fe43d746ac0bf866112fe30eb5f3ba7972dc /src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
parentc7c9684ae4d8e359e3ae57f619a9fa188c8b07df (diff)
downloadscala-2ac62aa9e91b58314e18641b1b831afb7d80741c.tar.gz
scala-2ac62aa9e91b58314e18641b1b831afb7d80741c.tar.bz2
scala-2ac62aa9e91b58314e18641b1b831afb7d80741c.zip
Fixed #2497
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/RefChecks.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index d273af60c5..31ebdc5906 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -234,7 +234,7 @@ abstract class RefChecks extends InfoTransform {
}
/** Check that all conditions for overriding <code>other</code> by
- * <code>member</code> are met.
+ * <code>member</code> of class <code>clazz</code> are met.
*/
def checkOverride(clazz: Symbol, member: Symbol, other: Symbol) {
@@ -271,9 +271,9 @@ abstract class RefChecks extends InfoTransform {
// return if we already checked this combination elsewhere
if (member.owner != clazz) {
if ((member.owner isSubClass other.owner) && (member.isDeferred || !other.isDeferred)) {
- //Console.println(infoString(member) + " shadows1 " + infoString(other) " in " + clazz);//DEBUG
- return;
- }
+ //Console.println(infoString(member) + " shadows1 " + infoString(other) " in " + clazz);//DEBUG
+ return;
+ }
if (clazz.info.parents exists (parent =>
(parent.typeSymbol isSubClass other.owner) && (parent.typeSymbol isSubClass member.owner) &&
(member.isDeferred || !other.isDeferred))) {
@@ -287,6 +287,11 @@ abstract class RefChecks extends InfoTransform {
}
}
+ /** Is the intersection between given two lists of overridden symbols empty?
+ */
+ def intersectionIsEmpty(syms1: List[Symbol], syms2: List[Symbol]) =
+ !(syms1 exists (syms2 contains))
+
if (member hasFlag PRIVATE) { // (1.1)
overrideError("has weaker access privileges; it should not be private")
}
@@ -310,6 +315,12 @@ abstract class RefChecks extends InfoTransform {
} else if ((member hasFlag (OVERRIDE | ABSOVERRIDE)) &&
(other hasFlag ACCESSOR) && other.accessed.isVariable && !other.accessed.hasFlag(LAZY)) {
overrideError("cannot override a mutable variable")
+ } else if ((member hasFlag (OVERRIDE | ABSOVERRIDE)) &&
+ !(member.owner isSubClass other.owner) &&
+ !member.isDeferred && !other.isDeferred &&
+ intersectionIsEmpty(member.allOverriddenSymbols, other.allOverriddenSymbols)) {
+ overrideError("cannot override a concrete member without a third member that's overridden by both "+
+ "(this rule is designed to prevent ``accidental overrides'')")
} else if (other.isStable && !member.isStable) { // (1.4)
overrideError("needs to be a stable, immutable value")
} else if (member.isValue && (member hasFlag LAZY) &&