Expand description
The value-semantics copy lint.
Collections and records are VALUES in LOGOS: Let opens be b's opens. binds opens to a
COPY of b’s field, not a reference to it. vdom.lg did this at four sites —
Let opens be b's opens.
Pop from opens into at.— popping the copy and never touching b’s own opens again, so the value b actually
holds never changes. A new author reaches for exactly this shape, because it reads as if it
mutates b in place.
CopyLintScope fires when a local is bound from a field access (b's opens, a's b's c)
or another local read by name (Let a be b. — a local is copied the same way a field is), is
then mutated through Pop/Push/Add/Remove/Set item … of …/Set …'s field, and after
its LAST such mutation is never read again and never written back to where it came from. It
is a WARNING, not an error: using the copy as scratch space and discarding it is legitimate,
so a read of any kind (handing it to a function, Showing it, using it as another
statement’s condition) after the last mutation silences the lint entirely.
One scope tracks one function/action/handler body — see
Parser::parse_statement for where each statement, at every nesting
depth (a Repeat/If/While body included — all of them recurse back through the same
per-statement dispatch a scope observes through), feeds into whichever scope is currently
open. A local’s tracked lifetime is until it is next bound to something else (a second Let
of the same name finalizes the first binding’s story right there) or the function ends —
deliberately NOT scoped tighter to a nested block, matching how a Repeat body’s Let
re-runs and re-copies every iteration regardless of where its own block happens to end.
What this deliberately does not chase, so a missed case only ever means a MISSED warning
(never a wrong one): a read inside a nested closure body, an interpolated view template, or a
page-test Dom query. A local’s value crossing into one of those is read there in a way this
pass has no reason to disbelieve, so it stays conservative rather than silent about the gap.
Structs§
- Copy
Lint Scope - One function/action/handler body’s worth of tracking state — see the module doc comment.
- Finding