I was recently surprised when invocations of Scala's implicitly was returning null during runtime. I had thought that was unlikely, given that the code shouldn't compile if no implicit instance was available in implicit scope. When is implicitly allowed to return null? Is this a compiler limitation, or is this expected behavior?
Here's some context, if it helps. I'm using shapeless to derive typeclass instances for persisting arbitrary nested case classes. I thought it would be helpful to use implicitly in the nested case classes to check if a typeclass instance could be derived, as it can be unclear where to start looking if the nested case class is large.
So, for example, if I was trying to persist:
case class Foo(bar: Bar, baz: Baz) and the compiler couldn't derive an instance for my formatter MyFormatter[Foo], I started doing something like the following:
case class Bar(i: Int, q: Qux) object Bar { implicit val formatter = implicitly[MyFormatter[Bar]] } expecting the compiler to tell me that it couldn't find an implicit instance of MyFormatter[Bar].
Instead, this was a terrible idea, and my code compiled (when it shouldn't have, as no typeclass instance for Qux could be derived) and Bar.formatter was null at runtime.
MyFormatter. Something is making that implicit, but it's impossible to say what without seeing it. The Scala compiler won't magically create one that isnullon its own.implicit val oyVey: MyFormatter[Bar] = null(which I promise I didn't do) what would make that possible?implicitlygrants no magic. You could tryprintln(scala.reflect.runtime.universe.reify(implicitly[MyFormatter[Foo]]))to see where it is being resolved from.