Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Macros cannot take call-by-name arguments #5778

Closed
scabug opened this issue May 9, 2012 · 5 comments
Closed

Macros cannot take call-by-name arguments #5778

scabug opened this issue May 9, 2012 · 5 comments
Assignees
Labels
Milestone

Comments

@scabug
Copy link

scabug commented May 9, 2012

Using the following code:

object Macros {
  def publish2(f: => Unit) = macro publish2Impl

  def publish2Impl(c : Context)(f: c.Expr[Function0[Unit]]) = c.reify{implicit val foo: String = "foo"; f.eval}
}

You get the error:

[error] C:\Users\szeiger\code\macrostuff\src\main\scala\com\novocode\macrostuff\MacroStuff.scala:69: macro implementation has wrong shape:
[error]  required: (c: scala.reflect.makro.Context)(f: c.Expr[=> Unit]): c.Expr[() => Unit]
[error]  found   : (c: scala.reflect.makro.Context)(f: c.Expr[() => Unit]): c.Expr[() => Unit]
[error] type mismatch for parameter f: c.Expr[=> Unit] does not conform to c.Expr[() => Unit]
[error]   def publish2(f: => Unit) = macro publish2Impl
[error]                                    ^

There is no way to write the expected type Expr[=> Unit]. Since call-by-name arguments are converted to Function0 internally, the type Expr[Function0[Unit]] should be accepted as a surrogate.

@scabug
Copy link
Author

scabug commented May 9, 2012

Imported From: https://issues.scala-lang.org/browse/SI-5778?orig=1
Reporter: @szeiger
Affected Versions: 2.10.0-M3

@scabug
Copy link
Author

scabug commented Dec 8, 2012

@retronym said:
What's the use case here? The generated code can choose whether or not to evaluate the argument without by-names.

@scabug
Copy link
Author

scabug commented Dec 8, 2012

@xeno-by said:
I'd say the stylistic effect of such a type annotation is quite useful.

@scabug
Copy link
Author

scabug commented Feb 3, 2013

@axel22 said (edited on Feb 3, 2013 12:21:07 AM UTC):
Interestingly, I am able to do:

object Macros {
  def publish2(f: =>Unit) = macro publish2Impl

  def publish2Impl(c : Context)(f: c.Expr[Unit]) = c.reify{implicit val foo: String = "foo"; f.eval}
}

Although I then cannot call eval. But if I just want to inline the body of f, it works.

@scabug
Copy link
Author

scabug commented Jan 28, 2014

@xeno-by said:
In 2.11, it is possible to define macro impl parameters as c.Tree's, not c.Expr[T]'s, and that makes it possible to write a macro impl that matches a macro def featuring a by-name parameter, e.g. something like this:

object Macros {
  def impl(c: Context)(x: c.Tree) = ???
  def foo[T](x: => T): Any = macro impl
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants