mirror of
https://github.com/sbt/sbt.git
synced 2026-09-06 09:37:02 +02:00
The cached-task macro allocated one mutable slot per syntactic Def.declareOutput / Def.declareOutputDirectory call site and snapshotted the slots into the task's outputs after the body ran. A call inside a loop or .map over a runtime-determined list is a single syntactic site executed many times, so each iteration overwrote the same slot and only the last file was cached and restored on a cache hit. There was also no way for a conditional call site that did not execute to stay out of the outputs: its slot remained null. Declared outputs now accumulate in a per-task ListBuffer: the macro emits one buffer at the top of the cached body and rewrites each call site to ActionCache.registerOutput(vf, buffer), which appends and returns the value. Every execution registers, an unexecuted site contributes nothing, and the static multi-site shape is unchanged. Refs #9462 (the declareOutput-in-a-loop half) Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]> Co-authored-by: eugene yokota <[email protected]>
709 B
709 B
Every Def.declareOutput call registers, including inside loops
The cached-task macro allocated one slot per syntactic Def.declareOutput (or
Def.declareOutputDirectory) call site, so a call inside a loop or .map over a
runtime-determined list of files overwrote the same slot on every iteration and
only the last file was cached and restored. Declared outputs now accumulate per
execution, so a dynamic number of outputs declared from one call site all
survive a cache hit. A declareOutput in a conditional branch that is not taken
no longer contributes a null entry to the task's outputs either.
This addresses the loop half of #9462.