Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infer a type of a tree in a scala macro

Inside a macro, how can I ask the compiler to infer the type of a constructed tree? I've only found Context.typeCheck, but that only checks the types but doesn't return the result.

like image 543
edofic Avatar asked Jun 30 '13 20:06

edofic


2 Answers

If you've type-checked the tree you can just use its tpe method:

scala> def impl(c: Context) = c.literal(c.typeCheck(c parse "1+1").tpe.toString)
impl: (c: scala.reflect.macros.Context)c.Expr[String]

scala> def mac = macro impl
mac: String

scala> println(mac)
Int(2)

You could also wrap it in an expression, of course, but there's no need to if you just want the type.

like image 154
Travis Brown Avatar answered Nov 19 '22 13:11

Travis Brown


I figured it out and I hope this saves somebody else the hassle

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

def impl(c: Context) = {
  val tree = c.parse("1+1")
  val expr = c.Expr[Any](c.typeCheck(tree))
  println(expr.staticType)
  println(expr.actualType)
  c.literalUnit
}

def mac = macro impl

By wrapping into Expr you get the ability to query for the actual type. Any is there to provide a legal upper bound. Without that the infered type would be Expr[Nothing] and you would be in trouble. The catch is to wrap the tree returned from c.typeCheck otherwise the Type is just null.

Method mac just returns () bu it prints out Any-upper bound and Int(2) -the actual type.

like image 4
edofic Avatar answered Nov 19 '22 14:11

edofic