Frage

Given an Option[T] in a macro, I am trying to find the enclosed type T, such that given something like

import scala.language.experimental.macros
import scala.reflect.macros.Context

def innerTypeImpl[T: c.WeakTypeTag](c: Context): c.Expr[String] = {
  import c.universe._

  val tpe = weakTypeOf[T]
  val innerType = tpe.typeSymbol.asType.typeParams.head.name.decoded
  c.Expr[String] { q" {$innerType} " }
}

def innerType[T] = macro innerTypeImpl[T]

the call innerType[Option[Int]] would return "Int" (whereas right now it is returning "A", which corresponds to the type parameter used in Option's definition)

T may not be an Option (the plan was to use tpe.typeSymbol.name.decoded == "Option" to determine if T is an Option), so I'm not able to place any bounds on T

War es hilfreich?

Lösung

I guess you want something like this:

val innerType = weakTypeOf[T] match {
  case r: TypeRef => r.args.head
  case _ => c.abort(c.enclosingPosition, "call this method with known type parameter only.")
}

Note that WeakTypeTag could be not a TypeRef.

This method will fail on None.type. To make it work on subtypes (like None.type) you should use a method baseType like this:

val innerType = weakTypeOf[T].baseType(typeOf[Option[_]].typeSymbol) match {
  case TypeRef(_, _, targ :: Nil) => targ
  case NoType => c.abort(...)
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top