Skip to content

feat(kernels-derive): reject malformed PrepareKernel slots - #2134

Open
quangvdao wants to merge 2 commits into
mainfrom
quang/kernels-derive-slot-diagnostics
Open

quangvdao wants to merge 2 commits into
mainfrom
quang/kernels-derive-slot-diagnostics

Conversation

@quangvdao

Copy link
Copy Markdown
Collaborator

#[derive(KernelSlots)] now rejects a malformed PrepareKernel slot at its declaration instead of skipping it.

Why

The derive emitted one PrepareKernel<F, R> impl per field of type exactly Box<dyn PrepareKernel<F, R>> and skipped every other field. A slot written with an extra object bound (+ Send), a wrapper (Option<Box<…>>) or the wrong number of type arguments was skipped too, so the registry silently lost that impl. The error then appeared as an unsatisfied PrepareKernel bound at whichever stage impl needed the slot, far from the field that caused it.

What

  • jolt-kernels-derive: a field whose type mentions the identifier PrepareKernel anywhere but is not exactly Box<dyn PrepareKernel<F, R>> is a derive error spanned at that field's type: "a KernelSlots slot must be exactly Box<dyn PrepareKernel<F, R>>". All such fields are reported in one pass (syn::Error::combine). Fields that never mention PrepareKernel (commit, joint_opening, the fronts) are still skipped. The emitted impls for valid slots are unchanged.
  • The check is syntactic. A slot spelled through a type alias or a renamed import never mentions PrepareKernel, so it is still skipped and still surfaces as a missing bound. The crate docs, the PrepareKernel trait docs and specs/prover-stage-drivers.md now say this.

Tests

crates/jolt-kernels-derive/src/tests.rs (new) calls expand directly. It checks that an extra object bound, an Option wrapper and a one-element tuple are each rejected with the message above, and that a struct with one valid slot, a three-argument slot, a bare PrepareKernel field and an ordinary field reports exactly two errors. It also checks that a valid slot next to a &'static str field and a bespoke boxed trait field expands to exactly one PrepareKernel<F, R> impl.

Verification

cargo fmt --all --check; cargo clippy -p jolt-kernels-derive -p jolt-kernels -p jolt-prover --all-targets -- -D warnings (JoltBackend in jolt-kernels uses the derive); cargo nextest run -p jolt-kernels-derive (5 passed) and -p jolt-kernels (152 passed).

KernelSlots skipped any field whose type did not parse as exactly
Box<dyn PrepareKernel<F, R>>, so a slot with an extra bound, a wrapper
or a wrong argument count vanished from the registry and surfaced as a
missing-bound error at a distant stage impl. Fields that name
PrepareKernel in another shape are now a derive error at the field,
with every such field reported at once. Fields that never name it are
still skipped.
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

📏 PR diff

Note

Actual code changed: 61 lines

🟢 +44 added    🔴 −17 removed

Tests, docs, fixtures, and helper scripts excluded.

Category 🟢 Added 🔴 Removed
⌨️ Actual code +44 −17
🧪 Tests +88 0
📚 Docs +20 −15
📦 Fixtures 0 0
🔧 Helper scripts 0 0
Total diff +152 −32

Every changed line is classified once.

@quangvdao quangvdao changed the title jolt-kernels-derive: reject malformed PrepareKernel slots feat(kernels-derive): reject malformed PrepareKernel slots Oct 23, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant