From fdc85b34d04c7e3da259f49e8b9d3efe5f41874c Mon Sep 17 00:00:00 2001 From: odersky Date: Wed, 28 Mar 2007 16:33:37 +0000 Subject: [PATCH] Fixed problem with sensibility checks. Made hashset/hashmap thread-safe. git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@10561 5e8d7ff9-d8ef-0310-90f0-a4852d11357a --- src/compiler/scala/tools/nsc/transform/Erasure.scala | 2 +- src/compiler/scala/tools/nsc/typechecker/Infer.scala | 7 ++----- .../scala/tools/nsc/typechecker/RefChecks.scala | 12 +++++++++--- src/library/scala/collection/immutable/HashMap.scala | 10 +++++----- src/library/scala/collection/immutable/HashSet.scala | 10 +++++----- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index bea50aa71..48e546bdc 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -468,7 +468,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { } catch { case ex: Throwable => //if (settings.debug.value) - Console.println("exception when typing " + tree); + Console.println("exception when typing " + tree); throw ex } def adaptCase(cdef: CaseDef): CaseDef = { diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 8f45ba017..3328bbcfd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -338,12 +338,9 @@ trait Infer requires Analyzer { explanation) if (context.unit != null) sym.toplevelClass match { case clazz : ClassSymbol => - // System.err.println("TOP: " + clazz + " " + clazz.sourceFile) if (clazz.sourceFile != null) { context.unit.depends += clazz.sourceFile - //Console.println("DEPEND " + global.currentRun.currentUnit + " ON " + clazz.sourceFile + " XXX " + context.unit) } - case _ => } val sym1 = sym filter (alt => context.isAccessible(alt, pre, site.isInstanceOf[Super])) @@ -453,7 +450,7 @@ trait Infer requires Analyzer { case ex: NoInstance => WildcardType } val tvars = tparams map freshVar - if (isCompatible(restpe.subst(tparams, tvars), pt)) + if (isWeaklyCompatible(restpe.subst(tparams, tvars), pt)) List.map2(tparams, tvars) ((tparam, tvar) => instantiateToBound(tvar, varianceInTypes(formals)(tparam))) else @@ -489,7 +486,7 @@ trait Infer requires Analyzer { } // check first whether type variables can be fully defined from // expected result type. - if (!isCompatible(restpe.subst(tparams, tvars), pt)) { + if (!isWeaklyCompatible(restpe.subst(tparams, tvars), pt)) { throw new DeferredNoInstance(() => "result type " + normalize(restpe) + " is incompatible with expected type " + pt) } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index b4b8f1cb5..e07b8ea43 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -448,9 +448,15 @@ abstract class RefChecks extends InfoTransform { } name match { case nme.EQ | nme.NE | nme.LT | nme.GT | nme.LE | nme.GE => - val formal = fn.tpe.paramTypes.head.widen.symbol - val actual = args.head.tpe.widen.symbol - val receiver = qual.tpe.widen.symbol + def underlyingClass(tp: Type): Symbol = { + var sym = tp.widen.symbol + while (sym.isAbstractType) + sym = sym.info.bounds.hi.widen.symbol + sym + } + val formal = underlyingClass(fn.tpe.paramTypes.head) + val actual = underlyingClass(args.head.tpe) + val receiver = underlyingClass(qual.tpe) def nonSensibleWarning(what: String, alwaysEqual: boolean) = unit.warning(pos, "comparing "+what+" using `"+name.decode+"' will always yield "+ (alwaysEqual == (name == nme.EQ || name == nme.LE || name == nme.GE))) diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala index 6a000a1f4..dd9ec3d3f 100644 --- a/src/library/scala/collection/immutable/HashMap.scala +++ b/src/library/scala/collection/immutable/HashMap.scala @@ -44,7 +44,7 @@ class HashMap[A, B] extends Map[A,B] with mutable.HashTable[A] { def empty[C]: Map[A, C] = new EmptyMap[A, C] - def get(key: A): Option[B] = { + def get(key: A): Option[B] = synchronized { var m = this var cnt = 0 while (m.later != null) { @@ -58,7 +58,7 @@ class HashMap[A, B] extends Map[A,B] with mutable.HashTable[A] { else Some(getValue(e)) } - def update [B1 >: B](key: A, value: B1): Map[A, B1] = { + def update [B1 >: B](key: A, value: B1): Map[A, B1] = synchronized { makeCopyIfUpdated() val e = findEntry(key) if (e == null) { @@ -71,7 +71,7 @@ class HashMap[A, B] extends Map[A,B] with mutable.HashTable[A] { later } - def - (key: A): Map[A, B] = { + def - (key: A): Map[A, B] = synchronized { makeCopyIfUpdated() val e = findEntry(key) if (e == null) this @@ -82,7 +82,7 @@ class HashMap[A, B] extends Map[A,B] with mutable.HashTable[A] { } } - override def size: int = { + override def size: int = synchronized { var m = this var cnt = 0 var s = tableSize @@ -95,7 +95,7 @@ class HashMap[A, B] extends Map[A,B] with mutable.HashTable[A] { s } - def elements = { + def elements = synchronized { makeCopyIfUpdated() entries map {e => (e.key, getValue(e))} } diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala index cb71b58b9..6af493b0e 100644 --- a/src/library/scala/collection/immutable/HashSet.scala +++ b/src/library/scala/collection/immutable/HashSet.scala @@ -39,7 +39,7 @@ class HashSet[A] extends Set[A] with mutable.FlatHashTable[A] { def empty[C]: Set[C] = new EmptySet[C] - def contains(elem: A): Boolean = { + def contains(elem: A): Boolean = synchronized { var m = this var cnt = 0 while (m.later != null) { @@ -51,7 +51,7 @@ class HashSet[A] extends Set[A] with mutable.FlatHashTable[A] { m.containsEntry(elem) } - def + (elem: A): Set[A] = { + def + (elem: A): Set[A] = synchronized { makeCopyIfUpdated() if (containsEntry(elem)) this else { @@ -61,7 +61,7 @@ class HashSet[A] extends Set[A] with mutable.FlatHashTable[A] { } } - def - (elem: A): Set[A] = { + def - (elem: A): Set[A] = synchronized { makeCopyIfUpdated() if (!containsEntry(elem)) this else { @@ -71,7 +71,7 @@ class HashSet[A] extends Set[A] with mutable.FlatHashTable[A] { } } - override def size: Int = { + override def size: Int = synchronized { var m = this var cnt = 0 var s = tableSize @@ -84,7 +84,7 @@ class HashSet[A] extends Set[A] with mutable.FlatHashTable[A] { s } - override def elements = { + override def elements = synchronized { makeCopyIfUpdated() super.elements }