NullPointerException on implicit resolution
Asked Answered
S

1

1

This code results in NullPointerException:

import anotherpackage.MyContext
import anotherpackage.builders.aMyContext

case class Context(id: String)
object Context {
  implicit def `ContextHolder to Context`(implicit holder: ContextHolder): Context = holder.context
}
trait ContextHolder {
  def context: Context
}

object anotherpackage {
  case class MyContext(name: String, context: Context) extends ContextHolder

  object builders {
    def aMyContext(name: String)(implicit context: Context = Context("test")): MyContext =
      MyContext(name, context)
  }
}

object SimpleDemo extends App {
  implicit val myContext: MyContext = aMyContext("name")
}

Stack trace:

Exception in thread "main" java.lang.NullPointerException
    at Context$.ContextHolder$u0020to$u0020Context(SimpleDemo.scala:8)
    at SimpleDemo$.delayedEndpoint$SimpleDemo$1(SimpleDemo.scala:24)
    at SimpleDemo$delayedInit$body.apply(SimpleDemo.scala:23)
    at scala.Function0.apply$mcV$sp(Function0.scala:39)
    at scala.Function0.apply$mcV$sp$(Function0.scala:39)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
    at scala.App.$anonfun$main$1$adapted(App.scala:80)
    at scala.collection.immutable.List.foreach(List.scala:392)
    at scala.App.main(App.scala:80)
    at scala.App.main$(App.scala:78)
    at SimpleDemo$.main(SimpleDemo.scala:23)
    at SimpleDemo.main(SimpleDemo.scala)

Why does Scala resolves implicit parameter for function aMyContext to itself:

implicit val myContext: MyContext = aMyContext("name")

Yes, aMyContext gets implicit Context and for MyContext there's an implicit conversion to Context. But how can it resolve it to the field itself?

Stave answered 20/5, 2020 at 16:16 Comment(0)
P
1

Try

implicit val myContext: MyContext = {
  val myContext = null
  aMyContext("name")
}

hiding the name of implicit.

Caching the circe implicitly resolved Encoder/Decoder instances

How can an implicit be unimported from the Scala repl?

Scala implicit def do not work if the def name is toString

[video] Some Mistakes We Made When Designing Implicits (11:18)

Paranoiac answered 20/5, 2020 at 16:43 Comment(2)
This trick does work, thanks. It's just a bit frustrating that scala works this way.Stave
@DmitryKomanov I guess this is intentional. Think of recursive implicits like implicit def succDouble[N <: Nat](implicit double: Double[N]): Double.Aux[Succ[N], Succ[Succ[double.Out]]] = null. Maybe by default myContext must be in scope when is being defined.Paranoiac

© 2022 - 2024 — McMap. All rights reserved.