Skip to content

Add a val in Scala 2 macro bundles #9098

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

Merged
merged 5 commits into from
Jun 6, 2020

Conversation

nicolasstucki
Copy link
Contributor

No description provided.

@nicolasstucki nicolasstucki requested a review from bishabosha June 2, 2020 14:41
@bishabosha
Copy link
Member

bishabosha commented Jun 3, 2020

[info] Test dotty.tools.vulpix.VulpixUnitTests.runTimeout started
failed because test tests/vulpix-tests/unit/timeout.scala timed out
[=======================================] completed (1/1, 1 failed, 3s)

is this a concern?, CI for 5beb624 failed with this

@nicolasstucki
Copy link
Contributor Author

It seems like some other issue. I restarted the tests to see what happens.

Copy link
Member

@bishabosha bishabosha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work because the val is local to the block, when it needs to be visible in the method selection. I tried out this version below which has the correct signature on the method selection:

def typedPrefix(tree: untpd.RefTree)(splice: Context ?=> Tree => Tree)(using Context): Tree = {
  tryAlternatively {
    splice(typedExpr(tree, defn.AnyType))
  } {
    // Try to type as a macro bundle
    val ref = tree match
      case Ident(name) => untpd.Ident(name.toTypeName).withSpan(tree.span)
      case Select(qual, name) => untpd.Select(qual, name.toTypeName).withSpan(tree.span)
    val bundle = untpd.Apply(untpd.Select(untpd.New(ref), nme.CONSTRUCTOR), untpd.Literal(Constant(null))).withSpan(call.span)
    val bundle1 = typedExpr(bundle, defn.AnyType)
    val bundleVal = SyntheticValDef(NameKinds.UniqueName.fresh("bundle".toTermName), bundle1)
    tpd.Block(List(bundleVal), splice(tpd.ref(bundleVal.symbol)))
  }
}
if ctx.phase.isTyper then
  call match
    case call: untpd.Ident =>
      typedIdent(call, defn.AnyType)
    case untpd.Select(qual: untpd.RefTree, name) =>
      typedPrefix(qual) { qual =>
        val call2 = untpd.Select(untpd.TypedSplice(qual), name).withSpan(call.span)
        typedSelect(call2, defn.AnyType)
      }
    case untpd.TypeApply(untpd.Select(qual: untpd.RefTree, name), targs) =>
      typedPrefix(qual) { qual =>
        val call2= untpd.TypeApply(untpd.Select(untpd.TypedSplice(qual), name), targs).withSpan(call.span)
        typedTypeApply(call2, defn.AnyType)
      }
    case _ =>
      ctx.error("Invalid Scala 2 macro " + call.show, call.sourcePos)
      EmptyTree
else typedExpr(call, defn.AnyType)

@bishabosha
Copy link
Member

with the changes I suggested I can successfuly compile and use the polymorphic macro bundle definition in the following:

// src-2/MacroImpl.scala
class MacroImpl(val c: scala.reflect.macros.blackbox.Context) {
  import c.universe._
  def poly[T: c.WeakTypeTag]: Tree = q"${c.weakTypeOf[T].toString}"
}
// src-3/Macros.scala
import scala.language.experimental.macros

object Macros {

  object Bundles {
    def poly[T]: String = macro MacroImpl.poly[T]
    inline def poly[T]: String = ${ Macros3.polyImpl[T] }
  }

  object Macros3 {
    def polyImpl[T: Type](using QuoteContext) = Expr(summon[Type[T]].show)
  }

}

and consume macro from TASTy in Scala 2:

// src-2/TestMacroCompat.scala
object TestMacroCompat extends App {
  import MacroCompat._
  import Bundles._
  assert(poly[String] == "String")
}

@nicolasstucki
Copy link
Contributor Author

@bishabosha could you push the changes that make it work on your side directly to this PR? As long as it works with your tests it good. If the CI fails after that, I can fix it.

@bishabosha
Copy link
Member

done

@bishabosha
Copy link
Member

looks like I didn't set the right span

tryAlternatively {
typedExpr(tree, defn.AnyType)
splice(typedExpr(tree, defn.AnyType))
} {
// Try to type as a macro bundle
val ref = tree match
case Ident(name) => untpd.Ident(name.toTypeName).withSpan(tree.span)
case Select(qual, name) => untpd.Select(qual, name.toTypeName).withSpan(tree.span)
val bundle = untpd.Apply(untpd.Select(untpd.New(ref), nme.CONSTRUCTOR), untpd.Literal(Constant(null))).withSpan(call.span)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This .withSpan(call.span) should probably be around the tpd.Block

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps I overdid it?,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed some of them. Could you check it works with your example?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure whats happening because the CI is passing but testCompilation tests/pos/i8945.scala fails for me

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait CI is still running

Copy link
Member

@bishabosha bishabosha Jun 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.withSpan still needs to be added to bundleVal - I'll do it

Copy link
Member

@bishabosha bishabosha Jun 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolasstucki the commit I just added also works with my scala 2 testing bd066e1

@bishabosha bishabosha requested a review from smarter June 5, 2020 08:07
@bishabosha
Copy link
Member

I guess someone else should review this now

@bishabosha bishabosha requested a review from smarter June 5, 2020 15:00
@bishabosha bishabosha assigned smarter and unassigned bishabosha Jun 5, 2020
@nicolasstucki nicolasstucki dismissed bishabosha’s stale review June 5, 2020 15:24

changes where made

@nicolasstucki nicolasstucki merged commit 31879e5 into scala:master Jun 6, 2020
@nicolasstucki nicolasstucki deleted the scala2-macro-bundle-val branch June 6, 2020 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants