Returns one index path per back-edge -- per slot that closes a
reference loop in `value`. An empty array means the value is acyclic.
Breaking (or deleting) exactly the returned slots would make the value
loop-free; break_cycles() does that in one call.
Path syntax, concatenated from the outermost container inward:
[3] array item 3
.2 class field 2 (declaration order)
["name"] mapping value under key "name"
[key <map>] a mapping KEY (the key itself continues the path)
(args) a function pointer's captured argument list
(result) a promise's settled value
(reaction) one pending reaction of a promise: its fulfillment
handler, its rejection handler, the promise it
chains to, or -- when the reaction holds a parked
async frame -- that frame's result promise
(parked frame)
a saved value-stack slot of a parked async frame
(parked defer)
a pending defer() handler of a parked async frame
Which slot of a loop is reported depends on traversal order (array
index order, mapping table order), so treat the paths as diagnostics,
not as a stable contract. Long string keys are truncated in the
rendering.
The traversal is iterative and has no nesting-depth limit.