From 2ac62aa9e91b58314e18641b1b831afb7d80741c Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 7 Nov 2009 20:02:30 +0000 Subject: Fixed #2497 --- .../scala/tools/nsc/typechecker/RefChecks.scala | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src/compiler/scala/tools/nsc/typechecker/RefChecks.scala') 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 other by - * member are met. + * member of class clazz 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) && -- cgit v1.2.3