scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.84k stars 1.05k forks source link

ClassNotFound on macro expansion depending on class distribution in compilation units #17539

Open jchyb opened 1 year ago

jchyb commented 1 year ago

Compiler version

3.3.1-RC1-bin-20230518-4ffe5af-NIGHTLY 3.3.0-RC6 3.2.2 and previous (including 3.0 and 3.1 versions)

Minimized code

// Macros.scala
package internal

import scala.quoted.*

object Macros:

  inline def summonEncoders[A]: List[Encoder[?]] = ${ summonEncodersImpl[A] }

  private def summonEncodersImpl[A: Type](using Quotes): Expr[List[Encoder[?]]] =
    import quotes.reflect.*
    Expr.ofList(recSummonEncodersImpl(Type.of[A]))

  private def recSummonEncodersImpl(t: Type[?])(using Quotes): List[Expr[Encoder[?]]] =
    import quotes.reflect.*
    t match
      case '[EmptyTuple] => Nil
      case '[head *: tail] =>
        val exprOfEncoder = Expr.summon[Encoder[head]].get
        exprOfEncoder :: recSummonEncodersImpl(Type.of[tail])
      case _ => ???
// codecs.scala
package internal

import scala.deriving.*

class Encoder[A]
object Encoder:

  inline given derived[A](using m: Mirror.Of[A]): Encoder[A] =
    val instances        = Macros.summonEncoders[m.MirroredElemTypes]
    new Encoder[A]

  given componentResourceEncoder[A](using ctx: Context): Encoder[A] = ???

  transparent inline given unionEncoder[U]: Encoder[U] = ${ unionEncoderImpl[U] }

  private def unionEncoderImpl[U: scala.quoted.Type] = ???

  given Encoder[Int] = new Encoder[Int]

class ArgsEncoder[A]
object ArgsEncoder:

  inline def derived[A <: Product](using m: Mirror.ProductOf[A]): ArgsEncoder[A] =
    val instances = Macros.summonEncoders[m.MirroredElemTypes]
    new ArgsEncoder[A]
// Context.scala
package internal

class Context()

case class EmptyArgs() derives ArgsEncoder
// example.scala
import internal.*

case class EncoderExample(arg: Int) derives Encoder

I was unable to minimize further.

Output (click arrow to expand)

```scala -- Error: /Users/jchyb/Documents/workspace/besom/repro/example.scala:4:44 ------ 4 |case class EncoderExample(arg: Int) derives Encoder | ^ |Exception occurred while executing macro expansion. |java.lang.NoClassDefFoundError: internal/Context | at java.base/java.lang.Class.getDeclaredMethods0(Native Method) | at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3402) | at java.base/java.lang.Class.getMethodsRecursive(Class.java:3543) | at java.base/java.lang.Class.getMethod0(Class.java:3529) | at java.base/java.lang.Class.getMethod(Class.java:2225) | at dotty.tools.dotc.transform.Splicer$Interpreter.getMethod(Splicer.scala:428) | at dotty.tools.dotc.transform.Splicer$Interpreter.interpretedStaticMethodCall(Splicer.scala:375) | at dotty.tools.dotc.transform.Splicer$Interpreter.interpretTree(Splicer.scala:268) | at dotty.tools.dotc.transform.Splicer$Interpreter.interpretTree$$anonfun$2(Splicer.scala:289) | at dotty.tools.dotc.transform.Splicer$.$anonfun$2(Splicer.scala:57) | at scala.Option.fold(Option.scala:263) | at dotty.tools.dotc.transform.Splicer$.splice(Splicer.scala:57) | at dotty.tools.dotc.inlines.Inliner.dotty$tools$dotc$inlines$Inliner$$expandMacro(Inliner.scala:1038) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedApply(Inliner.scala:816) | at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2895) | at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2958) | at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedUnadapted(Inliner.scala:900) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3025) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3022) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3029) | at dotty.tools.dotc.inlines.Inliner.inlined(Inliner.scala:671) | at dotty.tools.dotc.inlines.Inlines$InlineCall.expand(Inlines.scala:451) | at dotty.tools.dotc.inlines.Inlines$.inlineCall(Inlines.scala:148) | at dotty.tools.dotc.typer.Typer.adaptNoArgsOther$1(Typer.scala:3750) | at dotty.tools.dotc.typer.Typer.adaptNoArgs$1(Typer.scala:3849) | at dotty.tools.dotc.typer.Typer.adapt1(Typer.scala:4071) | at dotty.tools.dotc.typer.Typer.adapt(Typer.scala:3406) | at dotty.tools.dotc.typer.Typer.readapt$1(Typer.scala:3417) | at dotty.tools.dotc.typer.Typer.adapt1(Typer.scala:4058) | at dotty.tools.dotc.typer.Typer.adapt(Typer.scala:3406) | at dotty.tools.dotc.typer.Implicits.typedImplicit(Implicits.scala:1084) | at dotty.tools.dotc.typer.Implicits.typedImplicit$(Implicits.scala:811) | at dotty.tools.dotc.typer.Typer.typedImplicit(Typer.scala:121) | at dotty.tools.dotc.typer.Implicits$ImplicitSearch.tryImplicit(Implicits.scala:1206) | at dotty.tools.dotc.typer.Implicits$ImplicitSearch.rank$1(Implicits.scala:1305) | at dotty.tools.dotc.typer.Implicits$ImplicitSearch.searchImplicit(Implicits.scala:1475) | at dotty.tools.dotc.typer.Implicits$ImplicitSearch.searchImplicit(Implicits.scala:1503) | at dotty.tools.dotc.typer.Implicits$ImplicitSearch.searchImplicit(Implicits.scala:1511) | at dotty.tools.dotc.typer.Implicits$ImplicitSearch.bestImplicit(Implicits.scala:1536) | at dotty.tools.dotc.typer.Implicits.inferImplicit(Implicits.scala:1028) | at dotty.tools.dotc.typer.Implicits.inferImplicit$(Implicits.scala:811) | at dotty.tools.dotc.typer.Typer.inferImplicit(Typer.scala:121) | at dotty.tools.dotc.typer.Implicits.inferImplicitArg(Implicits.scala:877) | at dotty.tools.dotc.typer.Implicits.inferImplicitArg$(Implicits.scala:811) | at dotty.tools.dotc.typer.Typer.inferImplicitArg(Typer.scala:121) | at scala.quoted.runtime.impl.QuotesImpl$reflect$Implicits$.search(QuotesImpl.scala:2398) | at scala.quoted.runtime.impl.QuotesImpl$reflect$Implicits$.search(QuotesImpl.scala:2397) | at scala.quoted.Expr$.summon(Expr.scala:232) | at internal.Macros$.recSummonEncodersImpl(Macros.scala:18) | at internal.Macros$.summonEncodersImpl(Macros.scala:11) | at internal.Macros$.inline$summonEncodersImpl(Macros.scala:9) |Caused by: java.lang.ClassNotFoundException: internal.Context | at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:440) | at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587) | at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) | at java.base/java.lang.Class.getDeclaredMethods0(Native Method) | at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3402) | at java.base/java.lang.Class.getMethodsRecursive(Class.java:3543) | at java.base/java.lang.Class.getMethod0(Class.java:3529) | at java.base/java.lang.Class.getMethod(Class.java:2225) | at dotty.tools.dotc.transform.Splicer$Interpreter.getMethod(Splicer.scala:428) | at dotty.tools.dotc.transform.Splicer$Interpreter.interpretedStaticMethodCall(Splicer.scala:375) | at dotty.tools.dotc.transform.Splicer$Interpreter.interpretTree(Splicer.scala:268) | at dotty.tools.dotc.transform.Splicer$Interpreter.interpretTree$$anonfun$2(Splicer.scala:289) | at dotty.tools.dotc.transform.Splicer$.$anonfun$2(Splicer.scala:57) | at scala.Option.fold(Option.scala:263) | at dotty.tools.dotc.transform.Splicer$.splice(Splicer.scala:57) | at dotty.tools.dotc.inlines.Inliner.dotty$tools$dotc$inlines$Inliner$$expandMacro(Inliner.scala:1038) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedApply(Inliner.scala:816) | at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2895) | at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2958) | at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedUnadapted(Inliner.scala:900) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3025) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3022) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3029) | at dotty.tools.dotc.inlines.Inliner.inlined(Inliner.scala:671) | at dotty.tools.dotc.inlines.Inlines$InlineCall.expand(Inlines.scala:451) | at dotty.tools.dotc.inlines.Inlines$.inlineCall(Inlines.scala:148) | at dotty.tools.dotc.typer.Typer.adaptNoArgsOther$1(Typer.scala:3750) | at dotty.tools.dotc.typer.Typer.adaptNoArgs$1(Typer.scala:3849) | at dotty.tools.dotc.typer.Typer.adapt1(Typer.scala:4071) | at dotty.tools.dotc.typer.Typer.adapt(Typer.scala:3406) | at dotty.tools.dotc.typer.Typer.readapt$1(Typer.scala:3417) | at dotty.tools.dotc.typer.Typer.adapt1(Typer.scala:4058) | at dotty.tools.dotc.typer.Typer.adapt(Typer.scala:3406) | at dotty.tools.dotc.typer.Implicits.typedImplicit(Implicits.scala:1084) | at dotty.tools.dotc.typer.Implicits.typedImplicit$(Implicits.scala:811) | at dotty.tools.dotc.typer.Typer.typedImplicit(Typer.scala:121) | at dotty.tools.dotc.typer.Implicits$ImplicitSearch.tryImplicit(Implicits.scala:1206) | at dotty.tools.dotc.typer.Implicits$ImplicitSearch.rank$1(Implicits.scala:1305) | at dotty.tools.dotc.typer.Implicits$ImplicitSearch.searchImplicit(Implicits.scala:1475) | at dotty.tools.dotc.typer.Implicits$ImplicitSearch.searchImplicit(Implicits.scala:1503) | at dotty.tools.dotc.typer.Implicits$ImplicitSearch.searchImplicit(Implicits.scala:1511) | at dotty.tools.dotc.typer.Implicits$ImplicitSearch.bestImplicit(Implicits.scala:1536) | at dotty.tools.dotc.typer.Implicits.inferImplicit(Implicits.scala:1028) | at dotty.tools.dotc.typer.Implicits.inferImplicit$(Implicits.scala:811) | at dotty.tools.dotc.typer.Typer.inferImplicit(Typer.scala:121) | at dotty.tools.dotc.typer.Implicits.inferImplicitArg(Implicits.scala:877) | at dotty.tools.dotc.typer.Implicits.inferImplicitArg$(Implicits.scala:811) | at dotty.tools.dotc.typer.Typer.inferImplicitArg(Typer.scala:121) | at scala.quoted.runtime.impl.QuotesImpl$reflect$Implicits$.search(QuotesImpl.scala:2398) | at scala.quoted.runtime.impl.QuotesImpl$reflect$Implicits$.search(QuotesImpl.scala:2397) | at scala.quoted.Expr$.summon(Expr.scala:232) | at internal.Macros$.recSummonEncodersImpl(Macros.scala:18) | at internal.Macros$.summonEncodersImpl(Macros.scala:11) | at internal.Macros$.inline$summonEncodersImpl(Macros.scala:9) | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) | at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) | at java.base/java.lang.reflect.Method.invoke(Method.java:568) | at dotty.tools.dotc.transform.Splicer$Interpreter.interpretedStaticMethodCall$$anonfun$1$$anonfun$1(Splicer.scala:376) | at dotty.tools.dotc.transform.Splicer$Interpreter.stopIfRuntimeException(Splicer.scala:440) | at dotty.tools.dotc.transform.Splicer$Interpreter.interpretedStaticMethodCall$$anonfun$1(Splicer.scala:376) | at dotty.tools.dotc.transform.Splicer$Interpreter.interpretTree(Splicer.scala:269) | at dotty.tools.dotc.transform.Splicer$Interpreter.interpretTree$$anonfun$2(Splicer.scala:289) | at dotty.tools.dotc.transform.Splicer$.$anonfun$2(Splicer.scala:57) | at scala.Option.fold(Option.scala:263) | at dotty.tools.dotc.transform.Splicer$.splice(Splicer.scala:57) | at dotty.tools.dotc.inlines.Inliner.dotty$tools$dotc$inlines$Inliner$$expandMacro(Inliner.scala:1038) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedApply(Inliner.scala:816) | at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2895) | at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2958) | at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedUnadapted(Inliner.scala:900) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3025) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3029) | at dotty.tools.dotc.typer.ReTyper.typedTyped(ReTyper.scala:64) | at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2900) | at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2958) | at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedUnadapted(Inliner.scala:900) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3025) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3022) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3029) | at dotty.tools.dotc.inlines.Inliner.inlined(Inliner.scala:671) | at dotty.tools.dotc.inlines.Inlines$InlineCall.expand(Inlines.scala:451) | at dotty.tools.dotc.inlines.Inlines$.inlineCall(Inlines.scala:148) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.inlineIfNeeded(Inliner.scala:896) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedTypeApply(Inliner.scala:824) | at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2914) | at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2958) | at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedUnadapted(Inliner.scala:900) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3025) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3029) | at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3145) | at dotty.tools.dotc.typer.Typer.typedValDef(Typer.scala:2300) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedValDef(Inliner.scala:805) | at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2868) | at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2957) | at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedUnadapted(Inliner.scala:900) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3025) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3029) | at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3051) | at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3101) | at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1063) | at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1067) | at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2903) | at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2958) | at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedUnadapted(Inliner.scala:900) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3025) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3029) | at dotty.tools.dotc.typer.ReTyper.typedTyped(ReTyper.scala:64) | at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2900) | at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2958) | at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126) | at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedUnadapted(Inliner.scala:900) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3025) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3022) | at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3029) | at dotty.tools.dotc.inlines.Inliner.inlined(Inliner.scala:671) | at dotty.tools.dotc.inlines.Inlines$InlineCall.expand(Inlines.scala:451) | at dotty.tools.dotc.inlines.Inlines$.inlineCall(Inlines.scala:148) | at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:70) | at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1475) | at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:73) | at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:64) | at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1225) | at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1225) | at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1227) | at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:64) | at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:64) | at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1480) | at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:73) | at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:64) | at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1225) | at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1225) | at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1227) | at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1488) | at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:73) | at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:76) | at dotty.tools.dotc.transform.Inlining$$anon$2.transform(Inlining.scala:56) | at dotty.tools.dotc.transform.MacroTransform.run(MacroTransform.scala:18) | at dotty.tools.dotc.transform.Inlining.run(Inlining.scala:28) | at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:316) | at scala.collection.immutable.List.map(List.scala:250) | at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:320) | at dotty.tools.dotc.transform.Inlining.runOn(Inlining.scala:32) | at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:238) | at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15) | at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10) | at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1321) | at dotty.tools.dotc.Run.runPhases$1(Run.scala:249) | at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:257) | at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:266) | at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:68) | at dotty.tools.dotc.Run.compileUnits(Run.scala:266) | at dotty.tools.dotc.Run.compileUnits(Run.scala:196) | at dotty.tools.dotc.Driver.finish(Driver.scala:56) | at dotty.tools.dotc.Driver.doCompile(Driver.scala:36) | at dotty.tools.dotc.Driver.process(Driver.scala:195) | at dotty.tools.dotc.Driver.process(Driver.scala:163) | at dotty.tools.dotc.Driver.process(Driver.scala:175) | at dotty.tools.dotc.Driver.main(Driver.scala:205) | at dotty.tools.dotc.Main.main(Main.scala) | |----------------------------------------------------------------------------- |Inline stack trace |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from Macros.scala:7 7 | inline def summonEncoders[A]: List[Encoder[?]] = ${ summonEncodersImpl[A] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from Macros.scala:7 9 | val instances = Macros.summonEncoders[m.MirroredElemTypes] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----------------------------------------------------------------------------- ```

