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

Inconsistent lifting of receiver in macro #5119

Closed
allanrenucci opened this issue Sep 18, 2018 · 4 comments
Closed

Inconsistent lifting of receiver in macro #5119

allanrenucci opened this issue Sep 18, 2018 · 4 comments

Comments

@allanrenucci
Copy link
Contributor

Let's consider the following macro:

import scala.quoted._
import scala.tasty.Tasty

object Macro {
  class StringContextOps(sc: => StringContext) {
    rewrite def ff(args: => Any*): String = ~Macro.impl('(sc), '(args))
  }
  implicit rewrite def XmlQuote(sc: => StringContext): StringContextOps = new StringContextOps(sc)
  def impl(sc: Expr[StringContext], args: Expr[Seq[Any]])(implicit tasty: Tasty): Expr[String] = {
    import tasty._

    println(sc.toTasty.show)
    println(args.toTasty.show)
    '("")
  }
}

In the following use case:

class Test {
  import Macro._
  def test = ff"Hello World ${1}!"
}

the Macro.impl sees the receiver sc as

Macro.impl(
  scala.quoted.Expr.apply[StringContext](
    {
      _root_.scala.StringContext.apply(
        ["Hello World ","!" : String]: String*
      )
    }
  ),
  scala.quoted.Expr.apply[Any*](
    {
      [1 : Any]: Any*
    }
  )
)

as expected.

But now if my interpolator has no splice:

class Test {
  import Macro._
  def test = ff"Hello World"
}

the receiver is lifted out and I only see a reference to it:

val $1$: Macro.StringContextOps = ...

Macro.impl(
  scala.quoted.Expr.apply[StringContext](
    {
      $1$
    }.inline$sc
  ),
  scala.quoted.Expr.apply[Any*](
    {
      [ : Any]: Any*
    }
  )
)
@allanrenucci
Copy link
Contributor Author

Blocked on this for xml interpolation

allanrenucci added a commit to allanrenucci/jsx-interpolator that referenced this issue Sep 18, 2018
Does not work with no splice. See scala/scala3#5119
@nicolasstucki
Copy link
Contributor

nicolasstucki commented Sep 19, 2018

This can be minimized to

object Macro {
  final class StringContextOps(sc: => StringContext) {
    rewrite def ff(args: => Any*): String = sc.toString
  }
  implicit rewrite def XmlQuote(sc: => StringContext): StringContextOps = new StringContextOps(sc)

  def test0 = ff"Hello World 0!"
  def test1 = ff"Hello World 1 ${1}!"
  def test2 = ff"Hello World 2 ${22} ${222}!"
}

where in test0 sc is not inlined.

@allanrenucci
Copy link
Contributor Author

Note that this is still an issue after the introduction of TermAPI::underlyingArgument

@allanrenucci allanrenucci added this to the 0.10 Tech Preview milestone Oct 1, 2018
@allanrenucci
Copy link
Contributor Author

allanrenucci commented Oct 1, 2018

So this is not as issue with Inlining but when typing StringContext("Hello").foo():

object Test {
  implicit class SCOps(ctx: StringContext) {
    def foo(args: => Any*): String = ""
  }

  def test(name: String) = {
    // {
    //   val $1$: Test.SCOps = SCOps(StringContext.apply(["Hello" : String]: String*))
    //   $1$.foo([ : Any]: Any*)
    // }
    foo"Hello"

    // SCOps(StringContext.apply(["Hello ","" : String]: String*)).foo([name : Any]: Any*)
    foo"Hello $name"
  }
}

nicolasstucki added a commit to dotty-staging/dotty that referenced this issue Oct 2, 2018
nicolasstucki added a commit that referenced this issue Oct 2, 2018
Fix #5119: Get underlying argument for synthetic local values
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants