From 1df102a1ee0eb39dcbada50e10b226c7f7be0f26 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:07:37 +0100 Subject: [PATCH] fix: preserve generic kind on trait methods (#6099) # Description ## Problem\* Resolves #6100 ## Summary\* It seems that #5156 has resulted in problems in unifying numeric generics in trait impl methods. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- .../noirc_frontend/src/elaborator/traits.rs | 4 +-- compiler/noirc_frontend/src/tests.rs | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/traits.rs b/compiler/noirc_frontend/src/elaborator/traits.rs index 9263fe9c67d..0faaf409e6c 100644 --- a/compiler/noirc_frontend/src/elaborator/traits.rs +++ b/compiler/noirc_frontend/src/elaborator/traits.rs @@ -288,10 +288,10 @@ pub(crate) fn check_trait_impl_method_matches_declaration( // Substitute each generic on the trait function with the corresponding generic on the impl function for ( ResolvedGeneric { type_var: trait_fn_generic, .. }, - ResolvedGeneric { name, type_var: impl_fn_generic, .. }, + ResolvedGeneric { name, type_var: impl_fn_generic, kind, .. }, ) in trait_fn_meta.direct_generics.iter().zip(&meta.direct_generics) { - let arg = Type::NamedGeneric(impl_fn_generic.clone(), name.clone(), Kind::Normal); + let arg = Type::NamedGeneric(impl_fn_generic.clone(), name.clone(), kind.clone()); bindings.insert(trait_fn_generic.id(), (trait_fn_generic.clone(), arg)); } diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index 0b8773eea77..e21db0790d7 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -3700,3 +3700,28 @@ fn use_non_u32_generic_in_struct() { let errors = get_program_errors(src); assert_eq!(errors.len(), 0); } + +#[test] +fn use_numeric_generic_in_trait_method() { + let src = r#" + trait Foo { + fn foo(self, x: [u8; N]) -> Self; + } + + struct Bar; + + impl Foo for Bar { + fn foo(self, _x: [u8; N]) -> Self { + self + } + } + + fn main() { + let _ = Bar{}.foo([1,2,3]); + } + "#; + + let errors = get_program_errors(src); + println!("{errors:?}"); + assert_eq!(errors.len(), 0); +}