-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add a val in Scala 2 macro bundles #9098
Conversation
is this a concern?, CI for 5beb624 failed with this |
It seems like some other issue. I restarted the tests to see what happens. |
There was a problem hiding this 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)
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")
} |
@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. |
done |
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) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps I overdid it?,
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
I guess someone else should review this now |
No description provided.