Regression: Macro usage compilation error (related to closure?)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Regression: Macro usage compilation error (related to closure?)

Eduardo D'Avila
Hi!

I may have found a compiler bug related to macros.

The macro definition:

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

object Y {
  def m(g: () => Int): Unit = macro impl

  def impl(c: Context)(g: c.Tree): c.Tree = {
    import c.universe._
    q"{ () => $g() }.apply()"
  }
}

And the usage:

object X {
  def f(): Unit = {
    val thisIsTheVal = 0
    Y.m { () => thisIsTheVal }
  }
}

On 2.11.8, the compilation works without any error. But on 2.12.0 and 2.12.1, the compilation of the code using the macro issues a "java.util.NoSuchElementException: key not found: value thisIsTheVal" exception. See the attached file for the full stack trace.

Is this a known issue?

Regards,

Eduardo

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

stacktrace.txt (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Regression: Macro usage compilation error (related to closure?)

Jason Zaugg
In general, it is not safe to splice a macro argument into the body of a synthesised closure, class, method, or val. The result can be an incoherent "owner chain". 

A common fix (albeit with its own corner cases) it to call `c.untypecheck` on the tree before splicing. 

Changes to the way that lambdas are desugared in 2.12. might have changed this particular example from benign to a crasher.

-jason

On Wed, 25 Jan 2017 at 09:49 Eduardo D'Avila <[hidden email]> wrote:
Hi!

I may have found a compiler bug related to macros.

The macro definition:

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

object Y {
  def m(g: () => Int): Unit = macro impl

  def impl(c: Context)(g: c.Tree): c.Tree = {
    import c.universe._
    q"{ () => $g() }.apply()"
  }
}

And the usage:

object X {
  def f(): Unit = {
    val thisIsTheVal = 0
    Y.m { () => thisIsTheVal }
  }
}

On 2.11.8, the compilation works without any error. But on 2.12.0 and 2.12.1, the compilation of the code using the macro issues a "java.util.NoSuchElementException: key not found: value thisIsTheVal" exception. See the attached file for the full stack trace.

Is this a known issue?

Regards,

Eduardo

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Regression: Macro usage compilation error (related to closure?)

Eduardo D'Avila
Thank you, Jason! 
With the proposed fix, now the code compiles successfully:

  def impl(c: Context)(g: c.Tree): c.Tree = {
    import c.universe._
    val ug = c.untypecheck(g)
    q"{ () => $ug() }.apply()"
  }

Anyways, should I report an issue?

Eduardo



Em terça-feira, 24 de janeiro de 2017 21:58:08 UTC-2, Jason Zaugg escreveu:
In general, it is not safe to splice a macro argument into the body of a synthesised closure, class, method, or val. The result can be an incoherent "owner chain". 

A common fix (albeit with its own corner cases) it to call `c.untypecheck` on the tree before splicing. 

Changes to the way that lambdas are desugared in 2.12. might have changed this particular example from benign to a crasher.

-jason

On Wed, 25 Jan 2017 at 09:49 Eduardo D'Avila <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="KxvaZMlFCgAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">erda...@...> wrote:
Hi!

I may have found a compiler bug related to macros.

The macro definition:

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

object Y {
  def m(g: () => Int): Unit = macro impl

  def impl(c: Context)(g: c.Tree): c.Tree = {
    import c.universe._
    q"{ () => $g() }.apply()"
  }
}

And the usage:

object X {
  def f(): Unit = {
    val thisIsTheVal = 0
    Y.m { () => thisIsTheVal }
  }
}

On 2.11.8, the compilation works without any error. But on 2.12.0 and 2.12.1, the compilation of the code using the macro issues a "java.util.NoSuchElementException: key not found: value thisIsTheVal" exception. See the attached file for the full stack trace.

Is this a known issue?

Regards,

Eduardo

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="KxvaZMlFCgAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">scala-interna...@googlegroups.com.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Regression: Macro usage compilation error (related to closure?)

Jason Zaugg
I think in this case the macro is at fault, and it only worked accidentally in 2.11, so no need for an issue.

-jason

On Wed, 25 Jan 2017 at 10:19 Eduardo D'Avila <[hidden email]> wrote:
Thank you, Jason! 
With the proposed fix, now the code compiles successfully:

  def impl(c: Context)(g: c.Tree): c.Tree = {
    import c.universe._
    val ug = c.untypecheck(g)
    q"{ () => $ug() }.apply()"
  }

Anyways, should I report an issue?

Eduardo



Em terça-feira, 24 de janeiro de 2017 21:58:08 UTC-2, Jason Zaugg escreveu:
In general, it is not safe to splice a macro argument into the body of a synthesised closure, class, method, or val. The result can be an incoherent "owner chain". 

A common fix (albeit with its own corner cases) it to call `c.untypecheck` on the tree before splicing. 

Changes to the way that lambdas are desugared in 2.12. might have changed this particular example from benign to a crasher.

-jason

On Wed, 25 Jan 2017 at 09:49 Eduardo D'Avila <[hidden email]> wrote:
Hi!

I may have found a compiler bug related to macros.

The macro definition:

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

object Y {
  def m(g: () => Int): Unit = macro impl

  def impl(c: Context)(g: c.Tree): c.Tree = {
    import c.universe._
    q"{ () => $g() }.apply()"
  }
}

And the usage:

object X {
  def f(): Unit = {
    val thisIsTheVal = 0
    Y.m { () => thisIsTheVal }
  }
}

On 2.11.8, the compilation works without any error. But on 2.12.0 and 2.12.1, the compilation of the code using the macro issues a "java.util.NoSuchElementException: key not found: value thisIsTheVal" exception. See the attached file for the full stack trace.

Is this a known issue?

Regards,

Eduardo

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Regression: Macro usage compilation error (related to closure?)

Eduardo D'Avila

Hmmm... OK

Thanks!


On Tue, Jan 24, 2017, 22:29 Jason Zaugg <[hidden email]> wrote:
I think in this case the macro is at fault, and it only worked accidentally in 2.11, so no need for an issue.

-jason

On Wed, 25 Jan 2017 at 10:19 Eduardo D'Avila <[hidden email]> wrote:
Thank you, Jason! 
With the proposed fix, now the code compiles successfully:

  def impl(c: Context)(g: c.Tree): c.Tree = {
    import c.universe._
    val ug = c.untypecheck(g)
    q"{ () => $ug() }.apply()"
  }

Anyways, should I report an issue?

Eduardo



Em terça-feira, 24 de janeiro de 2017 21:58:08 UTC-2, Jason Zaugg escreveu:
In general, it is not safe to splice a macro argument into the body of a synthesised closure, class, method, or val. The result can be an incoherent "owner chain". 

A common fix (albeit with its own corner cases) it to call `c.untypecheck` on the tree before splicing. 

Changes to the way that lambdas are desugared in 2.12. might have changed this particular example from benign to a crasher.

-jason

On Wed, 25 Jan 2017 at 09:49 Eduardo D'Avila <[hidden email]> wrote:
Hi!

I may have found a compiler bug related to macros.

The macro definition:

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

object Y {
  def m(g: () => Int): Unit = macro impl

  def impl(c: Context)(g: c.Tree): c.Tree = {
    import c.universe._
    q"{ () => $g() }.apply()"
  }
}

And the usage:

object X {
  def f(): Unit = {
    val thisIsTheVal = 0
    Y.m { () => thisIsTheVal }
  }
}

On 2.11.8, the compilation works without any error. But on 2.12.0 and 2.12.1, the compilation of the code using the macro issues a "java.util.NoSuchElementException: key not found: value thisIsTheVal" exception. See the attached file for the full stack trace.

Is this a known issue?

Regards,

Eduardo

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to a topic in the Google Groups "scala-internals" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/scala-internals/W4pggkPRiFg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.