Emit the Kotlin too, and ask cbindgen for the header (#198, step 2b) - #405
Merged
Conversation
…#198, step 2b) Two stages a cell was passing without ever reaching. **JNI produced no Kotlin.** The driver called `write_rust` and stopped, so a `rustc` cell had shown half of what the target emits — the half that is not what a Kotlin caller ever sees. The binding now writes its Kotlin too, and a binding whose Kotlin cannot be written, or that produces none at all, is a rejection like any other. No cell moved: every JNI cell that emitted Rust also emits Kotlin, so this buys no new state today and closes the hole where one would have hidden. **C stopped at rustc, which is the wrong finish line.** What a C consumer gets is a header, produced from the emitted Rust by cbindgen, and the two can disagree: a signature rustc accepts can be one cbindgen skips or cannot name. `header` is now the top C state, pinned to the same cbindgen version `example-cbindgen` uses so this judges the header that example produces rather than another tool's opinion of the same Rust. The receipt is **not** "cbindgen returned `Ok`" — it returns `Ok` for a header that declares nothing. It is that the wrapper is declared: the name followed by an open parenthesis, since cbindgen carries doc comments through and a receipt that passes on prose is not a receipt. `the_header_stage_requires_a_declaration` is the discrimination check, with the negative control being the same Rust minus `extern "C"` — still valid, still parsed happily, still useless to a C caller. **Exit: answers move**, one class only: 45 cells `rustc` -> `header`. Every C cell whose Rust compiles also yields a header declaring its wrapper, so the stage adds evidence rather than findings. That is worth having anyway — it is the difference between "no C cell is known to be broken here" and "no C cell has been asked". The ladders now differ by target, and the report says so rather than levelling to the shorter one: C runs one stage further, JNI stops at rustc because this crate does not run the Kotlin compiler. Part of #198, tracked by #399.
The Kotlin is emitted but not compiled, so the JNI ladder still ends one stage short of C's.
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 2b of #198, on
shape-coverage(#402). Two stages cells were passing without ever reaching.JNI produced no Kotlin at all
The driver called
write_rustand stopped. So arustccell had shown half of what the target emits — and not the half a Kotlin caller ever sees. The binding now writes its Kotlin too, and a binding whose Kotlin cannot be written (or that produces none) is a rejection like any other.No cell moved. Every JNI cell that emits Rust also emits Kotlin, so this buys no new state today. It closes the hole where one would otherwise have hidden — a Kotlin-emission regression was previously invisible to every cell in the table.
C stopped at rustc, which is the wrong finish line
What a C consumer is given is a header, produced from the emitted Rust by cbindgen, and the two can disagree: a signature rustc is perfectly happy with can be one cbindgen skips, renders as an opaque it never defines, or cannot name. A cell whose wrapper is missing from the header is a cell no C program can call.
headeris now the top C state, pinned to the same cbindgen versionexample-cbindgenuses — so this judges the header that example produces, not another tool's opinion of the same Rust.The receipt is a declaration, not an
Okcbindgen returns
Okfor a header that declares nothing, so "it ran" would have been a state established by nothing. The receipt is that the wrapper is declared: the exported name at a word boundary followed by an open parenthesis, because cbindgen carries doc comments through and a receipt that can pass on prose is not a receipt.the_header_stage_requires_a_declarationis the discrimination check. The negative control is the same Rust withextern "C"removed — still valid Rust, still parsed happily, still useless to a C caller:Exit: answers move — one class, 45 cells
rustc→headerEvery C cell whose Rust compiles also yields a header declaring its wrapper. So this stage adds evidence, not findings — which is worth having on its own terms: it is the difference between "no C cell is known to be broken here" and "no C cell has been asked".
The ladders differ by target now
C runs one stage further than JNI, and the report says so rather than levelling to the shorter one — printing
rustcfor a C cell whose header is fine would throw away the stronger evidence.Left for 2c
The Kotlin is written but never compiled, so the JNI ladder still ends one stage short of C's; closing it needs kotlinc in CI.
RuntimeExercisedneeds the JVM covertest and the C smoke tests, under the same receipt rule.Checks
cargo test -p shape-matrix(10 tests), clippy-D warningson all targets and features,cargo fmt --checkwith CI's config,RUSTDOCFLAGS=-D warnings cargo doc, andexamples/regen-check.shclean with every other committed artifact byte-identical.