Due to the way collections are created in scala, null receives map as an implicit parameter, which has the following extended signature:
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That
In this particular example, the implicit parameter should be CanBuildFrom[List[Int], String, Int] , and unfortunately null is a lower type, so it satisfies this requirement.
Check out this QA for more details: How CanBuildFrom knows if a type can build from another?
You can reproduce it without implication as follows:
@ def a = { val x: Int = List(1,2,3).map(_.toString)(null) } defined function a
Then, when you actually run this function, it tries to use the builder, but this value is 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 on the stack that everything breaks as soon as the implementation of the map on TraversableLike tries to access the builder , which turns out to be null .
source share