First of all, the syntax of macro definitions doesn't require (or allow) you to specify the parameters to the macro implementation method, so the code you have should never compile, even with a literal in the implementation. See my examples below for the correct syntax.
Next, Expr.value is unfortunately a lie. Think about the case where the argument to the macro method is a variable. The value of the variable isn't (and in the general case couldn't be) known at compile-time, and yet you're trying to make a compile-time literal constant with that value. It's just fundamentally not going to work.
You have a couple of options, which may or may not be applicable depending on what you're trying to do. Suppose we need to add one to the param value and return the result, for example. If we wanted the addition to happen at compile-time, we'd have to throw a (compile-time) exception when we don't get a compile-time literal:
def myMacro(param: Int): Int = macro myMacroImpl
def myMacroImpl(c: Context)(param: c.Expr[Int]): c.Expr[Int] = {
import c.universe._
val p = param.tree match {
case Literal(Constant(p: Int)) => p
case _ => c.abort(c.enclosingPosition, "param must be a literal value!")
}
c.literal(p + 1) // Or, equivalently: c.Expr(Literal(Constant(p + 1))
}
Another option would be to build a tree around the param expression. For example, the following also returns the successor to param, but the addition is performed at runtime, and the method can handle non-literal arguments:
def myMacro(param: Int): Int = macro myMacroImpl
def myMacroImpl(c: Context)(param: c.Expr[Int]): c.Expr[Int] = {
import c.universe._
c.Expr(
Apply(Select(param.tree, newTermName("$plus")), c.literal(1).tree :: Nil)
)
}
We're just not going to get both compile-time addition and an arbitrary param expression, though.