I encountered this very peculiar behaviour that had me stumped for quite awhile. I've re-created it in a simple snippet below, code is lifted from Scala wrapper.
scala> def a = {
| implicit val u = null
| val x: Int = List(1,2,3).map(_.toString)
| }
a: Unit
In the code above, there is no error thrown even though I know the type of val x to be List[String]. I can change the type of x to Int, Long, etc. and it will continue to compile fine.
However when I add explicitly state a type for the implicit val u, like in the example below, the compiler behaves as expected and throws an error.
scala> def a = {
| implicit val u: Any = null
| val x: Int = List(1,2,3).map(_.toString)
| }
<console>:10: error: type mismatch;
found : List[String]
required: Int
Has anyone else experienced this or has any insight into why this is happening?
Due to how collections are designed in scala, null
gets picked up as the implicit parameter of map
, which has the following extended signature:
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That
In this specific example, the implicit parameter must be a CanBuildFrom[List[Int], String, Int]
, and unfortunately null
is a bottom type so it satisfies such requirement.
Check this QA for more details: How does CanBuildFrom know whether a type can build from another?
You can reproduce it without the implicit like this:
@ def a = {
val x: Int = List(1,2,3).map(_.toString)(null)
}
defined function a
Then, when you actually run the function, it tries to apply the builder but it's null, so... BOOM!
@ a
java.lang.NullPointerException
scala.collection.TraversableLike$class.builder$1(TraversableLike.scala:240)
scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
scala.collection.immutable.List.map(List.scala:285)
cmd3$.a(Main.scala:52)
cmd4$$anonfun$1.apply$mcV$sp(Main.scala:52)
cmd4$.<init>(Main.scala:53)
cmd4$.<clinit>(Main.scala:-1)
you can see in the stacktrace that everything breaks as soon as the implementation of map on TraversableLike
tries to access builder
, which happens to be null
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With