The error disappears when the EmptyArgs class is moved from Context.scala to a separate file.

Expectation

Should compile with no errors, just like it does when EmptyArgs is moved to a separate file.

jchyb commented 1 year ago

Better minimization:

// codecs.scala
package internal

import scala.deriving._
import scala.quoted._

class Encoder[A]
object Encoder:

  inline def derived[A](): Encoder[A] =
    val instances = Macros.summonEncoders[Int]
    new Encoder[A]

  // causes the classloader to fail
  def methodWithContext[A](using ctx: Context): Encoder[A] = new Encoder[A]

  inline given unionEncoder[U]: Encoder[U] = ${ unionEncoderImpl[U] }
  private def unionEncoderImpl[U: scala.quoted.Type](using Quotes): Expr[Encoder[U]] = '{new Encoder[U]}
// Context.scala
package internal

class Context()

object Other {
  def methodCallingMacro(): Unit =
    Encoder.derived[Int]()
}
// Macros.scala
package internal

import scala.quoted.*

object Macros:

  inline def summonEncoders[A]: Unit = ${ summonEncodersImpl[A] }
  private def summonEncodersImpl[A: Type](using Quotes): Expr[Unit] =
    Expr.summon[Encoder[Int]]
    '{ () }

Interestingly, if the packages are removed, the error changes into the even less descriptive SuspendException.

It looks like the Context.scala CompileationUnit becomes suspended, and after compiling the other files, when compiler returns to Context.scala it tries to inline the derived method, for which it calls the Macros macro, where to summon the Encoder it tries to expand the unionEncoder by calling the MacroClassLoader to classload the Encoder, which it fails to do because of unknown (from the ClassLoader point of view, since the file Context.class was not generated yet at that point) class Context.

Calling the failing unionEncoder macro directly leads to a slightly different error/crash, outside of the macro expansion context:

MInimization

// Context.scala
package internal

class Context()

object Other {
  def methodCallingMacro(): Unit =
    Encoder.unionEncoder[Int]
}
// codecs.scala
package internal

import scala.deriving._
import scala.quoted._

class Encoder[A]
object Encoder:

  def methodWithContext[A](using ctx: Context): Encoder[A] = new Encoder[A]

  inline def unionEncoder[U]: Encoder[U] = ${ unionEncoderImpl[U] }
  private def unionEncoderImpl[U: scala.quoted.Type](using Quotes): Expr[Encoder[U]] = '{new Encoder[U]}

Output

``` java.lang.NoClassDefFoundError: internal/Context while running inlining on /Users/jchyb/Documents/workspace/dotty/zerr/Context.scala java.lang.NoClassDefFoundError: internal/Context while compiling /Users/jchyb/Documents/workspace/dotty/zerr/Context.scala, /Users/jchyb/Documents/workspace/dotty/zerr/Macros.scala, /Users/jchyb/Documents/workspace/dotty/zerr/codecs.scala Exception in thread "main" java.lang.NoClassDefFoundError: internal/Context at java.base/java.lang.Class.getDeclaredMethods0(Native Method) at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3402) at java.base/java.lang.Class.getMethodsRecursive(Class.java:3543) at java.base/java.lang.Class.getMethod0(Class.java:3529) at java.base/java.lang.Class.getMethod(Class.java:2225) at dotty.tools.dotc.transform.Splicer$Interpreter.getMethod(Splicer.scala:428) at dotty.tools.dotc.transform.Splicer$Interpreter.interpretedStaticMethodCall(Splicer.scala:375) at dotty.tools.dotc.transform.Splicer$Interpreter.interpretTree(Splicer.scala:268) at dotty.tools.dotc.transform.Splicer$Interpreter.interpretTree$$anonfun$2(Splicer.scala:289) at dotty.tools.dotc.transform.Splicer$.$anonfun$2(Splicer.scala:57) at scala.Option.fold(Option.scala:263) at dotty.tools.dotc.transform.Splicer$.splice(Splicer.scala:57) at dotty.tools.dotc.inlines.Inliner.dotty$tools$dotc$inlines$Inliner$$expandMacro(Inliner.scala:1038) at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedApply(Inliner.scala:816) at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2895) at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2958) at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126) at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedUnadapted(Inliner.scala:900) at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3025) at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3029) at dotty.tools.dotc.typer.ReTyper.typedTyped(ReTyper.scala:64) at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2900) at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2958) at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126) at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedUnadapted(Inliner.scala:900) at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3025) at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3022) at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3029) at dotty.tools.dotc.inlines.Inliner.inlined(Inliner.scala:671) at dotty.tools.dotc.inlines.Inlines$InlineCall.expand(Inlines.scala:451) at dotty.tools.dotc.inlines.Inlines$.inlineCall(Inlines.scala:148) at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:70) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1225) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1225) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1230) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1426) at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:49) at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:66) at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:56) at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:64) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1225) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1225) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1227) at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:64) at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:64) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1480) at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:73) at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:64) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1225) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1225) at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1227) at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1488) at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:73) at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:76) at dotty.tools.dotc.transform.Inlining$$anon$2.transform(Inlining.scala:56) at dotty.tools.dotc.transform.MacroTransform.run(MacroTransform.scala:18) at dotty.tools.dotc.transform.Inlining.run(Inlining.scala:28) at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:316) at scala.collection.immutable.List.map(List.scala:246) at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:320) at dotty.tools.dotc.transform.Inlining.runOn(Inlining.scala:32) at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:238) at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15) at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10) at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1321) at dotty.tools.dotc.Run.runPhases$1(Run.scala:249) at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:257) at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:266) at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:68) at dotty.tools.dotc.Run.compileUnits(Run.scala:266) at dotty.tools.dotc.Run.compileUnits(Run.scala:196) at dotty.tools.dotc.Driver.finish(Driver.scala:56) at dotty.tools.dotc.Driver.doCompile(Driver.scala:36) at dotty.tools.dotc.Driver.process(Driver.scala:195) at dotty.tools.dotc.Driver.process(Driver.scala:163) at dotty.tools.dotc.Driver.process(Driver.scala:175) at dotty.tools.dotc.Driver.main(Driver.scala:205) at dotty.tools.dotc.Main.main(Main.scala) Caused by: java.lang.ClassNotFoundException: internal.Context at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:440) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ```