Repository navigation
steins-syntax: a statement lists each read its expressions write, at the read's own span with the construct that carries it (#1050 S1, ADR-0104) - #1062
Merged
Conversation
3 tasks
…nditional, a first-class callable folds its context, and the rule table is in the module doc with a test per row (#1050)
zonuexe
force-pushed
the
claude/rp-s1-read-positions
branch
from
October 11, 2026 09:45
5ee567b to
a4d269c
Compare
…its arguments, and the ADR names the CallRef consumer and the key-deprecation gap (#1050)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Slice S1 of the read-position run (#1050). It adds the IR that S2–S4 will judge: each statement lists the call, offset, property and class-constant reads written in its own expressions. Each read sits at its own span and carries what the construct around it means for the read. ADR-0104 records the owner's decision D1: a finding about a read is reported at the read's own span.
What changed
steins-syntax:ReadPosition { kind, span, carrier }holds one read.kindisCall(span only),Offset { place, key },ProporClassConst.carrieris one ofPlain,Argument { call, position },Conditional,IssetLike,Suppressed,CompoundReadorFirstClassCallable.Stmt.read_positionsisOption<Box<[_]>>, so a statement with no reads costs one word.lower_read.rs(new):static.match. An anonymous class keeps only its constructor arguments.match-arm routes fill the list too.Argument.positionisNonefor a named argument or one at or after a spread.isset,empty,??or??=. A class constant read there stays asIssetLike.checkoutput is byte-identical. NoSCHEMA_VERSIONbump is needed:PackageShardholds noStmt, and trace payloads are decoded past the gate.Memory
The first cut cloned a
CallExprper call read and re-lowered nested calls, which cost 25–31% peak RSS. The reworked payload stores spans, a smallPlace/Keyand boxed names instead.size_of::<ReadPosition>()is at most 40 bytes, and a test pins that bound.Peak RSS, release build, strict, median of 3 runs:
Wall time is within noise.
Tests
crates/steins-syntax/tests/it/read_positions.rshas 30 tests. They cover every carrier and every boundary, plus the size bound and the place/key content. The syntax, infer and xtask suites pass, and workspace clippy and rustdoc pass with-D warnings.Measurement
Ten public packages × strict and default: all 20 outputs are byte-identical.
Not measured
Review outcome
Adversarial review: three rounds, now approved.
?->is now Conditional.?->in a static-call class operand ($n?->s::m(…),($n?->p)::m(…)). This is fixed in e72776f.ReadKind::CallRef, with the context folded into the carrier. S2's "FCC existence" row consumeskind == CallRef.$a[$n?->p]['k14'][] = 1is not recorded. ADR-0104 notes it.