Skip to content

Instantly share code, notes, and snippets.

@travisbrown
Created December 12, 2012 17:20
Show Gist options
  • Save travisbrown/4269734 to your computer and use it in GitHub Desktop.
Save travisbrown/4269734 to your computer and use it in GitHub Desktop.
Constructing "singleton types" from compile-time literals with macros
/** Constructing "singleton types" from compile-time literals
*
* val x = Example.foo(42)
* val y: x.T = 42 // compiles
* val z: x.T = 43 // doesn't
*
*/
import scala.language.experimental.macros
import scala.reflect.macros.Context
object Example {
def foo(s: Int): Any = macro foo_impl
def foo_impl(c: Context)(s: c.Expr[Int]) = {
import c.universe._
s.tree match {
case Literal(constant: Constant) =>
val anon = newTypeName(c.fresh)
c.Expr(
Block(
ClassDef(
Modifiers(Flag.FINAL),
anon,
Nil,
Template(
Nil,
emptyValDef,
List(
constructor(c),
TypeDef(
Modifiers(),
newTypeName("T"),
Nil,
TypeTree(ConstantType(constant))
)
)
)
),
Apply(Select(New(Ident(anon)), nme.CONSTRUCTOR), Nil)
)
)
}
}
def constructor(c: Context) = {
import c.universe._
DefDef(
Modifiers(),
nme.CONSTRUCTOR,
Nil,
Nil :: Nil,
TypeTree(),
Block(
Apply(
Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR),
Nil
)
)
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment