Weird macro recursive inline limit infinite loop bug/crash
See original GitHub issueMaximal number of successive inlines exceeds when using Scala 3 Macros across various dependent files.
Compiler version
3.0.0-RC1
Minimized code
Please see attached sample zipped project. This issue only appears to surface when having definitions across multiple files. I currently found 3 workaround so far, but the underlying issue remains.
- If you either omit
Transactions.scala
and remove its reference, property inChain.scala
, - Change Transaction to use derive instead, like
case class Transaction( sender: Address, recipient: Address, value: Long) derives Codec.AsObject
- Group all the definitions in a single file as in here, it works too.
To Reproduce:
- Unzip the file.
- Run
sbt run
in the directory.
Output
Without default flags
[error] -- Error: /Users/swoorup.joshi/IdeaProjects/temp/LBAbOJMVT1260OKUnBXuzw/src/main/scala/blockchain/Chain.scala:25:27
[error] 25 |given Encoder[ChainLink] = deriveEncoder[ChainLink]
[error] | ^^^^^^^^^^^^^^^^^^^^^^^^
[error] | Maximal number of successive inlines (32) exceeded,
[error] | Maybe this is caused by a recursive inline method?
[error] | You can use -Xmax-inlines to change the limit.
[error] | This location contains code that was inlined from Chain.scala:25
[error] | This location contains code that was inlined from Derivation.scala:47
[error] | This location contains code that was inlined from Derivation.scala:16
[error] | This location contains code that was inlined from Derivation.scala:38
[error] | This location contains code that was inlined from Derivation.scala:12
[error] | This location contains code that was inlined from Derivation.scala:50
[error] | This location contains code that was inlined from Derivation.scala:16
[error] | This location contains code that was inlined from Derivation.scala:38
[error] | This location contains code that was inlined from Derivation.scala:38
[error] | This location contains code that was inlined from Derivation.scala:12
[error] | This location contains code that was inlined from Derivation.scala:50
[error] | This location contains code that was inlined from Derivation.scala:16
[error] | This location contains code that was inlined from Derivation.scala:38
[error] | This location contains code that was inlined from Derivation.scala:12
[error] | This location contains code that was inlined from Derivation.scala:50
[error] | This location contains code that was inlined from Derivation.scala:16
[error] | This location contains code that was inlined from Derivation.scala:38
[error] | This location contains code that was inlined from Derivation.scala:38
[error] | This location contains code that was inlined from Derivation.scala:12
[error] | This location contains code that was inlined from Derivation.scala:50
[error] | This location contains code that was inlined from Derivation.scala:16
[error] | This location contains code that was inlined from Derivation.scala:38
[error] | This location contains code that was inlined from Derivation.scala:12
[error] | This location contains code that was inlined from Derivation.scala:50
[error] | This location contains code that was inlined from Derivation.scala:16
[error] | This location contains code that was inlined from Derivation.scala:38
[error] | This location contains code that was inlined from Derivation.scala:38
[error] | This location contains code that was inlined from Derivation.scala:38
[error] | This location contains code that was inlined from Derivation.scala:38
[error] | This location contains code that was inlined from Derivation.scala:12
[error] | This location contains code that was inlined from Derivation.scala:50
[error] | This location contains code that was inlined from semiauto.scala:27
[error] one error found
[error] one error found
Using max inlines -Xmax-inlines 10000000
flag does not do any justice either, it runs into stack overflow.
With max inlines
java.lang.StackOverflowError while compiling /Users/swoorup.joshi/IdeaProjects/temp/LBAbOJMVT1260OKUnBXuzw/src/main/scala/blockchain/Chain.scala, /Users/swoorup.joshi/IdeaProjects/temp/LBAbOJMVT1260OKUnBX
uzw/src/main/scala/blockchain/Transaction.scala, /Users/swoorup.joshi/IdeaProjects/temp/LBAbOJMVT1260OKUnBXuzw/src/main/scala/main.scala
[error] ## Exception when compiling 3 sources to /Users/swoorup.joshi/IdeaProjects/temp/LBAbOJMVT1260OKUnBXuzw/target/scala-3.0.0-RC1/classes
[error] java.lang.StackOverflowError
[error] dotty.tools.dotc.ast.Positioned.sourcePos(Positioned.scala:52)
[error] dotty.tools.dotc.report$.recur$1(report.scala:119)
[error] dotty.tools.dotc.report$.recur$1(report.scala:119)
[error] dotty.tools.dotc.report$.recur$1(report.scala:119)
[error] dotty.tools.dotc.report$.recur$1(report.scala:119)
Expectation
[info] running Main
{
"index" : 1,
"proof" : 2,
"previousHash" : "",
"values" : [
],
"timestamp" : 1615684763839
}
The same example in scastie works however, when everything is lumped together in a single file. https://scastie.scala-lang.org/LBAbOJMVT1260OKUnBXuzw
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:6 (4 by maintainers)
Top Results From Across the Web
Recursive macro makes infinite recursion - Stack Overflow
I changed the recursion_limit to 128 and higher, but the compiler error message just increase as well. Even when I call n!(0) it...
Read more >High-order recursive macro to define several similar macro at ...
programming - High-order recursive macro to define several similar macro at once does infinite loop - TeX - LaTeX Stack Exchange. Stack ...
Read more >https://sajtr.ga/FRI/Novo/2019-2020/UNI-2.letnik/P...
... report by Mark Shinwell) - PR#6564: infinite loop in Mtype.remove_aliases ... not terminating on some lazy values w/ recursive types (Xavier Leroy, ......
Read more >ocaml-base-compiler.4.10.0/Changes - OCaml Docs - OCamlPro
46, provides a compatibility macro with the old name, but programs ... 1662, - #7847, #2019: Fix an infinite loop that could occur...
Read more >By Thread - Linux-Kernel Archive
[patch] sched: fix macro -> inline function conversion bug Ingo Molnar (Mon Jul 03 ... Re: 2.6.17-mm one process gets stuck in infinite...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
The zipped example works fine when:
given Encoder[Transaction] = blockchain.given_Encoder_Transaction
in Chain.scala.List[Transaction]
with justTransaction
.Also, the Scastie breaks if you use two different packages to separate the definitions: https://scastie.scala-lang.org/heksesang/Vr8kHxhURgWxQBmGcxB9ww/6
Based on the observations above, I think the problem is most likely the same as https://github.com/lampepfl/dotty/issues/11538 and thus fixed in RC2.
The thing that breaks the derivation is the fact that there is a
List[Transaction]
coupled with the bug mentioned above. The implicit circe uses forEncoder[List[A]]
requires an implicitEncoder[A]
. When it looks for aEncoder[List[Transaction]]
, it uses this implicit, but because of it does not find an implicitEncoder[Transaction]
, thesummonFrom
defaults to trying to derive anEncoder[List[Transaction]]
, and that causes some infinite recursion.If you create
case class A(val i: Int)
, do not derive anEncoder[A]
, but try to callderiveEncoder[List[A]]
you will see the same problem.If my deductions are correct, this is not a dotty bug, but a circe bug.
Sounds like we can close this then, thanks!