diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 10e56364ed3..d3dded22ab4 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -3,10 +3,6 @@ use std::{ rc::Rc, }; -use crate::{ - ast::ItemVisibility, graph::CrateGraph, hir_def::traits::ResolvedTraitBound, - node_interner::GlobalValue, usage_tracker::UsageTracker, StructField, StructType, TypeBindings, -}; use crate::{ ast::{ BlockExpression, FunctionKind, GenericTypeArgs, Ident, NoirFunction, NoirStruct, Param, @@ -41,6 +37,14 @@ use crate::{ token::SecondaryAttribute, Shared, Type, TypeVariable, }; +use crate::{ + ast::{ItemVisibility, UnresolvedType}, + graph::CrateGraph, + hir_def::traits::ResolvedTraitBound, + node_interner::GlobalValue, + usage_tracker::UsageTracker, + StructField, StructType, TypeBindings, +}; mod comptime; mod expressions; @@ -766,7 +770,9 @@ impl<'context> Elaborator<'context> { ) -> Vec { where_clause .iter_mut() - .flat_map(|constraint| self.add_missing_named_generics(&mut constraint.trait_bound)) + .flat_map(|constraint| { + self.add_missing_named_generics(&constraint.typ, &mut constraint.trait_bound) + }) .collect() } @@ -782,7 +788,11 @@ impl<'context> Elaborator<'context> { /// /// with a vector of `` returned so that the caller can then modify the function to: /// `fn foo() where T: Foo { ... }` - fn add_missing_named_generics(&mut self, bound: &mut TraitBound) -> Vec { + fn add_missing_named_generics( + &mut self, + object: &UnresolvedType, + bound: &mut TraitBound, + ) -> Vec { let mut added_generics = Vec::new(); let Ok(item) = self.resolve_path_or_error(bound.trait_path.clone()) else { @@ -796,6 +806,8 @@ impl<'context> Elaborator<'context> { let the_trait = self.get_trait_mut(trait_id); if the_trait.associated_types.len() > bound.trait_generics.named_args.len() { + let trait_name = the_trait.name.to_string(); + for associated_type in &the_trait.associated_types.clone() { if !bound .trait_generics @@ -806,10 +818,12 @@ impl<'context> Elaborator<'context> { // This generic isn't contained in the bound's named arguments, // so add it by creating a fresh type variable. let new_generic_id = self.interner.next_type_variable_id(); - let type_var = TypeVariable::unbound(new_generic_id, Kind::Normal); + let kind = associated_type.type_var.kind(); + let type_var = TypeVariable::unbound(new_generic_id, kind); let span = bound.trait_path.span; - let name = associated_type.name.clone(); + let name = format!("<{object} as {trait_name}>::{}", associated_type.name); + let name = Rc::new(name); let typ = Type::NamedGeneric(type_var.clone(), name.clone()); let typ = self.interner.push_quoted_type(typ); let typ = UnresolvedTypeData::Resolved(typ).with_span(span); diff --git a/test_programs/compile_success_empty/serialize/src/main.nr b/test_programs/compile_success_empty/serialize/src/main.nr index 66c79f9fc9d..a11fdf570d0 100644 --- a/test_programs/compile_success_empty/serialize/src/main.nr +++ b/test_programs/compile_success_empty/serialize/src/main.nr @@ -5,13 +5,12 @@ trait Serialize { fn serialize(self) -> [Field; Self::Size]; } -impl Serialize for (A, B) +impl Serialize for (A, B) where - A: Serialize, - B: Serialize, + A: Serialize, + B: Serialize, { - // let Size = ::Size + ::Size; - let Size: u32 = AS + BS; + let Size = ::Size + ::Size; fn serialize(self: Self) -> [Field; Self::Size] { let mut array: [Field; Self::Size] = std::mem::zeroed(); @@ -28,12 +27,11 @@ where } } -impl Serialize for [T; N] +impl Serialize for [T; N] where - T: Serialize, + T: Serialize, { - // let Size = ::Size * N; - let Size: u32 = TS * N; + let Size = ::Size * N; fn serialize(self: Self) -> [Field; Self::Size] { let mut array: [Field; Self::Size] = std::mem::zeroed();