Open
Description
Compiler version
3.3.1-RC1-bin-20230425-c9ca7ce-NIGHTLY
Minimized code
ClassGen.scala:
//> using scala "3.3.1-RC1-bin-20230425-c9ca7ce-NIGHTLY"
import scala.quoted.*
class Foo:
def test: String = "hey"
inline def generateFooOverride: Foo = ${generateFooImpl}
def generateFooImpl(using Quotes): Expr[Foo] =
import quotes.reflect.*
val fooRepr = TypeRepr.of[Foo]
val fooSymbol = fooRepr.dealias.classSymbol.get
val overridingSymbol = Symbol.newClass(Symbol.spliceOwner, Symbol.freshName("Foo"), List(fooRepr), _ => Nil, None)
def newInstance(clazz: Symbol, args: List[Term]): Term = Apply(Select(New(TypeTree.ref(clazz)), clazz.primaryConstructor), args)
val overridingTestSymbol = Symbol.newMethod(overridingSymbol, "test", TypeRepr.of[String], Flags.Override, Symbol.noSymbol)
def overridingTestDef(term: Term): DefDef =
DefDef(
overridingTestSymbol,
_ => Some(term)
)
def overridingClassDef(term: Term): ClassDef =
ClassDef(
overridingSymbol,
List(newInstance(fooSymbol, Nil)),
List(overridingTestDef(term))
)
def instance(term: Term): Term =
Block(
List(overridingClassDef(term)),
newInstance(overridingSymbol, Nil)
)
instance(Literal(StringConstant("listen"))).asExprOf[Foo]
//> using scala "3.3.1-RC1-bin-20230425-c9ca7ce-NIGHTLY"
//> using file "ClassGen.scala"
println(generateFooOverride.test)
Output
Code generated by the macro (as expected):
{
class Foo$macro$1 extends Foo {
override def test: java.lang.String = "listen"
}
new Foo$macro$1()
}
Printed output: "listen"
However, when making Foo#test
abstract:
abstract class Foo:
def test: String
The generated code is the same but the compiler throws this error:
class Foo$macro$1 needs to be abstract, since def test: String in class Foo is not defined
Expectation
I'd expect both versions to compile and not only the first one.