Skip to content

Assertion error during macro generation for an enum #20349

Closed
@MateuszKubuszok

Description

@MateuszKubuszok

Compiler version

3.3.3

Minimized code

repro.scala

//> using scala 3.3.3

import scala.quoted.*

object Macros {


  def valuesImpl[A: Type](using quotes: Quotes): Expr[List[A]] = {
    import quotes.*, quotes.reflect.*

    extension (sym: Symbol)
     def isPublic: Boolean = !sym.isNoSymbol &&
          !(sym.flags.is(Flags.Private) || sym.flags.is(Flags.PrivateLocal) || sym.flags.is(Flags.Protected) ||
            sym.privateWithin.isDefined || sym.protectedWithin.isDefined)

    def isSealed[A: Type]: Boolean =
      TypeRepr.of[A].typeSymbol.flags.is(Flags.Sealed)

    def extractSealedSubtypes[A: Type]: List[Type[?]] = {
      def extractRecursively(sym: Symbol): List[Symbol] =
        if sym.flags.is(Flags.Sealed) then sym.children.flatMap(extractRecursively)
        else if sym.flags.is(Flags.Enum) then List(sym.typeRef.typeSymbol)
        else if sym.flags.is(Flags.Module) then List(sym.typeRef.typeSymbol.moduleClass)
        else List(sym)

      extractRecursively(TypeRepr.of[A].typeSymbol).distinct.map(typeSymbol =>
        typeSymbol.typeRef.asType
      )
    }

    if isSealed[A] then {
      val refs = extractSealedSubtypes[A].flatMap { tpe =>
        val sym = TypeRepr.of(using tpe).typeSymbol
        val isCaseVal = sym.isPublic && sym.flags
          .is(Flags.Case | Flags.Enum) && (sym.flags.is(Flags.JavaStatic) || sym.flags.is(Flags.StableRealizable))

        if (isCaseVal) then List(Ref(sym).asExprOf[A])
        else Nil
      }
      Expr.ofList(refs)
    } else '{ Nil }
  }

  inline def values[A]: List[A] = ${ valuesImpl[A] }
}

repro.test.sc

//> using dep org.scalameta::munit:1.0.0-RC1

object domain:
  enum PaymentMethod:
    case PayPal(email: String)
    case Card(digits: Long, name: String)
    case Cash

println(Macros.values[domain.PaymentMethod])
scala-cli test .

Output

Compiling project (Scala 3.3.3, JVM (17))
Error compiling project (Scala 3.3.3, JVM (17))
Error: Unexpected error when compiling eldupa7_d832c8dfee: java.lang.AssertionError: assertion failed: missing outer accessor in class repro$u002Etest$_

Expectation

repro.test.sc should compile successfully (and print something like List(Cash)).

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions