Skip to content

Making case class constructor package-private crashes the compiler when there's a circular dependency #19526

Closed
@lbialy

Description

@lbialy

Compiler version

3.3.1

Minimized code

This caused by a circular reference between stack.scala (the trait StackFactory references Export) and macro.scala. If the trait is moved to another file this example compiles (and that's the workaround).

3 files, same directory, scala-cli setup:

package.scala

//> using scala 3.3.1

stack.scala

package crash.test

case class Stack private[crash] ( // remove private[crash] to make error go away
    exports: String,
    dependsOn: Vector[Int]
)

trait StackFactory:
  val exports: Export.type = Export

  def apply(dependsOn: Int*): Stack =
    Export().copy(dependsOn = dependsOn.toVector)

macro.scala

package crash.test

import scala.language.dynamics

import scala.quoted.*

object Export extends Dynamic:
  inline def applyDynamic(name: "apply")(inline args: Any*): Stack = ${
    applyDynamicImpl('args)
  }

  def applyDynamicImpl(args: Expr[Seq[Any]])(using Quotes): Expr[Stack] =
    import quotes.reflect.*

    '{ Stack("", Vector.empty) }

Output (click arrow to expand)

scala-cli compile --server=false .

  unhandled exception while running inlining on /Users/lbialy/Projects/foss/dotty-crash-replication/stack.scala

  An unhandled exception was thrown in the compiler.
  Please file a crash report here:
  https://github.com/lampepfl/dotty/issues/new/choose

     while compiling: <no file>
        during phase: <no phase>
                mode: Mode(ImplicitsEnabled)
     library version: version 2.13.10
    compiler version: version 3.3.1
            settings: -classpath /Users/lbialy/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala3-library_3/3.3.1/scala3-library_3-3.3.1.jar:/Users/lbialy/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar -d /Users/lbialy/Projects/foss/dotty-crash-replication/.scala-build/dotty-crash-replication_3a37a7372a/classes/main -java-output-version 17 -sourceroot /Users/lbialy/Projects/foss/dotty-crash-replication

                tree: EmptyTree
       tree position: :<unknown>
           tree type: <notype>
              symbol: val <none>
           call site: package <root> in module class <root>

  == Source file context for tree position ==


Exception while compiling /Users/lbialy/Projects/foss/dotty-crash-replication/macro.scala, /Users/lbialy/Projects/foss/dotty-crash-replication/package.scala, /Users/lbialy/Projects/foss/dotty-crash-replication/stack.scala
Exception in thread "main" java.lang.NoClassDefFoundError: crash/test/Stack$
	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.quoted.Interpreter.getMethod(Interpreter.scala:219)
	at dotty.tools.dotc.quoted.Interpreter.interpretedStaticMethodCall(Interpreter.scala:171)
	at dotty.tools.dotc.quoted.Interpreter.interpretTree(Interpreter.scala:80)
	at dotty.tools.dotc.transform.Splicer$SpliceInterpreter.interpretTree(Splicer.scala:258)
	at dotty.tools.dotc.quoted.Interpreter.interpretTree$$anonfun$2(Interpreter.scala:99)
	at dotty.tools.dotc.transform.Splicer$.$anonfun$2(Splicer.scala:60)
	at scala.Option.fold(Option.scala:263)
	at dotty.tools.dotc.transform.Splicer$.splice(Splicer.scala:60)
	at dotty.tools.dotc.inlines.Inliner.dotty$tools$dotc$inlines$Inliner$$expandMacro(Inliner.scala:1048)
	at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedSplice(Inliner.scala:839)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3092)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3112)
	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:146)
	at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedUnadapted(Inliner.scala:915)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3184)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3188)
	at dotty.tools.dotc.typer.ReTyper.typedTyped(ReTyper.scala:65)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3053)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3112)
	at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:146)
	at dotty.tools.dotc.inlines.Inliner$InlineTyper.typedUnadapted(Inliner.scala:915)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3184)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3181)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3188)
	at dotty.tools.dotc.inlines.Inliner.inlined(Inliner.scala:681)
	at dotty.tools.dotc.inlines.Inlines$InlineCall.expand(Inlines.scala:444)
	at dotty.tools.dotc.inlines.Inlines$.inlineCall(Inlines.scala:152)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:95)
	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1567)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:89)
	at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1244)
	at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1244)
	at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1249)
	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1518)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:43)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:91)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:50)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:89)
	at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1244)
	at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1244)
	at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1246)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:58)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:108)
	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1572)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:89)
	at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1244)
	at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1244)
	at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1246)
	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1580)
	at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
	at dotty.tools.dotc.transform.Inlining$InliningTreeMap.transform(Inlining.scala:97)
	at dotty.tools.dotc.transform.Inlining$$anon$2.transform(Inlining.scala:58)
	at dotty.tools.dotc.transform.MacroTransform.run(MacroTransform.scala:18)
	at dotty.tools.dotc.transform.Inlining.run(Inlining.scala:34)
	at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:327)
	at scala.collection.immutable.List.map(List.scala:246)
	at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:331)
	at dotty.tools.dotc.transform.Inlining.runOn(Inlining.scala:38)
	at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:246)
	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:262)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:270)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:279)
	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:67)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:279)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:200)
	at dotty.tools.dotc.Driver.finish(Driver.scala:58)
	at dotty.tools.dotc.Driver.doCompile(Driver.scala:38)
	at dotty.tools.dotc.Driver.process(Driver.scala:197)
	at dotty.tools.dotc.Driver.process(Driver.scala:165)
	at dotty.tools.dotc.Driver.process(Driver.scala:177)
	at dotty.tools.dotc.Driver.main(Driver.scala:207)
	at dotty.tools.dotc.Main.main(Main.scala)
Caused by: java.lang.ClassNotFoundException: crash.test.Stack$
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	... 82 more
Compilation failed

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions