Skip to content

Commit f16f4ab

Browse files
committed
Merge pull request scala#1678 from martende/ticket/5753
SI-5753 macros cannot be loaded when inherited from a class or a trait
2 parents b149c7b + 1be0244 commit f16f4ab

File tree

15 files changed

+57
-10
lines changed

15 files changed

+57
-10
lines changed

src/compiler/scala/tools/nsc/typechecker/Macros.scala

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,9 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
122122
}
123123

124124
def pickle(macroImplRef: Tree): Tree = {
125-
val macroImpl = macroImplRef.symbol
125+
val MacroImplReference(owner, macroImpl, targs) = macroImplRef
126126
val paramss = macroImpl.paramss
127127

128-
// this logic relies on the assumptions that were valid for the old macro prototype
129-
// namely that macro implementations can only be defined in top-level classes and modules
130-
// with the new prototype that materialized in a SIP, macros need to be statically accessible, which is different
131-
// for example, a macro def could be defined in a trait that is implemented by an object
132-
// there are some more clever cases when seemingly non-static method ends up being statically accessible
133-
// however, the code below doesn't account for these guys, because it'd take a look of time to get it right
134-
// for now I leave it as a todo and move along to more the important stuff
135128
// todo. refactor when fixing SI-5498
136129
def className: String = {
137130
def loop(sym: Symbol): String = sym match {
@@ -143,7 +136,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
143136
loop(sym.owner) + separator + sym.javaSimpleName.toString
144137
}
145138

146-
loop(macroImpl.owner.enclClass)
139+
loop(owner)
147140
}
148141

149142
def signature: List[Int] = {
@@ -164,7 +157,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
164157
// I just named it "macro", because it's macro-related, but I could as well name it "foobar"
165158
val nucleus = Ident(newTermName("macro"))
166159
val wrapped = Apply(nucleus, payload map { case (k, v) => Assign(pickleAtom(k), pickleAtom(v)) })
167-
val pickle = gen.mkTypeApply(wrapped, treeInfo.typeArguments(macroImplRef.duplicate))
160+
val pickle = gen.mkTypeApply(wrapped, targs map (_.duplicate))
168161

169162
// assign NoType to all freshly created AST nodes
170163
// otherwise pickler will choke on tree.tpe being null

test/files/neg/t5753.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Test_2.scala:9: error: macro implementation not found: foo (the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)
2+
println(foo(42))
3+
^
4+
one error found

test/files/neg/t5753.flags

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-language:experimental.macros
626 Bytes
Binary file not shown.

test/files/neg/t5753/Impls.class

866 Bytes
Binary file not shown.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import scala.reflect.macros.{Context => Ctx}
2+
3+
trait Impls {
4+
def impl(c: Ctx)(x: c.Expr[Any]) = x
5+
}
6+

test/files/neg/t5753/Test_2.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import scala.reflect.macros.{Context => Ctx}
2+
3+
object Macros extends Impls {
4+
def foo(x: Any) = macro impl
5+
}
6+
7+
object Test extends App {
8+
import Macros._
9+
println(foo(42))
10+
}
11+

test/files/run/t5753_1.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
42

test/files/run/t5753_1.flags

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-language:experimental.macros
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import scala.reflect.macros.Context
2+
import language.experimental.macros
3+
4+
trait Impls {
5+
def impl(c: Context)(x: c.Expr[Any]) = x
6+
}
7+
8+
object Macros extends Impls {
9+
def foo(x: Any) = macro impl
10+
}

0 commit comments

Comments
 (0)