Closed
Description
Compiler version
Latest main: 58810fd
Minimized code
Macro_1.scala
:
import scala.annotation.{experimental, MacroAnnotation}
import scala.quoted._
@experimental
class gen extends MacroAnnotation:
def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] =
import quotes.reflect._
tree match
case ClassDef(name, ctr, parents, self, body) =>
val cls = tree.symbol
// val meth = cls.methodMember("foo").head
// val fooTpe = cls.typeRef.memberType(meth)
val overrideTpe = MethodType(Nil)(_ => Nil, _ => defn.StringClass.typeRef)
val fooOverrideSym = Symbol.newMethod(cls, "foo", overrideTpe, Flags.Override, Symbol.noSymbol)
val fooDef = DefDef(fooOverrideSym, _ => Some(Literal(StringConstant("hi"))))
val newClassDef = ClassDef.copy(tree)(name, ctr, parents, self, fooDef :: body)
List(newClassDef)
case _ =>
report.error("Annotation only supports `class`")
List(tree)
Test_2.scala
:
class Base:
def foo(): Object = ???
@gen
class Sub extends Base
// > override def foo(): String = "hi"
@main def Test(): Unit =
val sub = new Sub
println(sub.foo())
Output
> scalac -Xcheck-macros Macro_1.scala Test_2.scala
> scala Test
Exception in thread "main" scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:344)
at Base.foo(Test_2.scala:2)
at Test_2$package$.Test(Test_2.scala:14)
at Test.main(Test_2.scala:12)
Expectation
> scala Test
hi
Analysis
The output from -Xprint:erasure
contains:
class Sub() extends Base() {
override def foo(): String = "hi"
}
Notice that the bridge to def foo(): Object
is missing. As far as I can tell the issue is that the overridden symbol is never entered into the decls of the enclosing class, so the bridge-generation logic does not even know it exists. Surprisingly -Ycheck:all does not catch this mismatch between decls and trees.