Skip to content

NoClassDefFoundError with multi-stage macros #9484

@szeiger

Description

@szeiger

This requires 4 separate source files which are compiled together in a single run:

The top level in Test.scala calls a macro in Q:

object Test extends App {
  Q.f()
}

The second level in Q.scala has the macro implementation which uses LC:

import scala.quoted._

object Q {
  inline def f(): Any = ${ fExpr }
  def fExpr(using QuoteContext): Expr[Any] = { new LC; Expr(1) }
}

L.scala defines LC and an unrelated object L which is not referenced anywhere but references another macro in C. This code is used at the same staging level as Q.scala but has to be in a separate compilation unit to trigger the bug:

import scala.quoted._

object L {
  val m = C.m
}

class LC

The third level in C.scala contains the macro that is referenced by L:

import scala.quoted._

object C {
  inline def m: Any = ${ mExpr }
  def mExpr(using qctx: QuoteContext): Expr[Any] = Expr(1)
}

In 0.26.0-RC1 this fails with:

[error] -- Error: /mnt/c/Users/szeiger/code/dottyquery/src/main/scala/dottyquery/Test.scala:2:5
[error] 2 |  Q.f()
[error]   |  ^^^^^
[error]   |  Exception occurred while executing macro expansion.
[error]   |  java.lang.NoClassDefFoundError: LC
[error]   |     at Q$.fExpr(Q.scala:5)
[error]   |
[error]   | This location contains code that was inlined from Test.scala:2

When all definitions are moved into a named package (instead of the default package) it causes a compiler crash with a stack trace instead of reporting an error, but the cause is the same NoClassDefFoundError.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions