In scala 2 or 3, is it possible to debug implicit resolution process in runtime?

前端 未结 1 1562
名媛妹妹
名媛妹妹 2020-12-20 08:02

In scala language, implicit resolution is often done in compile-time and sometimes throws obfuscating error information, one famous example of such error is when shapeless G

相关标签:
1条回答
  • 2020-12-20 08:32

    You can debug implicits at compile time:

    1. switch on -Xlog-implicits

    2. try to resolve implicits manually (maybe specifying type parameters as well) and see compile errors

      implicitly[...](...manually...)
      
    3. use scala.reflect

      println(reify { implicitly[...] }.tree)
      
    4. use IDE functionality to show implicits

    5. using macros with compiler internals you can debug implicit resolution

      Is there a type-class that checks for existence of at least one implicit of a type?

      create an ambiguous low priority implicit

      Using the "Prolog in Scala" to find available type class instances

      Finding the second matching implicit

      https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/package.scala#L119-L168

    If you're developing a type class don't forget to use annotations @implicitNotFound and @implicitAmbiguous.


    You can always postpone compilation of your program till runtime. So instead of program

    object App {
      def main(args: Array[String]): Unit = {
        println("test") // test
      }
    }
    

    you can have

    import scala.reflect.runtime.currentMirror
    import scala.reflect.runtime.universe._
    import scala.tools.reflect.ToolBox
    val toolbox = currentMirror.mkToolBox()
    
    toolbox.eval(q"""
      object App {
        def main(args: Array[String]): Unit = {
          println("test")
        }
      }
    
      App.main(Array())
    """) // test
    

    And instead of

    implicitly[Numeric[Int]]
    

    you can have

    toolbox.compile(q"""
      implicitly[Numeric[Int]]
    """)
    

    or

    toolbox.inferImplicitValue(
      toolbox.typecheck(tq"Numeric[Int]", mode = toolbox.TYPEmode).tpe, 
      silent = false
    )
    

    But it's too optimistic to think that postponing program compilation till runtime you'll be able to debug implicits easier at runtime rather than at compile time. Actually postponing program compilation till runtime you add one level of indirection more i.e. make things harder to debug.

    0 讨论(0)
提交回复
热议问题