Skip to content

Instantly share code, notes, and snippets.

@wheaties
Last active March 20, 2018 12:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wheaties/8fed20c1b26523693f7e616066386dab to your computer and use it in GitHub Desktop.
Save wheaties/8fed20c1b26523693f7e616066386dab to your computer and use it in GitHub Desktop.
Playing in the compiler with by name parameters
//Trying to transform
// def foo(value: Int) = something(value) }
//into
// def foo(value: Int) = { def defer$[A](f: => A) = { () => f }; something(defer$(value)) }
def mkDefer(methSym: Symbol): Tree ={
val sym = methSym.newMethodSymbol(TermName("defer$"), newFlags = ARTIFACT)
val tpe = sym.newAbstractType(TypeName("A"), newFlags = PARAM)
tpe.setInfo(TypeBounds.empty)
val tref = typeRef(NoPrefix, tpe, Nil)
val paramSym = sym.newValueParameter(TermName("f")) setInfo tref
paramSym.setFlag(BYNAMEPARAM) //yeah, this doesn't do much at all...
System.out.println(s"PARAM: $paramSym, ${paramSym.tpe}, ${paramSym.tpe.typeSymbol}, $tref, $tpe, $sym")
sym.setInfo(GenPolyType(List(tpe), MethodType(List(paramSym), definitions.functionType(Nil, tref))))
val iden = gen.mkAttributedRef(paramSym)
val rhs = Function(Nil, iden) setType definitions.functionType(Nil, tref)
localTyper.typed{
DefDef(sym, rhs)
}
}
//The above only produces a "defer$" which doesn't have a by name parameter:
//def foo(value: Int) = { def defer$[A](f: A) = { () => f }; something(defer$(value)) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment