Skip to content

StackOverflow during staging #22688

@hearnadam

Description

@hearnadam

On my github CI, I consistently see compiler crashes during staging. The code itself has been hard to minimize due to the crash not happening locally. I tried a variety of stack sizes, but once I reach -Xss512k other parts of the code fail to compile due to non-trivial inlining.

Compiler version

  • 3.6.3

Minimized code

The code is very similar to this file: https://github.com/getkyo/kyo/blob/main/kyo-examples/jvm/src/main/scala/examples/ledger/api/Endpoints.scala

It uses kyo-direct. The code is private, but happy to share privately with maintainers.

Output (click arrow to expand)

error] ## Exception when compiling 3 sources to /home/runner/work/winedb/winedb/backend/target/scala-3.6.3/classes
[error] java.lang.StackOverflowError
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1524)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1531)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1537)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform$$anonfun$1(Trees.scala:1643)
[error] scala.collection.immutable.List.mapConserve(List.scala:473)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1643)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:55)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:34)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1605)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:43)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1289)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1289)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1294)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1551)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:43)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:24)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1600)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:43)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1289)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1289)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1294)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1551)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:43)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:24)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1545)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1571)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1531)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1539)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1537)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock$$anonfun$1$$anonfun$1(tpd.scala:1294)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1276)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1289)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1294)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1551)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:43)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:24)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock$$anonfun$1$$anonfun$1(tpd.scala:1294)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1276)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1289)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1294)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1551)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:43)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:24)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1545)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1571)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1531)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1539)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1537)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock$$anonfun$1$$anonfun$1(tpd.scala:1294)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1276)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1289)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1294)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1551)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:43)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:24)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock$$anonfun$1$$anonfun$1(tpd.scala:1294)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1276)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1289)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1294)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1551)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:43)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:24)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1545)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1571)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1531)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1539)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1537)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock$$anonfun$1$$anonfun$1(tpd.scala:1294)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1276)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1289)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1294)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1551)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:43)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:24)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:43)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:24)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1600)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:43)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1289)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1289)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1294)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1551)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:43)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:24)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1545)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1571)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1531)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1539)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1537)
[error] dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
[error] dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
[error] dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
[error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock$$anonfun$1$$anonfun$1(tpd.scala:1294)

Activity

WojciechMazur

WojciechMazur commented on Mar 3, 2025

@WojciechMazur
Contributor

-Xss512k is ~ 0.5MB per thread, the JVM default is 1MB. The Scala compiler is not multithreading-heavy so typically you'd want to have bigger stack size, especially in case on non trivial code, like multi-level inlines.
The kyo is using lots of inlining and non trivial typing which might require a bigger stack size for the compiler.
I believe that instead of StackOverflowError the efforts should focus on dealing with the inlining.

Gedochao

Gedochao commented on Mar 3, 2025

@Gedochao
Contributor

@jchyb @dwijnand Can you think of any advice, how to help with minimising/reproducing this?

The code is private, but happy to share privately with maintainers.

@hearnadam it's hard to tell when we'll have the capacity to spend time on this in the maintenance team. When someone is available, we may reach out, but it'd be best to try to minimise this on your side, at least partially.

jchyb

jchyb commented on Mar 3, 2025

@jchyb
Contributor

Looking through the stack trace, nothing seems out of the ordinary - it just walks thought the program tree. I am wondering if perhaps somehow a different code is generated by Kyo locally and in the CI, as unlikely as that sounds. You can try running with the -Xcheck-macros option to check if the code generated by Kyo is correct. Otherwise I agree with @WojciechMazur that the issue might be with a too small of a stack size.

seroperson

seroperson commented on Jul 3, 2025

@seroperson

I guess I faced the same issue here bot4s/telegram#383 (comment) during migration to Scala 3. It occurs randomly: sometimes it compiles, but most of time it crashes.

Stacktrace looks very similar:

Details

Exception in thread "main" java.lang.Exception: java.lang.StackOverflowError
        at mill.eval.EvaluatorCore.$anonfun$evaluate0$6(EvaluatorCore.scala:208)
        at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:467)
        at mill.eval.ExecutionContexts$ThreadPool.$anonfun$execute$4(ExecutionContexts.scala:79)
        at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at mill.api.SystemStreams$.$anonfun$withStreams$9(SystemStreams.scala:104)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at mill.api.SystemStreams$.$anonfun$withStreams$8(SystemStreams.scala:103)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at mill.api.SystemStreams$.$anonfun$withStreams$7(SystemStreams.scala:102)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at scala.Console$.withErr(Console.scala:193)
        at mill.api.SystemStreams$.$anonfun$withStreams$6(SystemStreams.scala:101)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at scala.Console$.withOut(Console.scala:164)
        at mill.api.SystemStreams$.$anonfun$withStreams$5(SystemStreams.scala:100)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at scala.Console$.withIn(Console.scala:227)
        at mill.api.SystemStreams$.$anonfun$withStreams$4(SystemStreams.scala:99)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at mill.api.SystemStreams$.withStreams(SystemStreams.scala:98)
        at mill.eval.ExecutionContexts$ThreadPool.$anonfun$execute$3(ExecutionContexts.scala:79)
        at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at mill.eval.ExecutionContexts$ThreadPool.$anonfun$execute$1(ExecutionContexts.scala:78)
        at mill.eval.ExecutionContexts$ThreadPool$PriorityRunnable.run(ExecutionContexts.scala:99)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
        at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.lang.StackOverflowError
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1530)
        at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
        at dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
        at dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1545)
        at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
        at dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
        at dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1543)
        at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
        at dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:46)
        at dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1606)
        at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:67)
        at dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:43)
        at dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)
        at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1301)
        at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1301)
        at dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1306)
        at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1557)
        at dotty.tools.dotc.ast.TreeMapWithImplicits.transform(TreeMapWithImplicits.scala:43)
        at dotty.tools.dotc.staging.TreeMapWithStages.transform(TreeMapWithStages.scala:24)
        at dotty.tools.dotc.staging.CrossStageSafety.transform(CrossStageSafety.scala:123)

seroperson

seroperson commented on Jul 6, 2025

@seroperson

I guess I faced the same issue here bot4s/telegram#383 (comment) during migration to Scala 3. It occurs randomly: sometimes it compiles, but most of time it crashes.

This bug continuously (most of the time) appears on bot4s/telegram@e1325b4 commit even locally. The file which fails is: CirceDecoders.scala with a lot of automatically derived circe decoders. After I splitted this file and moved decoders to corresponding models, and then did the same to the similar CirceEncoders.scala file, this bug being unreproducible locally. After such splitting everything went good locally, but it was still reproducible on CI too during processing Message.scala file (which is heavy enough, there are around 60 fields and auto-derived codec). I implemented Encoder/Decoder manually for this class and finally build went green.

Here is a build which failed on Messages.scala processing. And stacktrace:

Details

Error: [772] [error] ## Exception when compiling 234 sources to /home/runner/work/telegram/telegram/out/core/jvm/3.3.6/compile.dest/classes
[772]   Please file a crash report here:
[772]   https://github.com/scala/scala3/issues/new/choose
[772]   For non-enriched exceptions, compile with -Xno-enrich-error-messages.
[772] 
[772] 
[772]      while compiling: /home/runner/work/telegram/telegram/core/src/com/bot4s/telegram/models/Message.scala
[772]         during phase: splicing
[772]                 mode: Mode(ImplicitsEnabled)
[772]      library version: version 2.13.16
[772]     compiler version: version 3.3.6
[772]             settings: -classpath /home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala3-library_3/3.3.6/scala3-library_3-3.3.6.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/io/circe/circe-core_3/0.14.14/circe-core_3-0.14.14.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/io/circe/circe-generic_3/0.14.14/circe-generic_3-0.14.14.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/io/circe/circe-generic-extras_3/0.14.5-RC1/circe-generic-extras_3-0.14.5-RC1.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/io/circe/circe-parser_3/0.14.14/circe-parser_3-0.14.14.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/io/circe/circe-literal_3/0.14.14/circe-literal_3-0.14.14.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/org/typelevel/cats-core_3/2.13.0/cats-core_3-2.13.0.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/org/typelevel/cats-free_3/2.13.0/cats-free_3-2.13.0.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/com/softwaremill/sttp/client3/core_3/3.11.0/core_3-3.11.0.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/com/typesafe/scala-logging/scala-logging_3/3.9.5/scala-logging_3-3.9.5.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.16/scala-library-2.13.16.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/io/circe/circe-numbers_3/0.14.14/circe-numbers_3-0.14.14.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/io/circe/circe-jawn_3/0.14.14/circe-jawn_3-0.14.14.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/org/typelevel/cats-kernel_3/2.13.0/cats-kernel_3-2.13.0.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/com/softwaremill/sttp/model/core_3/1.7.11/core_3-1.7.11.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/com/softwaremill/sttp/shared/core_3/1.3.22/core_3-1.3.22.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/com/softwaremill/sttp/shared/ws_3/1.3.22/ws_3-1.3.22.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/org/typelevel/jawn-parser_3/1.6.0/jawn-parser_3-1.6.0.jar:/home/runner/work/telegram/telegram/core/compile-resources:/home/runner/work/telegram/telegram/out/core/jvm/3.3.6/compile.dest/classes -d /home/runner/work/telegram/telegram/out/core/jvm/3.3.6/compile.dest/classes -deprecation true -feature true -language List(implicitConversions, higherKinds)
Error: [772] [error] java.lang.StackOverflowError
Error: [772] [error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1497)
Error: [772] [error] dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:49)
Error: [772] [error] dotty.tools.dotc.transform.Splicing$Level0QuoteTransformer$.transform(Splicing.scala:97)
Error: [772] [error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1544)
Error: [772] [error] dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:49)
Error: [772] [error] dotty.tools.dotc.transform.Splicing$Level0QuoteTransformer$.transform(Splicing.scala:97)
Error: [772] [error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1504)
Error: [772] [error] dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:49)
Error: [772] [error] dotty.tools.dotc.transform.Splicing$Level0QuoteTransformer$.transform(Splicing.scala:97)
Error: [772] [error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1573)
Error: [772] [error] dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:40)
Error: [772] [error] dotty.tools.dotc.transform.Splicing$Level0QuoteTransformer$.transform(Splicing.scala:97)
Error: [772] [error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform$$anonfun$1(Trees.scala:1614)
Error: [772] [error] scala.collection.immutable.List.mapConserve(List.scala:473)
Error: [772] [error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1614)
Error: [772] [error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transformSub(Trees.scala:1618)
Error: [772] [error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1544)
Error: [772] [error] dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:49)
Error: [772] [error] dotty.tools.dotc.transform.Splicing$Level0QuoteTransformer$.transform(Splicing.scala:97)
Error: [772] [error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1518)
Error: [772] [error] dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:49)
Error: [772] [error] dotty.tools.dotc.transform.Splicing$Level0QuoteTransformer$.transform(Splicing.scala:97)
Error: [772] [error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1544)
Error: [772] [error] dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:49)
Error: [772] [error] dotty.tools.dotc.transform.Splicing$Level0QuoteTransformer$.transform(Splicing.scala:97)
Error: [772] [error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1573)
Error: [772] [error] dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:40)
Error: [772] [error] dotty.tools.dotc.transform.Splicing$Level0QuoteTransformer$.transform(Splicing.scala:97)
Error: [772] [error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.loop$2(tpd.scala:1283)
Error: [772] [error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformStats(tpd.scala:1283)
Error: [772] [error] dotty.tools.dotc.ast.tpd$TreeMapWithPreciseStatContexts.transformBlock(tpd.scala:1288)
Error: [772] [error] dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1524)

WojciechMazur

WojciechMazur commented on Jul 7, 2025

@WojciechMazur
Contributor

This bug continuously (most of the time) appears on bot4s/telegram@e1325b4 commit even locally.

I've tried to reproduce it locally multiple times, but on my machine it always worked correctly with different versions of Scala 3 and JDK versions - MacOS M1 aarch64.

However what's interesting the StackOverflowErrror was triggered the first time I've tried to build on x86_64 Linux with JDK 11 (using gitpod). I have no idea why it platform might affect it, but seems like a worthy note when trying to minimize the issue.
What's also interesting in case of bot4s/telegram is fact that increasing -Xss to 5M (from default 1M) has not fixed the issue, it suggests there might be an actual problem in the compiler leading to infinite recursive call loop.

When trying to reproduce the issue outside the repo (and the external dependencies) I've only managed to get StackOverflowErrors during parser phase due to gargantuan for-comprehension block inspired by Message circe decoder from the repo.

When running with -Yprofile-trace I've once seen a graceful error, probably caused by exceeding recursive inline depth, but I don't remember it exactly. With profiling enabled there might be some small differences in symbols lookup (e.g. order) which could explain it.

Anyway I've not yet managed to obtain a reliable reproducer. The original repo was indeed crashing in gitpod, but there was a period in which is started to successfully compile (every compilation test involved cleaning the build tool result and running a fresh compilation)

seroperson

seroperson commented on Jul 7, 2025

@seroperson

My environment, just in case (WSL + JDK 17):

$ > java -version
openjdk version "17.0.7" 2023-04-18
OpenJDK Runtime Environment (build 17.0.7+7-nixos)
OpenJDK 64-Bit Server VM (build 17.0.7+7-nixos, mixed mode, sharing)
$ > uname -ar
Linux DESKTOP-PFPIT5H 6.6.87.1-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Mon Apr 21 17:08:54 UTC 2025 x86_64 GNU/Linux
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @seroperson@Gedochao@WojciechMazur@hearnadam@jchyb

        Issue actions

          StackOverflow during staging · Issue #22688 · scala/scala3