Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MatchError in immutable.HashMap.merged #9895

Closed
scabug opened this issue Aug 19, 2016 · 13 comments
Closed

MatchError in immutable.HashMap.merged #9895

scabug opened this issue Aug 19, 2016 · 13 comments

Comments

@scabug
Copy link

scabug commented Aug 19, 2016

I get following error when run a code below:

Exception in thread "main" scala.MatchError: (null,null) (of class scala.Tuple2)
	at HashMapError$.HashMapError$$$anonfun$2(HashMapError.scala:13)
	at HashMapError$lambda$$merge2$1.apply(HashMapError.scala:13)
	at HashMapError$lambda$$merge2$1.apply(HashMapError.scala:13)
	at scala.collection.immutable.HashMap$$anon$2$$anon$3.apply(HashMap.scala:150)
	at scala.collection.immutable.HashMap$HashMap1.updated0(HashMap.scala:200)
	at scala.collection.immutable.HashMap$HashMap1.merge0(HashMap.scala:225)
	at scala.collection.immutable.HashMap$HashTrieMap.merge0(HashMap.scala:488)
	at scala.collection.immutable.HashMap$HashTrieMap.merge0(HashMap.scala:488)
	at scala.collection.immutable.HashMap$HashTrieMap.merge0(HashMap.scala:488)
	at scala.collection.immutable.HashMap.merged(HashMap.scala:117)
	at HashMapError$.merge2(HashMapError.scala:13)
        ...
import scala.collection.immutable.HashMap

object HashMapError extends App {
  def merge[K, V](m1: HashMap[K, Seq[V]], m2: HashMap[K, Seq[V]]): HashMap[K, Seq[V]] =
    m2.foldLeft(m1) { case (m, (k, v2)) =>
      m.updated(k, m.get(k) match {
        case Some(v1) => v1 ++ v2
        case None => v2
      })
    }

  def merge2[K, V](m1: HashMap[K, Seq[V]], m2: HashMap[K, Seq[V]]): HashMap[K, Seq[V]] =
    m1.merged(m2) {
      case ((k, v1), (_, v2)) => (k, v1 ++ v2)
    }

  def diff[K, V](m1: HashMap[K, Seq[V]], m2: HashMap[K, Seq[V]]): HashMap[K, Seq[V]] =
    m2.foldLeft(m1) { case (m, (k, v2)) =>
      m.get(k) match {
        case Some(v1) =>
          val v = v1.diff(v2)
          if (v.isEmpty) m - k
          else m.updated(k, v)
        case None => m
      }
    }

  def create(first: Int, limit: Int): HashMap[String, Seq[Int]] = {
    var m = HashMap[String, Seq[Int]]()
    (first to limit).foreach { i =>
      m = m.updated(i.toString, (0 to i).toSeq)
    }
    m
  }

  var m1 = create(1, 10000)
  val m2 = create(1, 1000)
  (1 to 100).foreach { _ =>
    m1 = merge2(m1, m2)
    m1 = diff(m1, m2)
  }
}

But it works fine if instead of merge2 I call merge function.

@scabug
Copy link
Author

scabug commented Aug 19, 2016

Imported From: https://issues.scala-lang.org/browse/SI-9895?orig=1
Reporter: Andriy Plokhotnyuk (plokhotnyuk)
Affected Versions: 2.11.8
See #9688

@scabug
Copy link
Author

scabug commented Aug 19, 2016

Andrey Ivanov (a.nigredo-at-gmail.com) said:
The same for me

@scabug
Copy link
Author

scabug commented Aug 19, 2016

Yaroslav Ulanovych (yarulan) said (edited by @SethTisue on Aug 19, 2016 4:02:31 PM UTC):
Reduced to

  import scala.collection.immutable.HashMap
  val m1 = HashMap[String, Seq[Int]]().updated("0", Seq(0))
  val m2 = HashMap[String, Seq[Int]]().updated("0", Seq(1))
  // println(m1)
  // println(m2)
  m1.merged(m2) {
    case ((k, v1), (_, v2)) => (k, v1 ++ v2)
  }

Exception disappears if uncomment println statements

@scabug
Copy link
Author

scabug commented Aug 19, 2016

@SethTisue said:
[~yarulan]: I don't get an exception when I run your minimization on 2.11.8 (Java 1.8.0_102 on Mac OS X).

@scabug
Copy link
Author

scabug commented Aug 19, 2016

Yaroslav Ulanovych (yarulan) said (edited on Aug 19, 2016 4:54:08 PM UTC):
@SethTisue: Exception isn't thrown when running from repl, try to run as regular app.

@scabug
Copy link
Author

scabug commented Aug 19, 2016

Andriy Plokhotnyuk (plokhotnyuk) said:
Sorry, I hoped that it was regression.
But now I see that it can be reproduced with Scala 2.10.1 where HashMap.merged with current signature was introduced:

07:37:12 ~/Downloads/scala-2.9.3/bin$ cd ../../scala-2.10.1/bin
07:37:16 ~/Downloads/scala-2.10.1/bin$ ./scala
Welcome to Scala version 2.10.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_74).
Type in expressions to have them evaluated.
Type :help for more information.

