Skip to content

Commit b76d01d

Browse files
committed
Fix #8945: Support macro bundles
1 parent 5aec4f8 commit b76d01d

File tree

2 files changed

+53
-10
lines changed

2 files changed

+53
-10
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3446,15 +3446,31 @@ class Typer extends Namer
34463446
/** Types the body Scala 2 macro declaration `def f = macro <body>` */
34473447
private def typedScala2MacroBody(call: untpd.Tree)(using Context): Tree =
34483448
// TODO check that call is to a method with valid signature
3449-
call match
3450-
case rhs0: untpd.Ident =>
3451-
typedIdent(rhs0, defn.AnyType)
3452-
case rhs0: untpd.Select =>
3453-
typedSelect(rhs0, defn.AnyType)
3454-
case rhs0: untpd.TypeApply =>
3455-
typedTypeApply(rhs0, defn.AnyType)
3456-
case _ =>
3457-
ctx.error("Invalid Scala 2 macro", call.sourcePos)
3458-
EmptyTree
3449+
def typedPrefix(tree: untpd.RefTree): Tree = {
3450+
tryAlternatively {
3451+
typedExpr(tree, defn.AnyType)
3452+
} {
3453+
// Try to type as a macro bundle
3454+
val ref = tree match
3455+
case Ident(name) => untpd.Ident(name.toTypeName).withSpan(tree.span)
3456+
case Select(qual, name) => untpd.Select(qual, name.toTypeName).withSpan(tree.span)
3457+
val bundle = untpd.Apply(untpd.Select(untpd.New(ref), nme.CONSTRUCTOR), untpd.Literal(Constant(null))).withSpan(call.span)
3458+
typedExpr(bundle, defn.AnyType)
3459+
}
3460+
}
3461+
if ctx.phase.isTyper then
3462+
call match
3463+
case call: untpd.Ident =>
3464+
typedIdent(call, defn.AnyType)
3465+
case untpd.Select(qual: untpd.RefTree, name) =>
3466+
val call2 = untpd.Select(untpd.TypedSplice(typedPrefix(qual)), name).withSpan(call.span)
3467+
typedSelect(call2, defn.AnyType)
3468+
case untpd.TypeApply(untpd.Select(qual: untpd.RefTree, name), targs) =>
3469+
val call2= untpd.TypeApply(untpd.Select(untpd.TypedSplice(typedPrefix(qual)), name), targs).withSpan(call.span)
3470+
typedTypeApply(call2, defn.AnyType)
3471+
case _ =>
3472+
ctx.error("Invalid Scala 2 macro " + call.show, call.sourcePos)
3473+
EmptyTree
3474+
else typedExpr(call, defn.AnyType)
34593475

34603476
}

tests/pos/i8945.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// src-2/MacroImpl.scala
2+
trait Context {
3+
object universe {
4+
type Literal
5+
}
6+
}
7+
8+
class MacroImpl(val c: Context) {
9+
import c.universe._
10+
def mono: Literal = ???
11+
}
12+
13+
// src-3/Macros.scala
14+
import scala.language.experimental.macros
15+
16+
object Macros {
17+
18+
object Bundles {
19+
def mono: Unit = macro MacroImpl.mono
20+
inline def mono: Unit = ${ Macros3.monoImpl }
21+
}
22+
23+
object Macros3 {
24+
def monoImpl(using quoted.QuoteContext) = '{()}
25+
}
26+
27+
}

0 commit comments

Comments
 (0)