Skip to content

Abstract method overriding is incorrectly checked in macro #17375

Open
@Iltotore

Description

@Iltotore

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions