Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange error when compiling a for loop

Tags:

loops

scala

While I was writing some Scala code, I got a strange error message when trying to compile the code. I broke down the code to a much simpler one (which makes no sense at all from a semantic point of view, but still shows the error).

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

import scala.collection.mutable.ListBuffer

val map = scala.collection.mutable.Map[Int, ListBuffer[Int]]()
for (i <- 1 to 2) {
  map.get(0) match {
    case None => map += (1 -> ListBuffer[Int](1))
    case Some(l: ListBuffer[Int]) => l += i
  }
}

// Exiting paste mode, now interpreting.

<console>:12: error: type arguments [Any] do not conform to trait Cloneable's t
pe parameter bounds [+A <: AnyRef]
              for (i <- 1 to 2) {
                          ^

When adding an extra line at the end of the for loop, the code works:

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

import scala.collection.mutable.ListBuffer

val map = scala.collection.mutable.Map[Int, ListBuffer[Int]]()
for (i <- 1 to 2) {
  map.get(0) match {
    case None => map += (1 -> ListBuffer[Int](1))
    case Some(l: ListBuffer[Int]) => l += i
  }
  1   // <- With this line it works
}

// Exiting paste mode, now interpreting.

warning: there were 1 unchecked warnings; re-run with -unchecked for details
import scala.collection.mutable.ListBuffer
map: scala.collection.mutable.Map[Int,scala.collection.mutable.ListBuffer[Int]]
= Map(1 -> ListBuffer(1))

I guess, it has something to do with the return value of the match-case-statement. But I am not Scala-expert enough to figure out the reason behind this error message and what I am doing wrong. I hope, someone more wise can help here.

What is the reason behind the error message ? What is wrong with the match-case-statement ?

UPDATE: Tested with Scala 2.9.2

like image 382
John Threepwood Avatar asked Aug 11 '12 18:08

John Threepwood


1 Answers

You're seeing this bug in action. It's fixed in 2.10, and there's an easy workaround in this answer—just add a type annotation somewhere:

for (i <- 1 to 2) {
  map.get(0) match {
    case None => map += (1 -> ListBuffer[Int](1))
    case Some(l: ListBuffer[Int]) => (l += i): Unit
  }
}
like image 139
Travis Brown Avatar answered Nov 03 '22 00:11

Travis Brown