Scala 3 Macros: How do I get name of generic Type with quoted.Type

Viewed 254

I got following problem. I would like to get the type as a string representation in scala 3. If I use following, I have the problem with type erasure.

object Example1:
  @main def example1() =
    print[String]       // java.lang.String
    print[Int]          // int
    print[List[Double]] // scala.collection.immutable.List => Dang it, Double is erased

  def print[A: ClassTag]: Unit =
    println(getTypeString[A])

  def getTypeString[A](implicit ev: ClassTag[A]): String =
    ev.runtimeClass.getTypeName

So far so known. So I tried to find TypeTag in scala 3 and found quoted.Type. Which worked great on the first look, but I run into trouble if I don't call the macro directly:

object Macro1:
  import scala.quoted.*

  inline def getTypeString[A]: String = ${ getTypeStringImpl[A] }

  def getTypeStringImpl[A: Type](using Quotes): Expr[String] =
    Expr(Type.show[A])

// In another file
object Example2:
  @main def example2() =
    println(Macro1.getTypeString[String])       // scala.Predef.String
    println(Macro1.getTypeString[Int])          // scala.Int
    println(Macro1.getTypeString[List[Double]]) // scala.collection.immutable.List[scala.Double] => Profit!

    // Oh dang it...
    print[String]       // A
    print[Int]          // A
    print[List[Double]] // A

  def print[A]: Unit =
    println(Macro1.getTypeString[A])

So the solution could be passing the Type through all functions as with ClassTag, but I can't make it compile:

object Macro2:
  import scala.quoted.*

  /* Dang it! This doesn't compile:
   *
   * Malformed macro parameter: evidence$3
   *
   * Parameters may only be:
   *    * Quoted parameters or fields
   *    * Literal values of primitive types
   *    * References to `inline val`s
   *
   *   inline def getTypeString[A: Type]: String = ${ getTypeStringImpl[A] }
   */
  inline def getTypeString[A: Type]: String = ${ getTypeStringImpl[A] }

  def getTypeStringImpl[A: Type](using Quotes): Expr[String] =
    Expr(Type.show[A])

// In another file
object Example3:
  import scala.quoted.Type

  @main def example3() =
    print[String]       
    print[Int]          
    print[List[Double]]

  def print[A: Type]: Unit =
    println(Macro2.getTypeString[A])

Can anyone help me to make Example3 to compile? I tried different things, but non worked so far.

0 Answers
Related