Skip to content

fix(frontend): report trait/impl method generic kind mismatches instead of panicking - #13659

Draft
AztecBot wants to merge 1 commit into
masterfrom
cb/ninv-trait-generic-kinds
Draft

AztecBot wants to merge 1 commit into
masterfrom
cb/ninv-trait-generic-kinds

Conversation

@AztecBot

Copy link
Copy Markdown
Collaborator

Summary

When an impl method declares a generic with a different kind from the trait method's generic at the same position (a type parameter on one side, a numeric generic on the other), check_trait_impl_method_matches_declaration recorded a trait-to-impl binding whose recorded kind contradicted its replacement. If the trait method bounds that generic, the bound is substituted through the binding and the kind assert! in Type::substitute_helper aborts the compiler (nargo check exits 101 with a Rust panic).

This PR compares the two kinds before recording the binding:

  • A type-parameter/numeric-generic mismatch is reported as a new TypeCheckError::GenericKindMismatch, located at the impl method's generic: "f declares its generic Q as a numeric generic of type u32 but the trait declares a type parameter".
  • The mismatched pair is left unbound, so nothing downstream substitutes an ill-kinded binding.
  • Two numeric generics of different types (u32 vs u64) are already reported by generic resolution ("The numeric generic is not of type u64"). They are also left unbound, but not reported a second time.

Invariant

This enforces two entries in the Noir audit's invariant register:

  • ninv:trait-impls-conform-to-declarations: an impl is accepted only if every method matches its trait's declaration in generic count, generic kind, parameter types and bounds, and any mismatch is a diagnostic.
  • ninv:no-panic-on-user-input: no source program makes the compiler panic.

Refs noir-lang/noir-claude#1711. That finding also suggests renaming derive_hash's hasher parameter from H to H_ in noir_stdlib/src/hash/mod.nr, so that #[derive(Hash)] on a struct with a generic named H compiles. That rename is not in this PR, and the issue stays open for it. With this PR that case produces diagnostics instead of a panic.

Changes

  • compiler/noirc_frontend/src/elaborator/traits.rs: kind comparison in the trait-method/impl-method generic pairing loop.
  • compiler/noirc_frontend/src/hir/type_check/errors.rs: TypeCheckError::GenericKindMismatch and its diagnostic.
  • compiler/noirc_frontend/src/tests/traits/trait_impl_validation.rs: four tests.
    • trait_impl_method_numeric_generic_for_bounded_type_parameter: the reproducer from the finding; it panics without the fix (see below).
    • trait_impl_method_type_parameter_for_numeric_generic: the reverse direction.
    • trait_impl_method_numeric_generic_of_different_type: u32 vs u64 is still an error and is not reported twice.
    • trait_impl_method_generic_kinds_that_match_are_accepted: matching kinds under different names compile.

Testing

  • cargo test -p noirc_frontend -- tests::traits: 351 passed.
  • Red check: with the traits.rs change stashed, trait_impl_method_numeric_generic_for_bounded_type_parameter fails with panicked at compiler/noirc_frontend/src/hir_def/types.rs:2963:29: while substituting (unbound): expected kind of unbound TypeVariable (Normal) to match the kind of its binding (Numeric(u32)).
  • nargo check with this branch, on both reproducers from the finding: the plain-Noir trait impl, and #[derive(std::hash::Hash)] struct B<let H: u32> { x: [Field; H] }. Both now exit with diagnostics instead of a panic.
  • cargo fmt --all -- --check and cargo clippy -p noirc_frontend --tests are clean.

Created by claudebox · group: slackbot · requested by Tom (@TomAFrench) · Slack thread

@TomAFrench
TomAFrench force-pushed the cb/ninv-trait-generic-kinds branch from 542c4af to 5f60f5b Compare September 16, 2026 15:06

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant