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 +++++++++++++++---- src/library/scala/collection/TraversableLike.scala | 2 +- .../generic/GenericTraversableTemplate.scala | 2 +- .../scala/collection/mutable/FlatHashTable.scala | 6 +----- src/library/scala/collection/mutable/HashMap.scala | 4 ++-- src/library/scala/collection/mutable/HashSet.scala | 4 ++-- src/library/scala/collection/mutable/HashTable.scala | 6 +----- .../scala/collection/mutable/LinkedHashMap.scala | 4 ++-- .../scala/collection/mutable/LinkedHashSet.scala | 4 ++-- 9 files changed, 27 insertions(+), 24 deletions(-) (limited to 'src') 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) && diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala index 57f9840804..4fdaa6fee2 100644 --- a/src/library/scala/collection/TraversableLike.scala +++ b/src/library/scala/collection/TraversableLike.scala @@ -63,7 +63,7 @@ import annotation.experimental * @version 2.8 * @since 2.8 */ -trait TraversableLike[+A, +Repr] { +trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr] { self => import Traversable.breaks._ diff --git a/src/library/scala/collection/generic/GenericTraversableTemplate.scala b/src/library/scala/collection/generic/GenericTraversableTemplate.scala index 50a7aa3fe0..cf4f3abdd2 100644 --- a/src/library/scala/collection/generic/GenericTraversableTemplate.scala +++ b/src/library/scala/collection/generic/GenericTraversableTemplate.scala @@ -18,7 +18,7 @@ import annotation.unchecked.uncheckedVariance /** * @since 2.8 */ -trait GenericTraversableTemplate[+A, +CC[X] <: Traversable[X]] { +trait GenericTraversableTemplate[+A, +CC[X] <: Traversable[X]] extends HasNewBuilder[A, CC[A] @uncheckedVariance] { def foreach[U](f: A => U): Unit def head: A diff --git a/src/library/scala/collection/mutable/FlatHashTable.scala b/src/library/scala/collection/mutable/FlatHashTable.scala index 1861953eec..1d55933050 100644 --- a/src/library/scala/collection/mutable/FlatHashTable.scala +++ b/src/library/scala/collection/mutable/FlatHashTable.scala @@ -40,10 +40,6 @@ trait FlatHashTable[A] { */ protected var threshold: Int = newThreshold(initialSize) - /** Returns the number of entires in this hash table. - */ - def size: Int = tableSize - def findEntry(elem: A): Option[A] = { var h = index(elemHashCode(elem)) var entry = table(h) @@ -163,7 +159,7 @@ trait FlatHashTable[A] { (size.toLong * lf / loadFactorDenum ).toInt } - protected def clear() { + protected def clearTable() { var i = table.length - 1 while (i >= 0) { table(i) = null; i -= 1 } tableSize = 0 diff --git a/src/library/scala/collection/mutable/HashMap.scala b/src/library/scala/collection/mutable/HashMap.scala index 2591557c78..b2f259e4e9 100644 --- a/src/library/scala/collection/mutable/HashMap.scala +++ b/src/library/scala/collection/mutable/HashMap.scala @@ -23,8 +23,8 @@ class HashMap[A, B] extends Map[A, B] with HashTable[A] { override def empty: HashMap[A, B] = HashMap.empty[A, B] - override def clear() = super.clear() - override def size: Int = super[HashTable].size + override def clear() = clearTable() + override def size: Int = tableSize type Entry = DefaultEntry[A, B] diff --git a/src/library/scala/collection/mutable/HashSet.scala b/src/library/scala/collection/mutable/HashSet.scala index 9f24a0b341..9144a4be88 100644 --- a/src/library/scala/collection/mutable/HashSet.scala +++ b/src/library/scala/collection/mutable/HashSet.scala @@ -28,7 +28,7 @@ class HashSet[A] extends Set[A] with FlatHashTable[A] { override def companion: GenericCompanion[HashSet] = HashSet - override def size = super.size + override def size = tableSize def contains(elem: A): Boolean = containsEntry(elem) @@ -38,7 +38,7 @@ class HashSet[A] extends Set[A] override def add(elem: A): Boolean = addEntry(elem) override def remove(elem: A): Boolean = removeEntry(elem).isDefined - override def clear() = super.clear() + override def clear() = clearTable() override def foreach[U](f: A => U) { var i = 0 diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala index 9d3a35376c..9dd8a7aeb0 100644 --- a/src/library/scala/collection/mutable/HashTable.scala +++ b/src/library/scala/collection/mutable/HashTable.scala @@ -75,10 +75,6 @@ trait HashTable[A] { */ protected var threshold: Int = initialThreshold - /** Returns the size of this hash table. - */ - def size = tableSize - /** Find entry with given key in table, null if not found */ protected def findEntry(key: A): Entry = { @@ -154,7 +150,7 @@ trait HashTable[A] { /** Remove all entries from table */ - def clear() { + protected def clearTable() { var i = table.length - 1 while (i >= 0) { table(i) = null; i = i - 1 } tableSize = 0 diff --git a/src/library/scala/collection/mutable/LinkedHashMap.scala b/src/library/scala/collection/mutable/LinkedHashMap.scala index 5c17ef1cfb..b0cad79ef4 100644 --- a/src/library/scala/collection/mutable/LinkedHashMap.scala +++ b/src/library/scala/collection/mutable/LinkedHashMap.scala @@ -35,7 +35,7 @@ class LinkedHashMap[A, B] extends Map[A, B] with HashTable[A] { override def empty = LinkedHashMap.empty[A, B] - override def size = super[HashTable].size + override def size = tableSize type Entry = LinkedEntry[A, B] @@ -112,7 +112,7 @@ class LinkedHashMap[A, B] extends Map[A, B] } override def clear() { - super[HashTable].clear() + clearTable() firstEntry = null } } diff --git a/src/library/scala/collection/mutable/LinkedHashSet.scala b/src/library/scala/collection/mutable/LinkedHashSet.scala index fd606badec..081b068723 100644 --- a/src/library/scala/collection/mutable/LinkedHashSet.scala +++ b/src/library/scala/collection/mutable/LinkedHashSet.scala @@ -27,7 +27,7 @@ class LinkedHashSet[A] extends Set[A] protected val ordered = new ListBuffer[A] - override def size = super.size + override def size = tableSize def contains(elem: A): Boolean = containsEntry(elem) @@ -46,7 +46,7 @@ class LinkedHashSet[A] extends Set[A] override def clear() { ordered.clear() - super.clear() + clearTable() } override def iterator = ordered.iterator -- cgit v1.2.3