diff --git a/compiler/src/dotty/tools/dotc/core/Constraint.scala b/compiler/src/dotty/tools/dotc/core/Constraint.scala index a6c21c0d1ec0..ffa5082bf5b2 100644 --- a/compiler/src/dotty/tools/dotc/core/Constraint.scala +++ b/compiler/src/dotty/tools/dotc/core/Constraint.scala @@ -3,7 +3,6 @@ package dotc package core import Types._, Contexts._, Symbols._ -import util.SimpleMap import collection.mutable import printing.{Printer, Showable} import printing.Texts._ diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala index 247c028ae221..00b9507bf723 100644 --- a/compiler/src/dotty/tools/dotc/core/Contexts.scala +++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala @@ -17,7 +17,7 @@ import Comments._ import util.Positions._ import ast.Trees._ import ast.untpd -import util.{FreshNameCreator, SimpleMap, SourceFile, NoSource} +import util.{FreshNameCreator, SimpleIdentityMap, SourceFile, NoSource} import typer.{Implicits, ImplicitRunInfo, ImportInfo, Inliner, NamerContextOps, SearchHistory, TypeAssigner, Typer} import Implicits.ContextualImplicits import config.Settings._ @@ -694,14 +694,14 @@ object Contexts { implicit val ctx: Context = initctx } - class GADTMap(initBounds: SimpleMap[Symbol, TypeBounds]) extends util.DotClass { + class GADTMap(initBounds: SimpleIdentityMap[Symbol, TypeBounds]) extends util.DotClass { private var myBounds = initBounds def setBounds(sym: Symbol, b: TypeBounds): Unit = myBounds = myBounds.updated(sym, b) def bounds = myBounds } - @sharable object EmptyGADTMap extends GADTMap(SimpleMap.Empty) { + @sharable object EmptyGADTMap extends GADTMap(SimpleIdentityMap.Empty) { override def setBounds(sym: Symbol, b: TypeBounds) = unsupported("EmptyGADTMap.setBounds") } } diff --git a/compiler/src/dotty/tools/dotc/core/Names.scala b/compiler/src/dotty/tools/dotc/core/Names.scala index 17a64f471084..44db38abdddc 100644 --- a/compiler/src/dotty/tools/dotc/core/Names.scala +++ b/compiler/src/dotty/tools/dotc/core/Names.scala @@ -12,11 +12,8 @@ import StdNames.str import Designators._ import util.Chars.isIdentifierStart import collection.IndexedSeqOptimized -import collection.generic.CanBuildFrom -import collection.mutable.{ Builder, StringBuilder, AnyRefMap } -import collection.immutable.WrappedString -import collection.generic.CanBuildFrom -import util.{DotClass, SimpleMap} +import collection.immutable +import util.{DotClass} import config.Config import java.util.HashMap @@ -193,24 +190,24 @@ object Names { def underlying: TermName = unsupported("underlying") @sharable // because of synchronized block in `and` - private var derivedNames: AnyRef /* SimpleMap | j.u.HashMap */ = - SimpleMap.Empty[NameInfo] + private var derivedNames: AnyRef /* immutable.Map[NameInfo, DerivedName] | j.u.HashMap */ = + immutable.Map.empty[NameInfo, DerivedName] private def getDerived(info: NameInfo): DerivedName /* | Null */= derivedNames match { - case derivedNames: SimpleMap[NameInfo, DerivedName] @unchecked => - derivedNames(info) + case derivedNames: immutable.AbstractMap[NameInfo, DerivedName] @unchecked => + if (derivedNames.contains(info)) derivedNames(info) else null case derivedNames: HashMap[NameInfo, DerivedName] @unchecked => derivedNames.get(info) } private def putDerived(info: NameInfo, name: DerivedName): name.type = { derivedNames match { - case derivedNames: SimpleMap[NameInfo, DerivedName] @unchecked => + case derivedNames: immutable.Map[NameInfo, DerivedName] @unchecked => if (derivedNames.size < 4) this.derivedNames = derivedNames.updated(info, name) else { val newMap = new HashMap[NameInfo, DerivedName] - derivedNames.foreachBinding(newMap.put(_, _)) + derivedNames.foreach { case (k, v) => newMap.put(k, v) } newMap.put(info, name) this.derivedNames = newMap } diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala index 279e545cc2bd..609eb743979e 100644 --- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala @@ -3,7 +3,7 @@ package dotc package core import Types._, Contexts._, Symbols._, Decorators._ -import util.SimpleMap +import util.SimpleIdentityMap import collection.mutable import printing.{Printer, Showable} import printing.Texts._ @@ -14,7 +14,7 @@ import annotation.tailrec object OrderingConstraint { - type ArrayValuedMap[T] = SimpleMap[TypeLambda, Array[T]] + type ArrayValuedMap[T] = SimpleIdentityMap[TypeLambda, Array[T]] /** The type of `OrderingConstraint#boundsMap` */ type ParamBounds = ArrayValuedMap[Type] diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index 441faacebe82..c886adeebbc1 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -13,7 +13,7 @@ import Decorators.SymbolIteratorDecorator import ast._ import annotation.tailrec import CheckRealizable._ -import util.SimpleMap +import util.SimpleIdentityMap import util.Stats import java.util.WeakHashMap import config.Config @@ -1254,7 +1254,7 @@ object SymDenotations { // ----- caches ------------------------------------------------------- private[this] var myTypeParams: List[TypeSymbol] = null - private[this] var fullNameCache: SimpleMap[QualifiedNameKind, Name] = SimpleMap.Empty + private[this] var fullNameCache: SimpleIdentityMap[QualifiedNameKind, Name] = SimpleIdentityMap.Empty private[this] var myMemberCache: LRUCache[Name, PreDenotation] = null private[this] var myMemberCachePeriod: Period = Nowhere @@ -2041,7 +2041,7 @@ object SymDenotations { } private class MemberNamesImpl(createdAt: Period) extends InheritedCacheImpl(createdAt) with MemberNames { - private[this] var cache: SimpleMap[NameFilter, Set[Name]] = SimpleMap.Empty + private[this] var cache: SimpleIdentityMap[NameFilter, Set[Name]] = SimpleIdentityMap.Empty final def isValid(implicit ctx: Context): Boolean = cache != null && isValidAt(ctx.phase) @@ -2054,7 +2054,7 @@ object SymDenotations { */ def invalidate(): Unit = if (cache != null) - if (locked) cache = SimpleMap.Empty + if (locked) cache = SimpleIdentityMap.Empty else { cache = null invalidateDependents() diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 69d1c2a4454a..a2f09aa35987 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -6,7 +6,7 @@ import Types._, Contexts._, Symbols._, Flags._, Names._, NameOps._, Denotations. import Decorators._ import StdNames.{nme, tpnme} import collection.mutable -import util.{Stats, DotClass, SimpleMap} +import util.{Stats, DotClass} import config.Config import config.Printers.{typr, constr, subtyping, noPrinter} import TypeErasure.{erasedLub, erasedGlb} diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index 2b0be7e6e19e..9c65ab9b94af 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -13,7 +13,7 @@ import StdNames._ import Annotations._ import annotation.tailrec import config.Config -import util.{SimpleMap, Property} +import util.Property import collection.mutable import ast.tpd._ diff --git a/compiler/src/dotty/tools/dotc/core/TyperState.scala b/compiler/src/dotty/tools/dotc/core/TyperState.scala index 7b72c371c2c1..b804d242edd7 100644 --- a/compiler/src/dotty/tools/dotc/core/TyperState.scala +++ b/compiler/src/dotty/tools/dotc/core/TyperState.scala @@ -5,7 +5,7 @@ package core import Types._ import Flags._ import Contexts._ -import util.{SimpleMap, DotClass} +import util.{SimpleIdentityMap, DotClass} import reporting._ import printing.{Showable, Printer} import printing.Texts._ @@ -24,7 +24,7 @@ class TyperState(previous: TyperState /* | Null */) extends DotClass with Showab def setReporter(reporter: Reporter): this.type = { myReporter = reporter; this } private var myConstraint: Constraint = - if (previous == null) new OrderingConstraint(SimpleMap.Empty, SimpleMap.Empty, SimpleMap.Empty) + if (previous == null) new OrderingConstraint(SimpleIdentityMap.Empty, SimpleIdentityMap.Empty, SimpleIdentityMap.Empty) else previous.constraint def constraint = myConstraint diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 54c3113ddfe0..15ea7c1479cf 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -19,7 +19,7 @@ import Periods._ import Designators._ import util.Positions.{Position, NoPosition} import util.Stats._ -import util.{DotClass, SimpleMap} +import util.DotClass import reporting.diagnostic.Message import reporting.diagnostic.messages.CyclicReferenceInvolving import ast.tpd._ @@ -2599,7 +2599,32 @@ object Types { final override def toString = s"$prefixString($paramNames, $paramInfos, $resType)" } - trait HKLambda extends LambdaType + abstract class HKLambda extends CachedProxyType with LambdaType { + final override def underlying(implicit ctx: Context) = resType + + final override def computeHash = doHash(paramNames, resType, paramInfos) + + final override def equals(that: Any) = that match { + case that: HKLambda => + paramNames == that.paramNames && + paramInfos == that.paramInfos && + resType == that.resType && + companion.eq(that.companion) + case _ => + false + } + + final override def eql(that: Type) = that match { + case that: HKLambda => + paramNames.equals(that.paramNames) && + paramInfos.equals(that.paramInfos) && + resType.equals(that.resType) && + companion.eq(that.companion) + case _ => + false + } + } + trait MethodOrPoly extends LambdaType with MethodicType trait TermLambda extends LambdaType { thisLambdaType => @@ -2909,7 +2934,7 @@ object Types { */ class HKTypeLambda(val paramNames: List[TypeName])( paramInfosExp: HKTypeLambda => List[TypeBounds], resultTypeExp: HKTypeLambda => Type) - extends UncachedProxyType with HKLambda with TypeLambda { + extends HKLambda with TypeLambda { type This = HKTypeLambda def companion = HKTypeLambda @@ -2919,8 +2944,6 @@ object Types { assert(resType.isInstanceOf[TermType], this) assert(paramNames.nonEmpty) - final override def underlying(implicit ctx: Context) = resType - protected def prefixString = "HKTypeLambda" } diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 27b685a19299..d330327b5c15 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -21,7 +21,7 @@ import ErrorReporting.errorTree import annotation.unchecked import util.Positions._ -import util.{SimpleMap, Stats} +import util.Stats import util.common._ import transform.SymUtils._ import Decorators._ diff --git a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala index 682a1b2922c8..1870ca360edc 100644 --- a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala +++ b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala @@ -6,7 +6,7 @@ import ast.{tpd, untpd} import ast.Trees._ import core._ import printing.{Printer, Showable} -import util.SimpleMap +import util.SimpleIdentityMap import Symbols._, Names._, Denotations._, Types._, Contexts._, StdNames._, Flags._ import Decorators.StringInterpolators @@ -52,7 +52,7 @@ class ImportInfo(symf: Context => Symbol, val selectors: List[untpd.Tree], def excluded: Set[TermName] = { ensureInitialized(); myExcluded } /** A mapping from renamed to original names */ - def reverseMapping: SimpleMap[TermName, TermName] = { ensureInitialized(); myMapped } + def reverseMapping: SimpleIdentityMap[TermName, TermName] = { ensureInitialized(); myMapped } /** The original names imported by-name before renaming */ def originals: Set[TermName] = { ensureInitialized(); myOriginals } @@ -61,14 +61,14 @@ class ImportInfo(symf: Context => Symbol, val selectors: List[untpd.Tree], def isWildcardImport = { ensureInitialized(); myWildcardImport } private var myExcluded: Set[TermName] = null - private var myMapped: SimpleMap[TermName, TermName] = null + private var myMapped: SimpleIdentityMap[TermName, TermName] = null private var myOriginals: Set[TermName] = null private var myWildcardImport: Boolean = false /** Compute info relating to the selector list */ private def ensureInitialized(): Unit = if (myExcluded == null) { myExcluded = Set() - myMapped = SimpleMap.Empty + myMapped = SimpleIdentityMap.Empty myOriginals = Set() def recur(sels: List[untpd.Tree]): Unit = sels match { case sel :: sels1 => diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala index ee5995d3f0ee..295962162840 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala @@ -11,7 +11,7 @@ import Scopes._ import ProtoTypes._ import annotation.unchecked import util.Positions._ -import util.{Stats, SimpleMap} +import util.{Stats, SimpleIdentityMap} import util.common._ import Decorators._ import Uniques._ @@ -286,7 +286,7 @@ object Inferencing { result } - type VarianceMap = SimpleMap[TypeVar, Integer] + type VarianceMap = SimpleIdentityMap[TypeVar, Integer] /** All occurrences of type vars in this type that satisfy predicate * `include` mapped to their variances (-1/0/1) in this type, where @@ -350,7 +350,7 @@ object Inferencing { if (vmap1 eq vmap) vmap else propagate(vmap1) } - propagate(accu(SimpleMap.Empty, tp)) + propagate(accu(SimpleIdentityMap.Empty, tp)) } } diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index e7fe53bff0c6..02c281245b08 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -11,7 +11,7 @@ import Constants._ import Scopes._ import annotation.unchecked import util.Positions._ -import util.{Stats, SimpleMap} +import util.{Stats, SimpleIdentityMap} import util.common._ import Decorators._ import Uniques._ @@ -179,10 +179,10 @@ object ProtoTypes { override def resultType(implicit ctx: Context) = resType /** A map in which typed arguments can be stored to be later integrated in `typedArgs`. */ - private var myTypedArg: SimpleMap[untpd.Tree, Tree] = SimpleMap.Empty + private var myTypedArg: SimpleIdentityMap[untpd.Tree, Tree] = SimpleIdentityMap.Empty /** A map recording the typer states in which arguments stored in myTypedArg were typed */ - private var evalState: SimpleMap[untpd.Tree, TyperState] = SimpleMap.Empty + private var evalState: SimpleIdentityMap[untpd.Tree, TyperState] = SimpleIdentityMap.Empty def isMatchedBy(tp: Type)(implicit ctx: Context) = typer.isApplicable(tp, Nil, typedArgs, resultType) diff --git a/compiler/src/dotty/tools/dotc/util/SimpleMap.scala b/compiler/src/dotty/tools/dotc/util/SimpleMap.scala index b8668d7e439d..dbd5b1d1abbb 100644 --- a/compiler/src/dotty/tools/dotc/util/SimpleMap.scala +++ b/compiler/src/dotty/tools/dotc/util/SimpleMap.scala @@ -2,13 +2,13 @@ package dotty.tools.dotc.util import collection.mutable.ListBuffer -abstract class SimpleMap[K <: AnyRef, +V >: Null <: AnyRef] extends (K => V) { +abstract class SimpleIdentityMap[K <: AnyRef, +V >: Null <: AnyRef] extends (K => V) { def size: Int def apply(k: K): V - def remove(k: K): SimpleMap[K, V] - def updated[V1 >: V <: AnyRef](k: K, v: V1): SimpleMap[K, V1] + def remove(k: K): SimpleIdentityMap[K, V] + def updated[V1 >: V <: AnyRef](k: K, v: V1): SimpleIdentityMap[K, V1] def contains(k: K): Boolean = apply(k) != null - def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1): SimpleMap[K, V1] + def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1): SimpleIdentityMap[K, V1] def foreachBinding(f: (K, V) => Unit): Unit def map2[T](f: (K, V) => T): List[T] = { val buf = new ListBuffer[T] @@ -23,11 +23,11 @@ abstract class SimpleMap[K <: AnyRef, +V >: Null <: AnyRef] extends (K => V) { } } -object SimpleMap { +object SimpleIdentityMap { private val CompactifyThreshold = 4 - private object myEmpty extends SimpleMap[AnyRef, Null] { + private object myEmpty extends SimpleIdentityMap[AnyRef, Null] { def size = 0 def apply(k: AnyRef) = null def remove(k: AnyRef) = this @@ -36,18 +36,18 @@ object SimpleMap { def foreachBinding(f: (AnyRef, Null) => Unit) = () } - def Empty[K <: AnyRef] = myEmpty.asInstanceOf[SimpleMap[K, Null]] + def Empty[K <: AnyRef] = myEmpty.asInstanceOf[SimpleIdentityMap[K, Null]] - class Map1[K <: AnyRef, +V >: Null <: AnyRef] (k1: K, v1: V) extends SimpleMap[K, V] { + class Map1[K <: AnyRef, +V >: Null <: AnyRef] (k1: K, v1: V) extends SimpleIdentityMap[K, V] { def size = 1 def apply(k: K) = - if (k == k1) v1 + if (k eq k1) v1 else null def remove(k: K) = - if (k == k1) Empty.asInstanceOf[SimpleMap[K, V]] + if (k eq k1) Empty.asInstanceOf[SimpleIdentityMap[K, V]] else this def updated[V1 >: V <: AnyRef](k: K, v: V1) = - if (k == k1) new Map1(k, v) + if (k eq k1) new Map1(k, v) else new Map2(k1, v1, k, v) def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = { val w1 = f(k1, v1) @@ -56,19 +56,19 @@ object SimpleMap { def foreachBinding(f: (K, V) => Unit) = f(k1, v1) } - class Map2[K <: AnyRef, +V >: Null <: AnyRef] (k1: K, v1: V, k2: K, v2: V) extends SimpleMap[K, V] { + class Map2[K <: AnyRef, +V >: Null <: AnyRef] (k1: K, v1: V, k2: K, v2: V) extends SimpleIdentityMap[K, V] { def size = 2 def apply(k: K) = - if (k == k1) v1 - else if (k == k2) v2 + if (k eq k1) v1 + else if (k eq k2) v2 else null def remove(k: K) = - if (k == k1) new Map1(k2, v2) - else if (k == k2) new Map1(k1, v1) + if (k eq k1) new Map1(k2, v2) + else if (k eq k2) new Map1(k1, v1) else this def updated[V1 >: V <: AnyRef](k: K, v: V1) = - if (k == k1) new Map2(k, v, k2, v2) - else if (k == k2) new Map2(k1, v1, k, v) + if (k eq k1) new Map2(k, v, k2, v2) + else if (k eq k2) new Map2(k1, v1, k, v) else new Map3(k1, v1, k2, v2, k, v) def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = { val w1 = f(k1, v1); val w2 = f(k2, v2) @@ -78,22 +78,22 @@ object SimpleMap { def foreachBinding(f: (K, V) => Unit) = { f(k1, v1); f(k2, v2) } } - class Map3[K <: AnyRef, +V >: Null <: AnyRef] (k1: K, v1: V, k2: K, v2: V, k3: K, v3: V) extends SimpleMap[K, V] { + class Map3[K <: AnyRef, +V >: Null <: AnyRef] (k1: K, v1: V, k2: K, v2: V, k3: K, v3: V) extends SimpleIdentityMap[K, V] { def size = 3 def apply(k: K) = - if (k == k1) v1 - else if (k == k2) v2 - else if (k == k3) v3 + if (k eq k1) v1 + else if (k eq k2) v2 + else if (k eq k3) v3 else null def remove(k: K) = - if (k == k1) new Map2(k2, v2, k3, v3) - else if (k == k2) new Map2(k1, v1, k3, v3) - else if (k == k3) new Map2(k1, v1, k2, v2) + if (k eq k1) new Map2(k2, v2, k3, v3) + else if (k eq k2) new Map2(k1, v1, k3, v3) + else if (k eq k3) new Map2(k1, v1, k2, v2) else this def updated[V1 >: V <: AnyRef](k: K, v: V1) = - if (k == k1) new Map3(k, v, k2, v2, k3, v3) - else if (k == k2) new Map3(k1, v1, k, v, k3, v3) - else if (k == k3) new Map3(k1, v1, k2, v2, k, v) + if (k eq k1) new Map3(k, v, k2, v2, k3, v3) + else if (k eq k2) new Map3(k1, v1, k, v, k3, v3) + else if (k eq k3) new Map3(k1, v1, k2, v2, k, v) else new Map4(k1, v1, k2, v2, k3, v3, k, v) def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = { val w1 = f(k1, v1); val w2 = f(k2, v2); val w3 = f(k3, v3) @@ -103,25 +103,25 @@ object SimpleMap { def foreachBinding(f: (K, V) => Unit) = { f(k1, v1); f(k2, v2); f(k3, v3) } } - class Map4[K <: AnyRef, +V >: Null <: AnyRef] (k1: K, v1: V, k2: K, v2: V, k3: K, v3: V, k4: K, v4: V) extends SimpleMap[K, V] { + class Map4[K <: AnyRef, +V >: Null <: AnyRef] (k1: K, v1: V, k2: K, v2: V, k3: K, v3: V, k4: K, v4: V) extends SimpleIdentityMap[K, V] { def size = 4 def apply(k: K) = - if (k == k1) v1 - else if (k == k2) v2 - else if (k == k3) v3 - else if (k == k4) v4 + if (k eq k1) v1 + else if (k eq k2) v2 + else if (k eq k3) v3 + else if (k eq k4) v4 else null def remove(k: K) = - if (k == k1) new Map3(k2, v2, k3, v3, k4, v4) - else if (k == k2) new Map3(k1, v1, k3, v3, k4, v4) - else if (k == k3) new Map3(k1, v1, k2, v2, k4, v4) - else if (k == k4) new Map3(k1, v1, k2, v2, k3, v3) + if (k eq k1) new Map3(k2, v2, k3, v3, k4, v4) + else if (k eq k2) new Map3(k1, v1, k3, v3, k4, v4) + else if (k eq k3) new Map3(k1, v1, k2, v2, k4, v4) + else if (k eq k4) new Map3(k1, v1, k2, v2, k3, v3) else this def updated[V1 >: V <: AnyRef](k: K, v: V1) = - if (k == k1) new Map4(k, v, k2, v2, k3, v3, k4, v4) - else if (k == k2) new Map4(k1, v1, k, v, k3, v3, k4, v4) - else if (k == k3) new Map4(k1, v1, k2, v2, k, v, k4, v4) - else if (k == k4) new Map4(k1, v1, k2, v2, k3, v3, k, v) + if (k eq k1) new Map4(k, v, k2, v2, k3, v3, k4, v4) + else if (k eq k2) new Map4(k1, v1, k, v, k3, v3, k4, v4) + else if (k eq k3) new Map4(k1, v1, k2, v2, k, v, k4, v4) + else if (k eq k4) new Map4(k1, v1, k2, v2, k3, v3, k, v) else new MapMore(Array[AnyRef](k1, v1, k2, v2, k3, v3, k4, v4, k, v)) def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = { val w1 = f(k1, v1); val w2 = f(k2, v2); val w3 = f(k3, v3); val w4 = f(k4, v4) @@ -131,7 +131,7 @@ object SimpleMap { def foreachBinding(f: (K, V) => Unit) = { f(k1, v1); f(k2, v2); f(k3, v3); f(k4, v4) } } - class MapMore[K <: AnyRef, +V >: Null <: AnyRef](bindings: Array[AnyRef]) extends SimpleMap[K, V] { + class MapMore[K <: AnyRef, +V >: Null <: AnyRef](bindings: Array[AnyRef]) extends SimpleIdentityMap[K, V] { private def key(i: Int): K = bindings(i).asInstanceOf[K] private def value(i: Int): V = bindings(i + 1).asInstanceOf[V] @@ -146,12 +146,12 @@ object SimpleMap { null } - def remove(k: K): SimpleMap[K, V] = { + def remove(k: K): SimpleIdentityMap[K, V] = { var i = 0 while (i < bindings.length) { if (bindings(i) eq k) return { if (size == CompactifyThreshold) { - var m: SimpleMap[K, V] = Empty[K] + var m: SimpleIdentityMap[K, V] = Empty[K] for (j <- 0 until bindings.length by 2) if (j != i) m = m.updated(key(j), value(j)) m @@ -167,7 +167,7 @@ object SimpleMap { this } - def updated[V1 >: V <: AnyRef](k: K, v: V1): SimpleMap[K, V] = { + def updated[V1 >: V <: AnyRef](k: K, v: V1): SimpleIdentityMap[K, V] = { var i = 0 while (i < bindings.length) { if (bindings(i) eq k)