scala> [init] error: error while loading AnnotatedElement, class file '/usr/lib/jvm/jdk1.8.0_74/jre/lib/rt.jar(java/lang/reflect/AnnotatedElement.class)' is broken
(class java.lang.RuntimeException/bad constant pool tag 18 at byte 76)
[init] error: error while loading CharSequence, class file '/usr/lib/jvm/jdk1.8.0_74/jre/lib/rt.jar(java/lang/CharSequence.class)' is broken
(class java.lang.RuntimeException/bad constant pool tag 18 at byte 10)
:paste
// Entering paste mode (ctrl-D to finish)

import scala.collection.immutable.HashMap
val m1 = HashMap[String, Seq[Int]]().updated("0", Seq(0))
val m2 = HashMap[String, Seq[Int]]().updated("0", Seq(1))
// println(m1)
// println(m2)
m1.merged(m2) {
  case ((k, v1), (_, v2)) => (k, v1 ++ v2)
}

// Exiting paste mode, now interpreting.

scala.MatchError: (null,null) (of class scala.Tuple2)
	at $anonfun$1.apply(<console>:14)
	at $anonfun$1.apply(<console>:14)
	at scala.collection.immutable.HashMap$$anon$2$$anon$3.apply(HashMap.scala:139)
	at scala.collection.immutable.HashMap$HashMap1.updated0(HashMap.scala:206)
	at scala.collection.immutable.HashMap$HashMap1.merge0(HashMap.scala:228)
	at scala.collection.immutable.HashMap.merged(HashMap.scala:106)

@scabug
Copy link
Author

scabug commented Aug 19, 2016

Andriy Plokhotnyuk (plokhotnyuk) said:
It is reproducible for me with latest JDK 8:

08:02:51 ~$ java -version
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
08:02:55 ~$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_102).
Type in expressions for evaluation. Or try :help.

scala> :paste
// Entering paste mode (ctrl-D to finish)

import scala.collection.immutable.HashMap
val m1 = HashMap[String, Seq[Int]]().updated("0", Seq(0))
val m2 = HashMap[String, Seq[Int]]().updated("0", Seq(1))
// println(m1)
// println(m2)
m1.merged(m2) {
  case ((k, v1), (_, v2)) => (k, v1 ++ v2)
}

// Exiting paste mode, now interpreting.

scala.MatchError: (null,null) (of class scala.Tuple2)
  at $anonfun$1.apply(<console>:18)
  at $anonfun$1.apply(<console>:18)
  at scala.collection.immutable.HashMap$$anon$2$$anon$3.apply(HashMap.scala:150)
  at scala.collection.immutable.HashMap$HashMap1.updated0(HashMap.scala:200)
  at scala.collection.immutable.HashMap$HashMap1.merge0(HashMap.scala:225)
  at scala.collection.immutable.HashMap.merged(HashMap.scala:117)
  ... 37 elided

@scabug
Copy link
Author

scabug commented Aug 19, 2016

@SethTisue said (edited on Aug 30, 2016 2:02:21 AM UTC):
yup, reproducible for me now in the REPL if I use :paste. strange it would be sensitive to that

@scabug
Copy link
Author

scabug commented Aug 19, 2016

@som-snytt said:
No repro on 2.12.0-M5. :(

HashMap.toString uses TraversableOnce that just iterates building the string. (Repl also prints values.)

@scabug scabug closed this as completed Aug 30, 2016
@scabug
Copy link
Author

scabug commented Aug 30, 2016

@SethTisue said:
Closing since not reproducible in 2.12. The door remains open for someone to figure out when/how it got fixed and try to backport to 2.11.x, though.

@scabug
Copy link
Author

scabug commented Aug 30, 2016

@som-snytt said:
The linked ticket shows the fix on 2.11.9.

Many repros have proved sensitive to REPL because of toString effects. Recently ameliorated was the only puzzler with bleep in the title, http://scalapuzzlers.com/#pzzlr-025

Instead of using the paste command, you can paste at the prompt and then run silent, run deep:

scala> m1.merged(m2) {
     |   case ((k, v1), (_, v2)) => (k, v1 ++ v2)
     | }
res0: scala.collection.immutable.HashMap[String,Seq[Int]] = Map(0 -> List(0, 1))

scala> :silent

scala> :replay
Replaying: import scala.collection.immutable.HashMap

Replaying: val m1 = HashMap[String, Seq[Int]]().updated("0", Seq(0))

Replaying: val m2 = HashMap[String, Seq[Int]]().updated("0", Seq(1))

Replaying: m1.merged(m2) {
  case ((k, v1), (_, v2)) => (k, v1 ++ v2)
}
scala.MatchError: (null,null) (of class scala.Tuple2)
  at $anonfun$1.apply(<console>:15)
  at $anonfun$1.apply(<console>:15)
  at scala.collection.immutable.HashMap$$anon$2$$anon$3.apply(HashMap.scala:150)
  at scala.collection.immutable.HashMap$HashMap1.updated0(HashMap.scala:200)
  at scala.collection.immutable.HashMap$HashMap1.merge0(HashMap.scala:225)
  at scala.collection.immutable.HashMap.merged(HashMap.scala:117)
  ... 40 elided

@scabug
Copy link
Author

scabug commented Aug 30, 2016

@SethTisue said:
Oh, is this just a duplicate of #9688?

@scabug
Copy link
Author

scabug commented Dec 19, 2016

Seth Bromberger (sbromberger) said:
Just FYI - this bit me in some Spark code (running on 2.11 since Spark isn't yet ready for 2.12): see https://issues.apache.org/jira/browse/SPARK-18916 for the gory details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant