diff --git a/compiler/noirc_driver/src/abi_gen.rs b/compiler/noirc_driver/src/abi_gen.rs index 9d0d64b6300..e546cd822b7 100644 --- a/compiler/noirc_driver/src/abi_gen.rs +++ b/compiler/noirc_driver/src/abi_gen.rs @@ -33,7 +33,7 @@ pub(super) fn compute_function_abi( ) -> (Vec, Option) { let func_meta = context.def_interner.function_meta(func_id); - let (parameters, return_type) = func_meta.into_function_signature(); + let (parameters, return_type) = func_meta.function_signature(); let parameters = into_abi_params(context, parameters); let return_type = return_type.map(|typ| AbiType::from_type(context, &typ)); (parameters, return_type) diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index 8ada3faf756..e87ef34088d 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -542,6 +542,7 @@ pub(crate) fn check_methods_signatures( // TODO: This is not right since it may bind generic return types trait_method.return_type().unify(&resolved_return_type, &mut typecheck_errors, || { + let impl_method = resolver.interner.function_meta(func_id); let ret_type_span = impl_method.return_type.get_type().span; let expr_span = ret_type_span.expect("return type must always have a span"); diff --git a/compiler/noirc_frontend/src/hir/mod.rs b/compiler/noirc_frontend/src/hir/mod.rs index fc3ed06260f..c62f357167f 100644 --- a/compiler/noirc_frontend/src/hir/mod.rs +++ b/compiler/noirc_frontend/src/hir/mod.rs @@ -152,7 +152,7 @@ impl Context<'_> { None } - pub fn function_meta(&self, func_id: &FuncId) -> FuncMeta { + pub fn function_meta(&self, func_id: &FuncId) -> &FuncMeta { self.def_interner.function_meta(func_id) } diff --git a/compiler/noirc_frontend/src/hir/type_check/expr.rs b/compiler/noirc_frontend/src/hir/type_check/expr.rs index caa77852560..50ed98a794a 100644 --- a/compiler/noirc_frontend/src/hir/type_check/expr.rs +++ b/compiler/noirc_frontend/src/hir/type_check/expr.rs @@ -190,10 +190,11 @@ impl<'interner> TypeChecker<'interner> { // Automatically add `&mut` if the method expects a mutable reference and // the object is not already one. if *func_id != FuncId::dummy_id() { - let func_meta = self.interner.function_meta(func_id); + let function_type = + self.interner.function_meta(func_id).typ.clone(); self.try_add_mutable_reference_to_object( &mut method_call, - &func_meta.typ, + &function_type, &mut args, ); } @@ -561,7 +562,7 @@ impl<'interner> TypeChecker<'interner> { let func_meta = self.interner.function_meta(&func_id); let param_len = func_meta.parameters.len(); - (func_meta.typ, param_len) + (func_meta.typ.clone(), param_len) } HirMethodReference::TraitMethodId(method) => { let the_trait = self.interner.get_trait(method.trait_id); @@ -916,7 +917,7 @@ impl<'interner> TypeChecker<'interner> { &self.current_function.expect("unexpected method outside a function"), ); - for constraint in func_meta.trait_constraints { + for constraint in &func_meta.trait_constraints { if *object_type == constraint.typ { if let Some(the_trait) = self.interner.try_get_trait(constraint.trait_id) { for (method_index, method) in the_trait.methods.iter().enumerate() { diff --git a/compiler/noirc_frontend/src/hir/type_check/mod.rs b/compiler/noirc_frontend/src/hir/type_check/mod.rs index 092e8631f1b..c05c233fe34 100644 --- a/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -50,10 +50,15 @@ pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Vec Vec Vec Vec Vec Vec FunctionSignature { - // Doesn't use `self.return_type()` so we aren't working with references and don't need a `clone()` - let return_type = match self.typ { - Type::Function(_, ret, _env) => *ret, - Type::Forall(_, typ) => match *typ { - Type::Function(_, ret, _env) => *ret, - _ => unreachable!(), - }, - _ => unreachable!(), - }; - let return_type = match return_type { + pub fn function_signature(&self) -> FunctionSignature { + let return_type = match self.return_type() { Type::Unit => None, - typ => Some(typ), + typ => Some(typ.clone()), }; - - (self.parameters.0, return_type) + (self.parameters.0.clone(), return_type) } /// Gives the (uninstantiated) return type of this function. diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs index bb0972987e4..c24a2290011 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -20,7 +20,7 @@ use std::{ use crate::{ hir_def::{ expr::*, - function::{FuncMeta, FunctionSignature, Parameters}, + function::{FunctionSignature, Parameters}, stmt::{HirAssignStatement, HirLValue, HirLetStatement, HirPattern, HirStatement}, types, }, @@ -106,14 +106,14 @@ pub fn monomorphize(main: node_interner::FuncId, interner: &NodeInterner) -> Pro } let functions = vecmap(monomorphizer.finished_functions, |(_, f)| f); - let FuncMeta { return_distinctness, return_visibility, .. } = interner.function_meta(&main); + let meta = interner.function_meta(&main); Program::new( functions, function_sig, - return_distinctness, + meta.return_distinctness, monomorphizer.return_location, - return_visibility, + meta.return_visibility, ) } @@ -217,7 +217,7 @@ impl<'interner> Monomorphizer<'interner> { }, ); let main_meta = self.interner.function_meta(&main_id); - main_meta.into_function_signature() + main_meta.function_signature() } fn function(&mut self, f: node_interner::FuncId, id: FuncId) { @@ -237,7 +237,7 @@ impl<'interner> Monomorphizer<'interner> { _ => meta.return_type(), }); - let parameters = self.parameters(meta.parameters); + let parameters = self.parameters(&meta.parameters); let body = self.expr(body_expr_id); let unconstrained = modifiers.is_unconstrained @@ -254,17 +254,17 @@ impl<'interner> Monomorphizer<'interner> { /// Monomorphize each parameter, expanding tuple/struct patterns into multiple parameters /// and binding any generic types found. - fn parameters(&mut self, params: Parameters) -> Vec<(ast::LocalId, bool, String, ast::Type)> { + fn parameters(&mut self, params: &Parameters) -> Vec<(ast::LocalId, bool, String, ast::Type)> { let mut new_params = Vec::with_capacity(params.len()); - for parameter in params { - self.parameter(parameter.0, ¶meter.1, &mut new_params); + for (parameter, typ, _) in ¶ms.0 { + self.parameter(parameter, typ, &mut new_params); } new_params } fn parameter( &mut self, - param: HirPattern, + param: &HirPattern, typ: &HirType, new_params: &mut Vec<(ast::LocalId, bool, String, ast::Type)>, ) { @@ -276,11 +276,11 @@ impl<'interner> Monomorphizer<'interner> { new_params.push((new_id, definition.mutable, name, self.convert_type(typ))); self.define_local(ident.id, new_id); } - HirPattern::Mutable(pattern, _) => self.parameter(*pattern, typ, new_params), + HirPattern::Mutable(pattern, _) => self.parameter(pattern, typ, new_params), HirPattern::Tuple(fields, _) => { let tuple_field_types = unwrap_tuple_type(typ); - for (field, typ) in fields.into_iter().zip(tuple_field_types) { + for (field, typ) in fields.iter().zip(tuple_field_types) { self.parameter(field, &typ, new_params); } } @@ -288,7 +288,8 @@ impl<'interner> Monomorphizer<'interner> { let struct_field_types = unwrap_struct_type(typ); assert_eq!(struct_field_types.len(), fields.len()); - let mut fields = btree_map(fields, |(name, field)| (name.0.contents, field)); + let mut fields = + btree_map(fields, |(name, field)| (name.0.contents.clone(), field)); // Iterate over `struct_field_types` since `unwrap_struct_type` will always // return the fields in the order defined by the struct type. @@ -1183,7 +1184,7 @@ impl<'interner> Monomorphizer<'interner> { let parameters = vecmap(lambda.parameters, |(pattern, typ)| (pattern, typ, Visibility::Private)).into(); - let parameters = self.parameters(parameters); + let parameters = self.parameters(¶meters); let body = self.expr(lambda.body); let id = self.next_function_id(); @@ -1234,7 +1235,7 @@ impl<'interner> Monomorphizer<'interner> { let parameters = vecmap(lambda.parameters, |(pattern, typ)| (pattern, typ, Visibility::Private)).into(); - let mut converted_parameters = self.parameters(parameters); + let mut converted_parameters = self.parameters(¶meters); let id = self.next_function_id(); let name = lambda_name.to_owned(); diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index 261b11158cf..9d310b595de 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -768,12 +768,12 @@ impl NodeInterner { } /// Returns the interned meta data corresponding to `func_id` - pub fn function_meta(&self, func_id: &FuncId) -> FuncMeta { - self.func_meta.get(func_id).cloned().expect("ice: all function ids should have metadata") + pub fn function_meta(&self, func_id: &FuncId) -> &FuncMeta { + self.func_meta.get(func_id).expect("ice: all function ids should have metadata") } - pub fn try_function_meta(&self, func_id: &FuncId) -> Option { - self.func_meta.get(func_id).cloned() + pub fn try_function_meta(&self, func_id: &FuncId) -> Option<&FuncMeta> { + self.func_meta.get(func_id) } pub fn function_ident(&self, func_id: &FuncId) -> crate::Ident {