The call axis: shapes that only exist between parameters (#198, step 4) - #407
Merged
Conversation
Every cell so far described one value in one position. Aliasing cannot be described that way: two parameters can name the same underlying resource, and what a binding must do about it is a property of the **call**. Both generators already say so in their own code — each emits an alias preflight under a rule about the whole parameter set (at least one consumed handle, and any other handle), and both docs note that the narrower reading, "two consumed parameters", misses the mixed cases. So calls are a second kind of cell, running through the same driver, the same compile check, the same header stage and the same ratchet. Eight of them, chosen around that rule rather than at random: pairs that must be guarded (consume/consume, consume/borrow, consume/optional), a pair that must **not** be (borrow/borrow — two `&T` to one resource is legal Rust and legal C, and a guard there would remove working surface), pairs in different resource domains where the question does not arise, and one three-parameter call with the consume last, since position within a call must not matter. All eight are expressible in both targets: `header` for C, `rustc` for JNI. No findings — the value is that a call shape becoming inexpressible now falls below a floor, and that the fixtures exist and are named for the stage that can run them. **What no cell here claims.** Whether the guard *fires* — rejecting the aliased call, sparing the unaliased one, running before ownership moves — is a claim about running code. It is not asserted against emitted text: a grep for a guard establishes that the text contains a guard, which is not the property anyone cares about, and this crate has been careful to report only what something mechanical established. Those three discriminations wait for the runtime stage. **Exit: answers move**, additively only: 16 new cells, 8 `header` and 8 `rustc`. No existing cell changed. Two integrity tests, in the spirit of the ones already here: every call parameter is a type the model accepts (or the call measures a fixture that never contained the shape it names), and every cell id is unique — an id is a file name, a receipt key and a guarantee key at once, so a collision would silently merge two cells, one reporting the other's diagnostics and inheriting the other's floor. Part of #198, tracked by #399.
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.
Step 4 of #198, on
shape-coverage(#402).The axis a per-value cell cannot express
Every cell so far described one value in one position. Aliasing cannot be described that way: two parameters can name the same underlying resource, and what a binding must do about it is a property of the call.
Both generators already say so in their own code. Each emits an alias preflight under a rule about the whole parameter set — at least one consumed handle, and any other handle — and both docs note that the narrower reading ("two consumed parameters") misses the mixed cases, where a borrow dangles the moment a consume takes ownership.
So calls are a second kind of cell, running through the same driver, compile check, header stage and ratchet. Eight, chosen around that rule rather than at random:
(Handle, Handle)(Handle, &Handle)(&Handle, &Handle)&Tto one resource is legal Rust and legal C(Handle, Option<Handle>)(Handle, Rec),(Handle, Sum)(Rec, Rec)(&Handle, &Handle, Handle)All eight are expressible in both targets —
headerfor C,rustcfor JNI. No findings. The value is that a call shape becoming inexpressible now falls below a floor, and that the fixtures exist and are named for the stage that can run them.What no cell here claims
Whether the guard fires — rejecting the aliased call, sparing the unaliased one, running before ownership moves — is a claim about running code.
I deliberately did not assert it against emitted text. A grep for a guard establishes that the text contains a guard, which is not the property anyone cares about, and this crate has been careful to report only what something mechanical established. Those three discriminations wait for the runtime stage, and the branch map now records them as its debt rather than as a checkbox this step ticked.
Exit: answers move, additively
16 new cells (8
header, 8rustc). No existing cell changed — verified by diffing the old report against the new one per cell, not by reading the diff.Two integrity tests
In the spirit of the ones already here:
headercell would be measuring a fixture that never contained the shape it names;Checks
cargo test -p shape-matrix(16 tests), clippy-D warningsacross all targets and features,cargo fmt --checkwith CI's config,RUSTDOCFLAGS=-D warnings cargo doc, andexamples/regen-check.shclean.