Make Emit a registry-owned callback key - #401
Conversation
a52d2d4 to
a6bddec
Compare
There was a problem hiding this comment.
Pull request overview
Moves emission ownership into the registry while retaining rendering operations in the independent flat-model crate.
Changes:
- Adds registry-owned
Emitand flat-ownedRustEmitter. - Migrates adapters, callbacks, tests, and shape rendering.
- Restricts direct syntax access and redacts captured syntax from
Debug.
Reviewed changes
Copilot reviewed 32 out of 32 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
README.md |
Updates crate responsibilities. |
docs/crate-split.md |
Documents the new emission boundary. |
prebindgen-flat/Cargo.toml |
Removes the flat testing feature. |
prebindgen-flat/src/lib.rs |
Exports RustEmitter. |
prebindgen-flat/src/flat/emit.rs |
Introduces the rendering protocol. |
prebindgen-flat/src/flat/mod.rs |
Removes enum_item and updates guidance. |
prebindgen-flat/src/flat/origin.rs |
Restricts spelling and redacts debug output. |
prebindgen-flat/src/flat/spell.rs |
Updates shape-rendering documentation. |
prebindgen-flat/src/flat/ty.rs |
Restricts direct type spelling. |
prebindgen-flat/src/flat/tests/roundtrip.rs |
Migrates rendering tests. |
prebindgen-registry/Cargo.toml |
Moves test-key support into registry. |
prebindgen-registry/src/emit.rs |
Adds the registry-owned Emit key. |
prebindgen-registry/src/lib.rs |
Exports registry Emit. |
prebindgen-registry/src/prebindgen.rs |
Updates callback capability types. |
prebindgen-registry/src/write.rs |
Mints the registry emission key. |
prebindgen-registry/src/write/tests.rs |
Migrates write tests. |
prebindgen-registry/src/test_util.rs |
Adds test-only spelling support. |
prebindgen-registry/src/unfold.rs |
Uses diagnostic type display. |
prebindgen-registry/src/unfold/plan.rs |
Updates emission documentation. |
prebindgen-registry/src/unfold/tests.rs |
Imports test spelling support. |
prebindgen-registry/src/expand/plan.rs |
Updates emission documentation. |
prebindgen-registry/src/expand/tests.rs |
Imports test spelling support. |
prebindgen-registry/src/registry/declare.rs |
Passes registry Emit to converters. |
prebindgen-registry/src/registry/mod.rs |
Adjusts private-link documentation. |
prebindgen-registry/src/registry/scan.rs |
Adjusts private-link documentation. |
prebindgen-registry/src/registry/tests.rs |
Migrates registry tests and enum lookup. |
prebindgen-c/src/trait_impl.rs |
Uses shape-specific rendering methods. |
prebindgen-jni/Cargo.toml |
Removes flat testing feature usage. |
prebindgen-jni/src/jni/fn_plan.rs |
Updates spelling guidance. |
prebindgen-jni/src/jni/struct_plan.rs |
Uses diagnostic display. |
prebindgen-jni/src/jni/emit/flat_input.rs |
Uses shape-specific rendering methods. |
prebindgen-jni/src/jni/emit/sum_out.rs |
Uses alternative rendering. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
ReviewThe refactor itself is good: But the headline claim does not hold as written. The seal is not restored — an adapter can still forge one, with no extra dependency
Verified against use prebindgen_registry::flat::emit::RustEmitter;
pub struct Forge;
impl RustEmitter for Forge {}
// no Emit anywhere: classification code spelling captured syntax
pub fn decision_code_spells(t: &prebindgen_registry::flat::TypeRef) -> proc_macro2::TokenStream {
Forge.spell(t)
}Compiles. So relative to #375, the mint moved from That makes these overstated:
One-word change that buys most of it backMake the module private and keep the root re-export: -pub mod emit;
+pub(crate) mod emit;
Verified on top of the branch: Consider also not re-exporting Then say what is actually trueCross-crate friend visibility does not exist, so the honest end state is: the default path is compiler-checked, and the residual is a convention. That convention is now precisely greppable in a way the retired "count the doors" metric never was — one trait name, one impl form: Three lines of CI, and it cannot be walked around without naming the trait. Worth more than the current paragraph claiming enforcement. Smaller things
Net: merge the mechanical part happily. Either land the |
|
Addressed the full review in e85c00e:
Local validation is green: focused compile-fail doctests, full workspace tests, workspace Clippy with warnings denied, rustdoc with warnings denied, formatting, diff checks, and the new policy guard. — Codex (GPT-5) |
Summary
prebindgen -> prebindgen-flat -> prebindgen-registry -> adaptersdependency directionprebindgen-flat, with a registry-owned unconstructableEmitcallback keyflat::emitfrom registry-only adapters while retaining the rootprebindgen_flat::RustEmitterpath for independent collectorsDeref<dyn RustEmitter>, keepingemit.spell(ty)ergonomic without duplicating the rendering APIFlat::enum_itemtest helperBoundary
The default registry path is compiler-checked:
prebindgen-registrydeliberately does not re-exportRustEmitter.prebindgen-flat::flat::emitis crate-private.Emitor name the rendering protocol; they render only after a callback receives&Emit.Independent use remains intact. Another collector can depend directly on
prebindgen-flat, implement the publicRustEmitterprotocol for its own key, and establish a separate rendering boundary without involving the registry.Rust cannot prevent an adapter from deliberately adding that direct dependency. That residual is explicit in both
Cargo.tomlandimpl RustEmitter; workspace CI now rejects such implementations inprebindgen-candprebindgen-jni.The trait remains object-safe. The old generic
shapeoperation becomes the unambiguousshape_struct,shape_alternative, andshape_enum_valuemethods. The flattestingfeature is no longer needed; registry test code usesprebindgen-registry/testing.Other API cleanup
Emitis a private-field tuple struct, and its compile-fail example now tests privacy directly withEmit(()).Originretains derivedDebugfor resolver diagnostics;Debugis documented as diagnostic output rather than structured syntax access.ReturnTypeMismatch.actualnow uses canonicalTypeKeydisplay, matching the already-canonicaldeclaredside, rather than captured source spelling.Validation
cargo fmt --all -- --checkcargo test -p prebindgen-flat -p prebindgen-registry --all-features --doccargo test --workspace --all-features --quietcargo clippy --workspace --all-features --all-targets -- -D warningsRUSTDOCFLAGS=-Dwarnings cargo doc -p prebindgen-flat -p prebindgen-registry --all-features --no-depsCloses #375