Skip to content

Commit

Permalink
fix: preserve generic kind on trait methods (#6099)
Browse files Browse the repository at this point in the history
# 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.
  • Loading branch information
TomAFrench authored Sep 19, 2024
1 parent 3d9d072 commit 1df102a
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/elaborator/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

Expand Down
25 changes: 25 additions & 0 deletions compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<let N: u32>(self, x: [u8; N]) -> Self;
}
struct Bar;
impl Foo for Bar {
fn foo<let N: u32>(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);
}

0 comments on commit 1df102a

Please sign in to comment.