In scala 2.13, why sometimes TypeTags cannot be inferred? And how to construct one from a variable symbol?

Viewed 198

Here is a simple example in shapeless:

  it("from Witness") {

    val ttg = implicitly[TypeTag[Witness.Lt[String]]]
    val ctg = implicitly[ClassTag[Witness.Lt[String]]]
  }

  it("... from macro") {

    val ttg = implicitly[TypeTag[Witness.`1`.T]]
    val ctg = implicitly[ClassTag[Witness.`1`.T]]
  }

  it("... doesn't work") {

    val ttg = implicitly[TypeTag[w1.T]] // failed!
    val ctg = implicitly[ClassTag[w2.T]]
  }

The second and third it block have very similar bytecode (after the Witness.? macro has been invoked), yet one succeed and one failed:


[Error] /home/peng/git-spike/scalaspike/common/src/test/scala/com/tribbloids/spike/scala_spike/Reflection/InferTypeTag.scala:55: No TypeTag available for com.tribbloids.spike.scala_spike.Reflection.InferTypeTag.w1.T

What could have caused this? And how do I circumvent this problem?

1 Answers

If you switch on scalacOptions += "-Xlog-implicits" you'll see

val w1 = Witness(1)
val ttg = implicitly[TypeTag[w1.T]] // doesn't compile

//materializing requested reflect.runtime.universe.type.TypeTag[App.w1.T] using scala.reflect.api.`package`.materializeTypeTag[App.w1.T](scala.reflect.runtime.`package`.universe)

//scala.reflect.api.`package`.materializeTypeTag[App.w1.T](scala.reflect.runtime.`package`.universe) is not a valid implicit value for reflect.runtime.universe.TypeTag[App.w1.T] because:
//failed to typecheck the materialized tag: 
//cannot create a TypeTag referring to type shapeless.Witness.<refinement>.T local to the reifee: use WeakTypeTag instead

//No TypeTag available for App.w1.T

So try to use WeakTypeTag as recommended

val w1 = Witness(1)
val ttg2 = implicitly[WeakTypeTag[w1.T]] // compiles

In Scala, why it is impossible to infer TypeTag from type alias or dependent type?

Why there is no TypeTag available in nested instantiations (when interpreted by scala code runner)?

Typetags not working inside of code block scope?

Type aliases screw up type tags?

Related