Skip to content

Commit 88de965

Browse files
authored
Merge pull request scala/scala#9192 from retronym/t12140-map-merge
Fix NPE regression in immutable.HashMap.merge
2 parents f97da22 + deb32b1 commit 88de965

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

library/src/scala/collection/immutable/HashMap.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
342342
}
343343

344344
@deprecatedInheritance("This class will be made final in a future release.", "2.12.2")
345-
class HashMap1[A,+B](private[collection] val key: A, private[collection] val hash: Int, private[collection] val value: (B @uV), private[collection] var kv: (A,B @uV)) extends HashMap[A,B] {
345+
class HashMap1[A,+B](private[collection] val key: A, private[collection] val hash: Int, private[collection] val value: (B @uV), private[this] var kvOrNull: (A,B @uV)) extends HashMap[A,B] {
346346
override def size = 1
347347

348348
private[collection] def getKey = key
@@ -394,8 +394,8 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
394394
override def foreach[U](f: ((A, B)) => U): Unit = f(ensurePair)
395395
override private[immutable] def foreachEntry[U](f: (A, B) => U): Unit = f(key, value)
396396
// this method may be called multiple times in a multi-threaded environment, but that's ok
397-
private[HashMap] def ensurePair: (A, B) = if (kv ne null) kv else {
398-
kv = (key, value); kv
397+
private[HashMap] def ensurePair: (A, B) = if (kvOrNull ne null) kvOrNull else {
398+
kvOrNull = (key, value); kvOrNull
399399
}
400400

401401
protected[HashMap] override def merge0[B1 >: B](that: HashMap[A, B1], level: Int, merger: Merger[A, B1]): HashMap[A, B1] = {
@@ -405,10 +405,10 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
405405
else if (this.hash == hm1.hash && this.key == hm1.key)
406406
if (merger eq HashMap.defaultMerger) this
407407
else if (merger eq HashMap.defaultMerger.invert) hm1
408-
else this.updated0(hm1.key, hm1.hash, level, hm1.value, hm1.kv, merger)
409-
else this.updated0(hm1.key, hm1.hash, level, hm1.value, hm1.kv, merger)
408+
else this.updated0(hm1.key, hm1.hash, level, hm1.value, hm1.ensurePair, merger)
409+
else this.updated0(hm1.key, hm1.hash, level, hm1.value, hm1.ensurePair, merger)
410410
case _ =>
411-
that.updated0(key, hash, level, value, kv, merger.invert)
411+
that.updated0(key, hash, level, value, ensurePair, merger.invert)
412412
}
413413
}
414414

@@ -504,7 +504,7 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
504504
hm.merge0(this, level, merger.invert)
505505
case h1: HashMap1[A, B1] =>
506506
if (h1.hash != hash) makeHashTrieMap(hash, this, h1.hash, h1, level, size + 1)
507-
else updated0(h1.key, h1.hash, level, h1.value, h1.kv, merger)
507+
else updated0(h1.key, h1.hash, level, h1.value, h1.ensurePair, merger)
508508
case c: HashMapCollision1[A, B1] =>
509509
if (c.hash != hash) makeHashTrieMap(hash, this, c.hash, c, level, c.size + size)
510510
else if (merger.retainIdentical && (c eq this)) this
@@ -760,7 +760,7 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
760760

761761
protected[HashMap] override def merge0[B1 >: B](that: HashMap[A, B1], level: Int, merger: Merger[A, B1]): HashMap[A, B1] = that match {
762762
case hm: HashMap1[A, B1] =>
763-
this.updated0(hm.key, hm.hash, level, hm.value.asInstanceOf[B1], hm.kv, merger)
763+
this.updated0(hm.key, hm.hash, level, hm.value.asInstanceOf[B1], hm.ensurePair, merger)
764764
case that: HashTrieMap[A, B1] =>
765765
def mergeMaybeSubset(larger: HashTrieMap[A, B1], smaller: HashTrieMap[A, B1], merger: Merger[A, B1]):HashTrieMap[A, B1] = {
766766
var resultElems: Array[HashMap[A, B1]] = null

0 commit comments

Comments
 (0)