Collects the sets a loop iterates with at at its ascending cadence. The index must be the
bare cadence identifier; copies and composite expressions are deliberately left out.
Walks a function body in statement order and, for each loop, flags the EnumerableSet remove
calls that corrupt that loopβs own iteration. The walk keeps, at every point, what each local
storage reference last named, so each loop is judged against the bindings standing where it
runs rather than against every binding of the function.
A resolved EnumerableSet call: which operation, on which set, and where its index sits. The
method form binds the set to the receiver, so its arguments start one position later than the
parameters they fill.
The storage location a set expression names: a base variable and the steps taken from it.
holders, pair.a and sets[1] each name one, and two of them are the same set exactly
when they are the same path.
The loopβs own indices that step upward unconditionally: a bare identifier advanced by i++,
i += <positive literal>, or i = i + <positive literal> (with either addition order) as a
straight-line statement of the body (a forβs desugared post-step lands here, a whileβs
in-body counter too). A step under a branch, a reset (i = 0), a no-op (i += 0), a decrement,
or composite arithmetic (i = (i + 2) - 1) does not qualify: the walk is only known to ascend
for the simple forms.
Whether every statement of a loop body runs on one straight line: no branch (if/try), no
jump (break/continue), no terminal statement, no inline assembly, and no nested loop. Bare
blocks are transparent. Any of these would let control skip a removal, skip the cadence step,
or leave the loop before a shifted slot is read, none of which this detector tracks, so their
presence makes it silent.
Walks the straight-line statements of a body, bare blocks included, and records variables
written by a supported ascending step separately from every other write or declaration. A
cadence is valid only when all of its writes are supported ascending steps.
Collects the variables written through an assignment target. Tuple assignment targets can
contain several identifiers; member and indexed targets do not write the base variable itself.
The variables a statement list writes through expressions, through the loops under it as well:
assignments (tuple targets included), increments, decrements, and deletes, wherever they sit.
The EnumerableSet at or remove a call dispatches to. Resolving through the type checker
covers the using for method form, the library-qualified form and import aliases. The library
is identified only by its kind and exact EnumerableSet name, not its source or behavior.
Whether receiver is a value of one of the set struct types declared in a library (or
contract) named EnumerableSet (AddressSet / UintSet / Bytes32Set), which tells the
bound method form apart from the library-qualified form.
The argument at position arg of a positional call, or the one a named call binds to the
calleeβs parameter at position parameter. Named arguments come in source order, which is
neither the parameter order nor, in the method form, the argument order.
Whether two set operands can name the same set. Two paths that can be read name the same set
exactly when they are equal; a path that cannot be read may be either.
The user-written body of a loop, peeled out of the synthetic condition guard the AST lowering
wraps it in. A for/while lowers to a single if (cond) { body } else break, its body
holding the user statements (and, for a for, the next-step); a do-while appends an
if (cond) continue else break after the user statements. Peeling these makes the guardβs
break/continue and the next-step read for what they are, not as user control flow. A body
that does not match the exact synthetic shape is returned unchanged.
The path a set expression names, or None when it cannot be read: an index that varies, a
call result, a reference without one straight-line binding, anything the analysis would have
to evaluate.
Walks the children of an expression while skipping short-circuit and ternary arms that a
literal boolean condition proves unreachable. Unknown conditions keep both possible arms.
What each local storage reference names at the point being analyzed, the latest entry
winning; None marks a reference no straight-line reading gives one answer for.