diff --git a/compiler/noirc_arena/src/lib.rs b/compiler/noirc_arena/src/lib.rs index 0bf9b5058e9..39b0b54f711 100644 --- a/compiler/noirc_arena/src/lib.rs +++ b/compiler/noirc_arena/src/lib.rs @@ -6,14 +6,6 @@ use std::fmt; #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)] pub struct Index(usize); -impl Index { - /// Return a dummy index (max value internally). - /// This should be avoided over `Option` if possible. - pub fn dummy() -> Self { - Self(usize::MAX) - } -} - impl fmt::Display for Index { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) diff --git a/compiler/noirc_frontend/src/elaborator/comptime.rs b/compiler/noirc_frontend/src/elaborator/comptime.rs index 2aba18af63a..25398aaa59e 100644 --- a/compiler/noirc_frontend/src/elaborator/comptime.rs +++ b/compiler/noirc_frontend/src/elaborator/comptime.rs @@ -88,7 +88,7 @@ impl<'context> Elaborator<'context> { let meta = elaborator.interner.function_meta(&function); elaborator.current_item = Some(DependencyId::Function(function)); elaborator.crate_id = meta.source_crate; - elaborator.local_module = meta.source_module; + elaborator.local_module = Some(meta.source_module); elaborator.introduce_generics_into_scope(meta.all_generics.clone()); } }) @@ -106,7 +106,7 @@ impl<'context> Elaborator<'context> { self.elaborate_item_from_comptime(reason, f, |elaborator| { elaborator.current_item = None; elaborator.crate_id = module.krate; - elaborator.local_module = module.local_id; + elaborator.local_module = Some(module.local_id); }) } @@ -318,7 +318,7 @@ impl<'context> Elaborator<'context> { attribute_context: AttributeContext, attributes_to_run: &mut CollectedAttributes, ) -> Result<(), CompilationError> { - self.local_module = attribute_context.attribute_module; + self.local_module = Some(attribute_context.attribute_module); let kind = match &attribute.name { MetaAttributeName::Path(path) => ExpressionKind::Variable(path.clone()), @@ -381,7 +381,7 @@ impl<'context> Elaborator<'context> { location: Location, generated_items: &mut CollectedItems, ) -> Result<(), CompilationError> { - self.local_module = attribute_context.module; + self.local_module = Some(attribute_context.module); let mut interpreter = self.setup_interpreter(); let mut arguments = Self::handle_attribute_arguments( @@ -447,7 +447,7 @@ impl<'context> Elaborator<'context> { if ¶meters[0] != expected_type { return Err(InterpreterError::TypeMismatch { - expected: parameters[0].clone(), + expected: parameters[0].to_string(), actual: expected_type.clone(), location, } @@ -504,7 +504,7 @@ impl<'context> Elaborator<'context> { &mut errors, || { CompilationError::InterpreterError(InterpreterError::TypeMismatch { - expected: param_type.clone(), + expected: param_type.to_string(), actual: expr_type.clone(), location: arg_location, }) @@ -551,6 +551,8 @@ impl<'context> Elaborator<'context> { /// (e.g., module declarations and submodules) would require additional def-map updates /// thus potentially affecting the source order of attributes and would not be safe during elaboration. fn add_item(&mut self, item: Item, generated_items: &mut CollectedItems, location: Location) { + let local_module = self.local_module(); + match item.kind { ItemKind::Function(function) => { let module_id = self.module_id(); @@ -564,7 +566,7 @@ impl<'context> Elaborator<'context> { item.doc_comments, &mut self.errors, ) { - let functions = vec![(self.local_module, id, function)]; + let functions = vec![(local_module, id, function)]; generated_items.functions.push(UnresolvedFunctions { file_id: location.file, functions, @@ -580,12 +582,12 @@ impl<'context> Elaborator<'context> { &mut trait_impl, self.crate_id, location.file, - self.local_module, + local_module, ); generated_items.trait_impls.push(UnresolvedTraitImpl { file_id: location.file, - module_id: self.local_module, + module_id: local_module, r#trait: trait_impl.r#trait, object_type: trait_impl.object_type, methods, @@ -611,7 +613,7 @@ impl<'context> Elaborator<'context> { Documented::new(global, item.doc_comments), visibility, location.file, - self.local_module, + local_module, self.crate_id, ); @@ -626,7 +628,7 @@ impl<'context> Elaborator<'context> { self.def_maps.get_mut(&self.crate_id).unwrap(), self.usage_tracker, Documented::new(struct_def, item.doc_comments), - self.local_module, + local_module, self.crate_id, &mut self.errors, ) { @@ -640,7 +642,7 @@ impl<'context> Elaborator<'context> { self.usage_tracker, Documented::new(enum_def, item.doc_comments), location.file, - self.local_module, + local_module, self.crate_id, &mut self.errors, ) { diff --git a/compiler/noirc_frontend/src/elaborator/enums.rs b/compiler/noirc_frontend/src/elaborator/enums.rs index bcbc5c7c37e..59199689d93 100644 --- a/compiler/noirc_frontend/src/elaborator/enums.rs +++ b/compiler/noirc_frontend/src/elaborator/enums.rs @@ -116,7 +116,7 @@ impl Row { impl Elaborator<'_> { pub(super) fn collect_enum_definitions(&mut self, enums: &BTreeMap) { for (type_id, typ) in enums { - self.local_module = typ.module_id; + self.local_module = Some(typ.module_id); self.generics.clear(); let datatype = self.interner.get_type(*type_id); diff --git a/compiler/noirc_frontend/src/elaborator/expressions.rs b/compiler/noirc_frontend/src/elaborator/expressions.rs index 3fc299646e6..b6d71feee7e 100644 --- a/compiler/noirc_frontend/src/elaborator/expressions.rs +++ b/compiler/noirc_frontend/src/elaborator/expressions.rs @@ -688,22 +688,18 @@ impl Elaborator<'_> { .func_id(self.interner) .expect("Expected trait function to be a DefinitionKind::Function"); - let generics = if func_id != FuncId::dummy_id() { - let function_type = self.interner.function_meta(&func_id).typ.clone(); - self.try_add_mutable_reference_to_object(&function_type, &mut object_type, &mut object); - let generics = method_call.generics; - let generics = generics.map(|generics| { - vecmap(generics, |generic| { - let location = generic.location; - let wildcard_allowed = true; - let typ = self.use_type_with_kind(generic, &Kind::Any, wildcard_allowed); - Located::from(location, typ) - }) - }); - self.resolve_function_turbofish_generics(&func_id, generics, location) - } else { - None - }; + let function_type = self.interner.function_meta(&func_id).typ.clone(); + self.try_add_mutable_reference_to_object(&function_type, &mut object_type, &mut object); + let generics = method_call.generics; + let generics = generics.map(|generics| { + vecmap(generics, |generic| { + let location = generic.location; + let wildcard_allowed = true; + let typ = self.use_type_with_kind(generic, &Kind::Any, wildcard_allowed); + Located::from(location, typ) + }) + }); + let generics = self.resolve_function_turbofish_generics(&func_id, generics, location); let location = object_location.merge(method_name_location); diff --git a/compiler/noirc_frontend/src/elaborator/function.rs b/compiler/noirc_frontend/src/elaborator/function.rs index ba59a6cbedc..0d5c78c8305 100644 --- a/compiler/noirc_frontend/src/elaborator/function.rs +++ b/compiler/noirc_frontend/src/elaborator/function.rs @@ -71,7 +71,7 @@ impl Elaborator<'_> { extra_constraints: &[(TraitConstraint, Location)], ) { for (local_module, id, func) in &mut function_set.functions { - self.local_module = *local_module; + self.local_module = Some(*local_module); self.recover_generics(|this| { this.define_function_meta(func, *id, None, extra_constraints); }); @@ -86,7 +86,7 @@ impl Elaborator<'_> { local_module: crate::hir::def_map::LocalModuleId, function_sets: &mut Vec<(UnresolvedGenerics, Location, UnresolvedFunctions)>, ) { - self.local_module = local_module; + self.local_module = Some(local_module); for (generics, _, function_set) in function_sets { // Prepare the impl @@ -240,7 +240,7 @@ impl Elaborator<'_> { is_entry_point, has_inline_attribute: func.has_inline_attribute(), source_crate: self.crate_id, - source_module: self.local_module, + source_module: self.local_module(), function_body: FunctionBody::Unresolved(func.kind, body, func.def.location), self_type: self.self_type.clone(), source_file: location.file, @@ -453,7 +453,7 @@ impl Elaborator<'_> { "Functions in other crates should be already elaborated" ); - self.local_module = func_meta.source_module; + self.local_module = Some(func_meta.source_module); self.self_type = func_meta.self_type.clone(); self.current_trait_impl = func_meta.trait_impl; diff --git a/compiler/noirc_frontend/src/elaborator/globals.rs b/compiler/noirc_frontend/src/elaborator/globals.rs index c2056f308b2..3f06b8f9443 100644 --- a/compiler/noirc_frontend/src/elaborator/globals.rs +++ b/compiler/noirc_frontend/src/elaborator/globals.rs @@ -54,7 +54,7 @@ impl Elaborator<'_> { fn elaborate_global(&mut self, global: UnresolvedGlobal) { // Set up the elaboration context for this global. We need to ensure that name resolution // happens in the module where the global was defined, not where it's being referenced. - let old_module = std::mem::replace(&mut self.local_module, global.module_id); + let old_module = std::mem::replace(&mut self.local_module, Some(global.module_id)); let old_item = self.current_item.take(); let global_id = global.global_id; diff --git a/compiler/noirc_frontend/src/elaborator/impls.rs b/compiler/noirc_frontend/src/elaborator/impls.rs index bb519ecd27d..73364e005d4 100644 --- a/compiler/noirc_frontend/src/elaborator/impls.rs +++ b/compiler/noirc_frontend/src/elaborator/impls.rs @@ -112,7 +112,7 @@ impl Elaborator<'_> { impls: &mut [(UnresolvedGenerics, Location, UnresolvedFunctions)], self_type: &UnresolvedType, ) { - self.local_module = module; + self.local_module = Some(module); for (generics, location, unresolved) in impls { self.check_generics_appear_in_types(generics, &[self_type], &[]); diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 8feb61873bf..10fac35fbfb 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -224,8 +224,8 @@ pub struct Elaborator<'context> { function_context: Vec, /// The current module this elaborator is in. - /// Initially empty, it is set whenever a new top-level item is resolved. - local_module: LocalModuleId, + /// Initially None, it is set whenever a new top-level item is resolved. + local_module: Option, /// True if we're elaborating a comptime item such as a comptime function, /// block, global, or attribute. @@ -306,7 +306,7 @@ impl<'context> Elaborator<'context> { lambda_stack: Vec::new(), self_type: None, current_item: None, - local_module: LocalModuleId::dummy_id(), + local_module: None, crate_id, resolving_ids: BTreeSet::new(), trait_bounds: Vec::new(), @@ -322,6 +322,10 @@ impl<'context> Elaborator<'context> { } } + pub(crate) fn local_module(&self) -> LocalModuleId { + self.local_module.expect("local_module is unset") + } + pub fn from_context( context: &'context mut Context, crate_id: CrateId, @@ -565,7 +569,7 @@ impl<'context> Elaborator<'context> { } fn elaborate_trait_impl(&mut self, trait_impl: UnresolvedTraitImpl) { - self.local_module = trait_impl.module_id; + self.local_module = Some(trait_impl.module_id); self.generics = trait_impl.resolved_generics.clone(); self.current_trait_impl = trait_impl.impl_id; @@ -576,7 +580,7 @@ impl<'context> Elaborator<'context> { self.remove_trait_impl_assumed_trait_implementations(trait_impl.impl_id); for (module, function, noir_function) in &trait_impl.methods.functions { - self.local_module = *module; + self.local_module = Some(*module); let errors = check_trait_impl_method_matches_declaration( self.interner, *function, @@ -603,7 +607,7 @@ impl<'context> Elaborator<'context> { } fn define_type_alias(&mut self, alias_id: TypeAliasId, alias: UnresolvedTypeAlias) { - self.local_module = alias.module_id; + self.local_module = Some(alias.module_id); let name = &alias.type_alias_def.name; let visibility = alias.type_alias_def.visibility; diff --git a/compiler/noirc_frontend/src/elaborator/scope.rs b/compiler/noirc_frontend/src/elaborator/scope.rs index c5b68f54117..adc1102e45d 100644 --- a/compiler/noirc_frontend/src/elaborator/scope.rs +++ b/compiler/noirc_frontend/src/elaborator/scope.rs @@ -2,7 +2,7 @@ use crate::ast::{ERROR_IDENT, Ident}; use crate::elaborator::path_resolution::PathResolution; -use crate::hir::def_map::{LocalModuleId, ModuleId}; +use crate::hir::def_map::ModuleId; use crate::hir::scope::{Scope as GenericScope, ScopeTree as GenericScopeTree}; use crate::{ @@ -25,16 +25,14 @@ type ScopeTree = GenericScopeTree; impl Elaborator<'_> { pub fn module_id(&self) -> ModuleId { - assert_ne!(self.local_module, LocalModuleId::dummy_id(), "local_module is unset"); - ModuleId { krate: self.crate_id, local_id: self.local_module } + ModuleId { krate: self.crate_id, local_id: self.local_module() } } pub fn replace_module(&mut self, new_module: ModuleId) -> ModuleId { - assert_ne!(new_module.local_id, LocalModuleId::dummy_id(), "local_module is unset"); let current_module = self.module_id(); self.crate_id = new_module.krate; - self.local_module = new_module.local_id; + self.local_module = Some(new_module.local_id); current_module } diff --git a/compiler/noirc_frontend/src/elaborator/structs.rs b/compiler/noirc_frontend/src/elaborator/structs.rs index dad93367975..e6c9feb925f 100644 --- a/compiler/noirc_frontend/src/elaborator/structs.rs +++ b/compiler/noirc_frontend/src/elaborator/structs.rs @@ -35,7 +35,7 @@ impl Elaborator<'_> { // Resolve each field in each struct. // Each struct should already be present in the NodeInterner after def collection. for (type_id, typ) in structs { - self.local_module = typ.module_id; + self.local_module = Some(typ.module_id); let fields = self.resolve_struct_fields(&typ.struct_def, *type_id); diff --git a/compiler/noirc_frontend/src/elaborator/trait_impls.rs b/compiler/noirc_frontend/src/elaborator/trait_impls.rs index e25fd13b95b..9f5241605fd 100644 --- a/compiler/noirc_frontend/src/elaborator/trait_impls.rs +++ b/compiler/noirc_frontend/src/elaborator/trait_impls.rs @@ -4,7 +4,6 @@ use crate::{ Kind, NamedGeneric, ResolvedGeneric, Shared, TypeBindings, TypeVariable, ast::{GenericTypeArgs, Ident, UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression}, elaborator::{PathResolutionMode, types::bind_ordered_generics}, - graph::CrateId, hir::{ def_collector::{ dc_crate::{CompilationError, UnresolvedTraitImpl}, @@ -31,7 +30,7 @@ use super::Elaborator; impl Elaborator<'_> { pub(super) fn collect_trait_impl(&mut self, trait_impl: &mut UnresolvedTraitImpl) { - self.local_module = trait_impl.module_id; + self.local_module = Some(trait_impl.module_id); self.current_trait_impl = trait_impl.impl_id; let self_type = trait_impl.methods.self_type.clone(); @@ -204,7 +203,7 @@ impl Elaborator<'_> { trait_impl: &mut UnresolvedTraitImpl, trait_impl_where_clause: &[TraitConstraint], ) { - self.local_module = trait_impl.module_id; + self.local_module = Some(trait_impl.module_id); let impl_id = trait_impl.impl_id.expect("impl_id should be set in define_function_metas"); @@ -405,15 +404,15 @@ impl Elaborator<'_> { trait_id: TraitId, trait_impl: &UnresolvedTraitImpl, ) { - self.local_module = trait_impl.module_id; + self.local_module = Some(trait_impl.module_id); let object_crate = match &trait_impl.resolved_object_type { - Some(Type::DataType(struct_type, _)) => struct_type.borrow().id.krate(), - _ => CrateId::Dummy, + Some(Type::DataType(struct_type, _)) => Some(struct_type.borrow().id.krate()), + _ => None, }; let the_trait = self.interner.get_trait(trait_id); - if self.crate_id != the_trait.crate_id && self.crate_id != object_crate { + if self.crate_id != the_trait.crate_id && Some(self.crate_id) != object_crate { self.push_err(DefCollectorErrorKind::TraitImplOrphaned { location: trait_impl.object_type.location, }); @@ -671,7 +670,7 @@ impl Elaborator<'_> { &mut self, trait_impl: &mut UnresolvedTraitImpl, ) -> Vec<(TraitConstraint, Location)> { - self.local_module = trait_impl.module_id; + self.local_module = Some(trait_impl.module_id); let (trait_id, trait_generics, path_location) = self.resolve_trait_impl_trait_path(trait_impl); diff --git a/compiler/noirc_frontend/src/elaborator/traits.rs b/compiler/noirc_frontend/src/elaborator/traits.rs index 9ee0c0a80f1..dcc150bed01 100644 --- a/compiler/noirc_frontend/src/elaborator/traits.rs +++ b/compiler/noirc_frontend/src/elaborator/traits.rs @@ -199,7 +199,7 @@ impl Elaborator<'_> { /// 4. Resolves the trait's bounds (its listed super traits). pub fn collect_traits(&mut self, traits: &mut BTreeMap) { for (trait_id, unresolved_trait) in traits { - self.local_module = unresolved_trait.module_id; + self.local_module = Some(unresolved_trait.module_id); self.recover_generics(|this| { this.current_trait = Some(*trait_id); @@ -277,7 +277,7 @@ impl Elaborator<'_> { /// method bodies are not elaborated. pub fn collect_trait_methods(&mut self, traits: &mut BTreeMap) { for (trait_id, unresolved_trait) in traits { - self.local_module = unresolved_trait.module_id; + self.local_module = Some(unresolved_trait.module_id); self.recover_generics(|this| { this.current_trait = Some(*trait_id); @@ -609,7 +609,7 @@ impl Elaborator<'_> { trait_id: TraitId, unresolved_trait: &UnresolvedTrait, ) -> Vec { - self.local_module = unresolved_trait.module_id; + self.local_module = Some(unresolved_trait.module_id); let mut functions = vec![]; diff --git a/compiler/noirc_frontend/src/graph/mod.rs b/compiler/noirc_frontend/src/graph/mod.rs index 01a6cbc42a0..82e8b6bc1e4 100644 --- a/compiler/noirc_frontend/src/graph/mod.rs +++ b/compiler/noirc_frontend/src/graph/mod.rs @@ -20,25 +20,20 @@ pub enum CrateId { /// In that case there's only one crate, and it's both the root /// crate and the stdlib crate. RootAndStdlib(usize), - Dummy, } impl CrateId { - pub fn dummy_id() -> CrateId { - CrateId::Dummy - } - pub fn is_stdlib(&self) -> bool { match self { CrateId::Stdlib(_) | CrateId::RootAndStdlib(_) => true, - CrateId::Root(_) | CrateId::Crate(_) | CrateId::Dummy => false, + CrateId::Root(_) | CrateId::Crate(_) => false, } } pub fn is_root(&self) -> bool { match self { CrateId::Root(_) | CrateId::RootAndStdlib(_) => true, - CrateId::Stdlib(_) | CrateId::Crate(_) | CrateId::Dummy => false, + CrateId::Stdlib(_) | CrateId::Crate(_) => false, } } } @@ -251,9 +246,6 @@ impl CrateGraph { Some((CrateId::Stdlib(_), _)) | Some((CrateId::RootAndStdlib(_), _)) => { panic!("ICE: Tried to re-add the stdlib crate as a regular crate") } - Some((CrateId::Dummy, _)) => { - panic!("ICE: A dummy CrateId should not exist in the CrateGraph") - } None => { let data = CrateData { root_file_id: file_id, dependencies: Vec::new() }; let crate_id = CrateId::Crate(self.arena.len()); diff --git a/compiler/noirc_frontend/src/hir/comptime/errors.rs b/compiler/noirc_frontend/src/hir/comptime/errors.rs index 62def6fe91a..fef579b73ff 100644 --- a/compiler/noirc_frontend/src/hir/comptime/errors.rs +++ b/compiler/noirc_frontend/src/hir/comptime/errors.rs @@ -23,7 +23,7 @@ pub enum InterpreterError { location: Location, }, TypeMismatch { - expected: Type, + expected: String, actual: Type, location: Location, }, diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index bfed380880e..4f0b0f907a0 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -487,7 +487,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { (value, _) => { let actual = value.get_type().into_owned(); Err(InterpreterError::TypeMismatch { - expected: typ.clone(), + expected: typ.to_string(), actual, location, }) @@ -524,7 +524,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { Ok(()) } value => Err(InterpreterError::TypeMismatch { - expected: typ.clone(), + expected: typ.to_string(), actual: value.get_type().into_owned(), location, }), diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index d95382a5449..626b9ba9187 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -71,16 +71,14 @@ impl Interpreter<'_, '_> { "apply_range_constraint" => { self.call_foreign("range", arguments, return_type, location) } - "array_as_str_unchecked" => array_as_str_unchecked(interner, arguments, location), - "array_len" => array_len(interner, arguments, location), + "array_as_str_unchecked" => array_as_str_unchecked(arguments, location), + "array_len" => array_len(arguments, location), "array_refcount" => Ok(Value::U32(0)), "assert_constant" => Ok(Value::Unit), - "as_slice" => as_slice(interner, arguments, location), + "as_slice" => as_slice(arguments, location), "ctstring_eq" => ctstring_eq(arguments, location), "ctstring_hash" => ctstring_hash(arguments, location), - "derive_pedersen_generators" => { - derive_generators(interner, arguments, return_type, location) - } + "derive_pedersen_generators" => derive_generators(arguments, return_type, location), "expr_as_array" => expr_as_array(interner, arguments, return_type, location), "expr_as_assert" => expr_as_assert(interner, arguments, return_type, location), "expr_as_assert_eq" => expr_as_assert_eq(interner, arguments, return_type, location), @@ -125,8 +123,8 @@ impl Interpreter<'_, '_> { "expr_resolve" => expr_resolve(self, arguments, location), "is_unconstrained" => Ok(Value::Bool(true)), "field_less_than" => field_less_than(arguments, location), - "fmtstr_as_ctstring" => fmtstr_as_ctstring(interner, arguments, location), - "fmtstr_quoted_contents" => fmtstr_quoted_contents(interner, arguments, location), + "fmtstr_as_ctstring" => fmtstr_as_ctstring(arguments, location), + "fmtstr_quoted_contents" => fmtstr_quoted_contents(arguments, location), "fresh_type_variable" => fresh_type_variable(interner), "function_def_add_attribute" => function_def_add_attribute(self, arguments, location), "function_def_as_typed_expr" => function_def_as_typed_expr(self, arguments, location), @@ -180,16 +178,16 @@ impl Interpreter<'_, '_> { "quoted_eq" => quoted_eq(self.elaborator.interner, arguments, location), "quoted_hash" => quoted_hash(arguments, location), "quoted_tokens" => quoted_tokens(arguments, location), - "slice_insert" => slice_insert(interner, arguments, location), - "slice_pop_back" => slice_pop_back(interner, arguments, location, call_stack), - "slice_pop_front" => slice_pop_front(interner, arguments, location, call_stack), - "slice_push_back" => slice_push_back(interner, arguments, location), - "slice_push_front" => slice_push_front(interner, arguments, location), + "slice_insert" => slice_insert(arguments, location), + "slice_pop_back" => slice_pop_back(arguments, location, call_stack), + "slice_pop_front" => slice_pop_front(arguments, location, call_stack), + "slice_push_back" => slice_push_back(arguments, location), + "slice_push_front" => slice_push_front(arguments, location), "slice_refcount" => Ok(Value::U32(0)), - "slice_remove" => slice_remove(interner, arguments, location, call_stack), + "slice_remove" => slice_remove(arguments, location, call_stack), "static_assert" => static_assert(interner, arguments, location, call_stack), - "str_as_bytes" => str_as_bytes(interner, arguments, location), - "str_as_ctstring" => str_as_ctstring(interner, arguments, location), + "str_as_bytes" => str_as_bytes(arguments, location), + "str_as_ctstring" => str_as_ctstring(arguments, location), "to_be_radix" => to_be_radix(arguments, return_type, location), "to_le_radix" => to_le_radix(arguments, return_type, location), "to_be_bits" => to_be_bits(arguments, return_type, location), @@ -280,63 +278,45 @@ fn failing_constraint( }) } -fn array_len( - interner: &NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn array_len(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let (argument, argument_location) = check_one_argument(arguments, location)?; match argument { Value::Array(values, _) | Value::Slice(values, _) => Ok(Value::U32(values.len() as u32)), value => { - let type_var = Box::new(interner.next_type_variable()); - let expected = Type::Array(type_var.clone(), type_var); + let expected = "array".to_string(); let actual = value.get_type().into_owned(); Err(InterpreterError::TypeMismatch { expected, actual, location: argument_location }) } } } -fn array_as_str_unchecked( - interner: &NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn array_as_str_unchecked(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let argument = check_one_argument(arguments, location)?; - let array = get_array(interner, argument)?.0; + let array = get_array(argument)?.0; let string_bytes = try_vecmap(array, |byte| get_u8((byte, location)))?; let string = String::from_utf8_lossy(&string_bytes).into_owned(); Ok(Value::String(Rc::new(string))) } -fn as_slice( - interner: &NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn as_slice(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let (array, array_location) = check_one_argument(arguments, location)?; match array { Value::Array(values, Type::Array(_, typ)) => Ok(Value::Slice(values, Type::Slice(typ))), value => { - let type_var = Box::new(interner.next_type_variable()); - let expected = Type::Array(type_var.clone(), type_var); + let expected = "array".to_string(); let actual = value.get_type().into_owned(); Err(InterpreterError::TypeMismatch { expected, actual, location: array_location }) } } } -fn slice_push_back( - interner: &NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn slice_push_back(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let (slice, (element, _)) = check_two_arguments(arguments, location)?; - let (mut values, typ) = get_slice(interner, slice)?; + let (mut values, typ) = get_slice(slice)?; values.push_back(element); Ok(Value::Slice(values, typ)) } @@ -359,13 +339,9 @@ fn static_assert( } } -fn str_as_bytes( - interner: &NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn str_as_bytes(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let string = check_one_argument(arguments, location)?; - let string = get_str(interner, string)?; + let string = get_str(string)?; let bytes: Vector = string.bytes().map(Value::U8).collect(); let byte_array_type = byte_array_type(bytes.len()); @@ -373,13 +349,9 @@ fn str_as_bytes( } // fn str_as_ctstring(self) -> CtString -fn str_as_ctstring( - interner: &NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn str_as_ctstring(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let self_argument = check_one_argument(arguments, location)?; - let string = get_str(interner, self_argument)?; + let string = get_str(self_argument)?; Ok(Value::CtString(string)) } @@ -391,7 +363,7 @@ fn type_def_add_attribute( ) -> IResult { let (self_argument, attribute) = check_two_arguments(arguments, location)?; let attribute_location = attribute.1; - let attribute = get_str(interner, attribute)?; + let attribute = get_str(attribute)?; let attribute = format!("#[{attribute}]"); let mut parser = Parser::for_str(&attribute, attribute_location.file); let Some((Attribute::Secondary(attribute), _span)) = parser.parse_attribute() else { @@ -417,7 +389,7 @@ fn type_def_add_generic( ) -> IResult { let (self_argument, generic) = check_two_arguments(arguments, location)?; let generic_location = generic.1; - let generic = get_str(interner, generic)?; + let generic = get_str(generic)?; let mut tokens = lex(&generic, location); if tokens.len() != 1 { @@ -493,7 +465,7 @@ fn type_def_as_type_with_generics( let type_def = type_def_rc.borrow(); let generics_location = generics.1; - let (generics, _) = get_slice(interner, generics)?; + let (generics, _) = get_slice(generics)?; let generics = try_vecmap(generics, |generic| get_type((generic, generics_location)))?; let correct_generic_count = type_def.generics.len() == generics.len(); @@ -517,21 +489,24 @@ fn type_def_generics( let type_def = interner.get_type(type_id); let type_def = type_def.borrow(); - let expected = Type::Slice(Box::new(Type::Tuple(vec![ - Type::Quoted(QuotedType::Type), - interner.next_type_variable(), // Option - ]))); + let expected = || { + Type::Slice(Box::new(Type::Tuple(vec![ + Type::Quoted(QuotedType::Type), + interner.next_type_variable(), // Option + ]))) + .to_string() + }; let actual = return_type.clone(); let slice_item_type = match return_type { Type::Slice(item_type) => *item_type, - _ => return Err(InterpreterError::TypeMismatch { expected, actual, location }), + _ => return Err(InterpreterError::TypeMismatch { expected: expected(), actual, location }), }; let option_typ = match &slice_item_type { Type::Tuple(types) if types.len() == 2 => types[1].clone(), - _ => return Err(InterpreterError::TypeMismatch { expected, actual, location }), + _ => return Err(InterpreterError::TypeMismatch { expected: expected(), actual, location }), }; let generics = type_def @@ -568,7 +543,7 @@ fn type_def_has_named_attribute( let (self_argument, name) = check_two_arguments(arguments, location)?; let type_id = get_type_id(self_argument)?; - let name = get_str(interner, name)?; + let name = get_str(name)?; Ok(Value::Bool(has_named_attribute(&name, interner.type_attributes(&type_id), interner))) } @@ -588,7 +563,7 @@ fn type_def_fields( let struct_def = struct_def.borrow(); let args_location = generic_args.1; - let generic_args = get_slice(interner, generic_args)?.0; + let generic_args = get_slice(generic_args)?.0; let generic_args = try_vecmap(generic_args, |arg| get_type((arg, args_location)))?; let actual = generic_args.len(); @@ -701,10 +676,10 @@ fn type_def_set_fields( let mut struct_def = struct_def.borrow_mut(); let field_location = fields.1; - let fields = get_slice(elaborator.interner, fields)?.0; + let fields = get_slice(fields)?.0; let fields = fields .into_iter() - .flat_map(|field_pair| get_tuple(elaborator.interner, (field_pair, field_location))) + .flat_map(|field_pair| get_tuple((field_pair, field_location))) .enumerate() .collect::>(); @@ -742,8 +717,7 @@ fn type_def_set_fields( } } } else { - let type_var = elaborator.interner.next_type_variable(); - let expected = Type::Tuple(vec![type_var.clone(), type_var]); + let expected = "tuple".to_string(); let actual = Type::Tuple(vecmap(&field_pair, |value| value.borrow().get_type().into_owned())); @@ -757,14 +731,13 @@ fn type_def_set_fields( } fn slice_remove( - interner: &mut NodeInterner, arguments: Vec<(Value, Location)>, location: Location, call_stack: &Vector, ) -> IResult { let (slice, index) = check_two_arguments(arguments, location)?; - let (mut values, typ) = get_slice(interner, slice)?; + let (mut values, typ) = get_slice(slice)?; let index = get_u32(index)? as usize; if values.is_empty() { @@ -783,27 +756,22 @@ fn slice_remove( Ok(Value::Tuple(vec![Shared::new(Value::Slice(values, typ)), element])) } -fn slice_push_front( - interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn slice_push_front(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let (slice, (element, _)) = check_two_arguments(arguments, location)?; - let (mut values, typ) = get_slice(interner, slice)?; + let (mut values, typ) = get_slice(slice)?; values.push_front(element); Ok(Value::Slice(values, typ)) } fn slice_pop_front( - interner: &mut NodeInterner, arguments: Vec<(Value, Location)>, location: Location, call_stack: &Vector, ) -> IResult { let argument = check_one_argument(arguments, location)?; - let (mut values, typ) = get_slice(interner, argument)?; + let (mut values, typ) = get_slice(argument)?; match values.pop_front() { Some(element) => { Ok(Value::Tuple(vec![Shared::new(element), Shared::new(Value::Slice(values, typ))])) @@ -813,14 +781,13 @@ fn slice_pop_front( } fn slice_pop_back( - interner: &mut NodeInterner, arguments: Vec<(Value, Location)>, location: Location, call_stack: &Vector, ) -> IResult { let argument = check_one_argument(arguments, location)?; - let (mut values, typ) = get_slice(interner, argument)?; + let (mut values, typ) = get_slice(argument)?; match values.pop_back() { Some(element) => { Ok(Value::Tuple(vec![Shared::new(Value::Slice(values, typ)), Shared::new(element)])) @@ -829,14 +796,10 @@ fn slice_pop_back( } } -fn slice_insert( - interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn slice_insert(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let (slice, index, (element, _)) = check_three_arguments(arguments, location)?; - let (mut values, typ) = get_slice(interner, slice)?; + let (mut values, typ) = get_slice(slice)?; let index = get_u32(index)? as usize; values.insert(index, element); Ok(Value::Slice(values, typ)) @@ -2444,24 +2407,16 @@ fn unwrap_expr_value(interner: &NodeInterner, mut expr_value: ExprValue) -> Expr } // fn fmtstr_as_ctstring(self) -> CtString -fn fmtstr_as_ctstring( - interner: &NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn fmtstr_as_ctstring(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let self_argument = check_one_argument(arguments, location)?; - let (string, _) = get_format_string(interner, self_argument)?; + let (string, _) = get_format_string(self_argument)?; Ok(Value::CtString(string)) } // fn quoted_contents(self) -> Quoted -fn fmtstr_quoted_contents( - interner: &NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn fmtstr_quoted_contents(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let self_argument = check_one_argument(arguments, location)?; - let (string, _) = get_format_string(interner, self_argument)?; + let (string, _) = get_format_string(self_argument)?; let tokens = lex(&string, location); Ok(Value::Quoted(Rc::new(tokens))) } @@ -2479,7 +2434,7 @@ fn function_def_add_attribute( ) -> IResult { let (self_argument, attribute) = check_two_arguments(arguments, location)?; let attribute_location = attribute.1; - let attribute = get_str(interpreter.elaborator.interner, attribute)?; + let attribute = get_str(attribute)?; let attribute = format!("#[{attribute}]"); let mut parser = Parser::for_str(&attribute, attribute_location.file); let Some((attribute, _span)) = parser.parse_attribute() else { @@ -2580,7 +2535,7 @@ fn function_def_has_named_attribute( let (self_argument, name) = check_two_arguments(arguments, location)?; let func_id = get_function_def(self_argument)?; - let name = &*get_str(interner, name)?; + let name = &*get_str(name)?; let modifiers = interner.function_modifiers(&func_id); if let Some(attribute) = modifiers.attributes.function() { @@ -2735,8 +2690,7 @@ fn function_def_set_parameters( let func_id = get_function_def(self_argument)?; check_function_not_yet_resolved(interpreter, func_id, location)?; - let (input_parameters, _type) = - get_slice(interpreter.elaborator.interner, parameters_argument)?; + let (input_parameters, _type) = get_slice(parameters_argument)?; // What follows is very similar to what happens in Elaborator::define_function_meta let mut parameters = Vec::new(); @@ -2744,10 +2698,7 @@ fn function_def_set_parameters( let mut parameter_idents = Vec::new(); for input_parameter in input_parameters { - let mut tuple = get_tuple( - interpreter.elaborator.interner, - (input_parameter, parameters_argument_location), - )?; + let mut tuple = get_tuple((input_parameter, parameters_argument_location))?; let parameter = tuple.pop().unwrap().unwrap_or_clone(); let parameter_type = get_type((parameter, parameters_argument_location))?; let parameter_pattern = parse( @@ -3010,7 +2961,7 @@ fn module_has_named_attribute( let module_id = get_module(self_argument)?; let module_data = interpreter.elaborator.get_module(module_id); - let name = get_str(interpreter.elaborator.interner, name)?; + let name = get_str(name)?; Ok(Value::Bool(has_named_attribute( &name, @@ -3162,7 +3113,6 @@ fn ctstring_hash(arguments: Vec<(Value, Location)>, location: Location) -> IResu } fn derive_generators( - interner: &mut NodeInterner, arguments: Vec<(Value, Location)>, return_type: Type, location: Location, @@ -3170,7 +3120,7 @@ fn derive_generators( let (domain_separator_string, starting_index) = check_two_arguments(arguments, location)?; let domain_separator_location = domain_separator_string.1; - let (domain_separator_string, _) = get_array(interner, domain_separator_string)?; + let (domain_separator_string, _) = get_array(domain_separator_string)?; let starting_index = get_u32(starting_index)?; let domain_separator_string = diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs index 6aa4b4cfccb..74907167457 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs @@ -18,7 +18,7 @@ use crate::lexer::Lexer; use crate::parser::{Parser, ParserError}; use crate::signed_field::SignedField; use crate::token::{Keyword, LocatedToken, SecondaryAttributeKind}; -use crate::{DataType, Kind, Shared}; +use crate::{Kind, Shared}; use crate::{ QuotedType, Type, ast::{ @@ -95,14 +95,12 @@ pub(crate) fn check_arguments( } pub(crate) fn get_array( - interner: &NodeInterner, (value, location): (Value, Location), ) -> IResult<(im::Vector, Type)> { match value { Value::Array(values, typ) => Ok((values, typ)), value => { - let type_var = Box::new(interner.next_type_variable()); - let expected = Type::Array(type_var.clone(), type_var); + let expected = "array"; type_mismatch(value, expected, location) } } @@ -117,14 +115,7 @@ pub(crate) fn get_struct_fields( match value { Value::Struct(fields, typ) => Ok((fields, typ)), _ => { - let expected = DataType::new( - TypeId::dummy_id(), - Ident::new(name.to_string(), location), - location, - Vec::new(), - ItemVisibility::Public, - ); - let expected = Type::DataType(Shared::new(expected), Vec::new()); + let expected = format!("struct {name}"); type_mismatch(value, expected, location) } } @@ -152,19 +143,17 @@ pub(crate) fn get_struct_field( pub(crate) fn get_bool((value, location): (Value, Location)) -> IResult { match value { Value::Bool(value) => Ok(value), - value => type_mismatch(value, Type::Bool, location), + value => type_mismatch(value, "bool", location), } } pub(crate) fn get_slice( - interner: &NodeInterner, (value, location): (Value, Location), ) -> IResult<(im::Vector, Type)> { match value { Value::Slice(values, typ) => Ok((values, typ)), value => { - let type_var = Box::new(interner.next_type_variable()); - let expected = Type::Slice(type_var); + let expected = "slice"; type_mismatch(value, expected, location) } } @@ -173,11 +162,10 @@ pub(crate) fn get_slice( /// Interpret the input as an array, then map each element. /// Returns the values in the array and the original array type. pub(crate) fn get_array_map( - interner: &NodeInterner, (value, location): (Value, Location), f: impl Fn((Value, Location)) -> IResult, ) -> IResult<(Vec, Type)> { - let (values, typ) = get_array(interner, (value, location))?; + let (values, typ) = get_array((value, location))?; let values = try_vecmap(values, |value| f((value, location)))?; Ok((values, typ)) } @@ -185,30 +173,27 @@ pub(crate) fn get_array_map( /// Get an array and convert it to a fixed size. /// Returns the values in the array and the original array type. pub(crate) fn get_fixed_array_map( - interner: &NodeInterner, (value, location): (Value, Location), f: impl Fn((Value, Location)) -> IResult, ) -> IResult<([T; N], Type)> { - let (values, typ) = get_array_map(interner, (value, location), f)?; + let (values, typ) = get_array_map((value, location), f)?; values.try_into().map(|v| (v, typ.clone())).map_err(|_| { // Assuming that `values.len()` corresponds to `typ`. let Type::Array(_, ref elem) = typ else { unreachable!("get_array_map checked it was an array") }; - let expected = Type::Array(Box::new(Type::Constant(N.into(), Kind::u32())), elem.clone()); + let expected = + Type::Array(Box::new(Type::Constant(N.into(), Kind::u32())), elem.clone()).to_string(); InterpreterError::TypeMismatch { expected, actual: typ, location } }) } -pub(crate) fn get_str( - interner: &NodeInterner, - (value, location): (Value, Location), -) -> IResult> { +pub(crate) fn get_str((value, location): (Value, Location)) -> IResult> { match value { Value::String(string) => Ok(string), value => { - let expected = Type::String(Box::new(interner.next_type_variable())); + let expected = "str"; type_mismatch(value, expected, location) } } @@ -217,19 +202,15 @@ pub(crate) fn get_str( pub(crate) fn get_ctstring((value, location): (Value, Location)) -> IResult> { match value { Value::CtString(string) => Ok(string), - value => type_mismatch(value, Type::Quoted(QuotedType::CtString), location), + value => type_mismatch(value, Type::Quoted(QuotedType::CtString).to_string(), location), } } -pub(crate) fn get_tuple( - interner: &NodeInterner, - (value, location): (Value, Location), -) -> IResult>> { +pub(crate) fn get_tuple((value, location): (Value, Location)) -> IResult>> { match value { Value::Tuple(values) => Ok(values), value => { - let type_var = interner.next_type_variable(); - let expected = Type::Tuple(vec![type_var]); + let expected = "tuple"; type_mismatch(value, expected, location) } } @@ -238,7 +219,7 @@ pub(crate) fn get_tuple( pub(crate) fn get_field((value, location): (Value, Location)) -> IResult { match value { Value::Field(value) => Ok(value), - value => type_mismatch(value, Type::FieldElement, location), + value => type_mismatch(value, Type::FieldElement.to_string(), location), } } @@ -247,7 +228,7 @@ pub(crate) fn get_u8((value, location): (Value, Location)) -> IResult { Value::U8(value) => Ok(value), value => { let expected = Type::Integer(Signedness::Unsigned, IntegerBitSize::Eight); - type_mismatch(value, expected, location) + type_mismatch(value, expected.to_string(), location) } } } @@ -257,7 +238,7 @@ pub(crate) fn get_u32((value, location): (Value, Location)) -> IResult { Value::U32(value) => Ok(value), value => { let expected = Type::Integer(Signedness::Unsigned, IntegerBitSize::ThirtyTwo); - type_mismatch(value, expected, location) + type_mismatch(value, expected.to_string(), location) } } } @@ -267,7 +248,7 @@ pub(crate) fn get_u64((value, location): (Value, Location)) -> IResult { Value::U64(value) => Ok(value), value => { let expected = Type::Integer(Signedness::Unsigned, IntegerBitSize::SixtyFour); - type_mismatch(value, expected, location) + type_mismatch(value, expected.to_string(), location) } } } @@ -292,42 +273,39 @@ pub(crate) fn get_expr( } _ => Ok(*expr), }, - value => type_mismatch(value, Type::Quoted(QuotedType::Expr), location), + value => type_mismatch(value, Type::Quoted(QuotedType::Expr).to_string(), location), } } pub(crate) fn get_format_string( - interner: &NodeInterner, (value, location): (Value, Location), ) -> IResult<(Rc, Type)> { match value { Value::FormatString(value, typ) => Ok((value, typ)), - value => { - let n = Box::new(interner.next_type_variable()); - let e = Box::new(interner.next_type_variable()); - type_mismatch(value, Type::FmtString(n, e), location) - } + value => type_mismatch(value, "fmtstr", location), } } pub(crate) fn get_function_def((value, location): (Value, Location)) -> IResult { match value { Value::FunctionDefinition(id) => Ok(id), - value => type_mismatch(value, Type::Quoted(QuotedType::FunctionDefinition), location), + value => { + type_mismatch(value, Type::Quoted(QuotedType::FunctionDefinition).to_string(), location) + } } } pub(crate) fn get_module((value, location): (Value, Location)) -> IResult { match value { Value::ModuleDefinition(module_id) => Ok(module_id), - value => type_mismatch(value, Type::Quoted(QuotedType::Module), location), + value => type_mismatch(value, Type::Quoted(QuotedType::Module).to_string(), location), } } pub(crate) fn get_type_id((value, location): (Value, Location)) -> IResult { match value { Value::TypeDefinition(id) => Ok(id), - _ => type_mismatch(value, Type::Quoted(QuotedType::TypeDefinition), location), + _ => type_mismatch(value, Type::Quoted(QuotedType::TypeDefinition).to_string(), location), } } @@ -336,42 +314,46 @@ pub(crate) fn get_trait_constraint( ) -> IResult<(TraitId, TraitGenerics)> { match value { Value::TraitConstraint(trait_id, generics) => Ok((trait_id, generics)), - value => type_mismatch(value, Type::Quoted(QuotedType::TraitConstraint), location), + value => { + type_mismatch(value, Type::Quoted(QuotedType::TraitConstraint).to_string(), location) + } } } pub(crate) fn get_trait_def((value, location): (Value, Location)) -> IResult { match value { Value::TraitDefinition(id) => Ok(id), - value => type_mismatch(value, Type::Quoted(QuotedType::TraitDefinition), location), + value => { + type_mismatch(value, Type::Quoted(QuotedType::TraitDefinition).to_string(), location) + } } } pub(crate) fn get_trait_impl((value, location): (Value, Location)) -> IResult { match value { Value::TraitImpl(id) => Ok(id), - value => type_mismatch(value, Type::Quoted(QuotedType::TraitImpl), location), + value => type_mismatch(value, Type::Quoted(QuotedType::TraitImpl).to_string(), location), } } pub(crate) fn get_type((value, location): (Value, Location)) -> IResult { match value { Value::Type(typ) => Ok(typ), - value => type_mismatch(value, Type::Quoted(QuotedType::Type), location), + value => type_mismatch(value, Type::Quoted(QuotedType::Type).to_string(), location), } } pub(crate) fn get_typed_expr((value, location): (Value, Location)) -> IResult { match value { Value::TypedExpr(typed_expr) => Ok(typed_expr), - value => type_mismatch(value, Type::Quoted(QuotedType::TypedExpr), location), + value => type_mismatch(value, Type::Quoted(QuotedType::TypedExpr).to_string(), location), } } pub(crate) fn get_quoted((value, location): (Value, Location)) -> IResult>> { match value { Value::Quoted(tokens) => Ok(tokens), - value => type_mismatch(value, Type::Quoted(QuotedType::Quoted), location), + value => type_mismatch(value, Type::Quoted(QuotedType::Quoted).to_string(), location), } } @@ -388,12 +370,15 @@ pub(crate) fn get_unresolved_type( Ok(typ) } } - value => type_mismatch(value, Type::Quoted(QuotedType::UnresolvedType), location), + value => { + type_mismatch(value, Type::Quoted(QuotedType::UnresolvedType).to_string(), location) + } } } -fn type_mismatch(value: Value, expected: Type, location: Location) -> IResult { +fn type_mismatch(value: Value, expected: impl Into, location: Location) -> IResult { let actual = value.get_type().into_owned(); + let expected = expected.into(); Err(InterpreterError::TypeMismatch { expected, actual, location }) } diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs index 7570212e9f1..8367d7141f4 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs @@ -10,12 +10,11 @@ use iter_extended::vecmap; use noirc_errors::Location; use crate::{ - Kind, Type, + Type, hir::comptime::{ InterpreterError, Value, errors::IResult, interpreter::builtin::builtin_helpers::to_byte_array, }, - node_interner::NodeInterner, signed_field::SignedField, }; @@ -36,14 +35,7 @@ impl Interpreter<'_, '_> { return_type: Type, location: Location, ) -> IResult { - call_foreign( - self.elaborator.interner, - name, - arguments, - return_type, - location, - self.elaborator.pedantic_solving(), - ) + call_foreign(name, arguments, return_type, location, self.elaborator.pedantic_solving()) } } @@ -51,7 +43,6 @@ impl Interpreter<'_, '_> { /// /// Similar to `evaluate_black_box` in `brillig_vm`. fn call_foreign( - interner: &mut NodeInterner, name: &str, args: Vec<(Value, Location)>, return_type: Type, @@ -59,33 +50,23 @@ fn call_foreign( pedantic_solving: bool, ) -> IResult { match name { - "aes128_encrypt" => aes128_encrypt(interner, args, location), - "blake2s" => blake_hash(interner, args, location, acvm::blackbox_solver::blake2s), - "blake3" => blake_hash(interner, args, location, acvm::blackbox_solver::blake3), + "aes128_encrypt" => aes128_encrypt(args, location), + "blake2s" => blake_hash(args, location, acvm::blackbox_solver::blake2s), + "blake3" => blake_hash(args, location, acvm::blackbox_solver::blake3), // cSpell:disable-next-line - "ecdsa_secp256k1" => ecdsa_secp256_verify( - interner, - args, - location, - acvm::blackbox_solver::ecdsa_secp256k1_verify, - ), - // cSpell:disable-next-line - "ecdsa_secp256r1" => ecdsa_secp256_verify( - interner, - args, - location, - acvm::blackbox_solver::ecdsa_secp256r1_verify, - ), - "embedded_curve_add" => embedded_curve_add(args, return_type, location, pedantic_solving), - "multi_scalar_mul" => { - multi_scalar_mul(interner, args, return_type, location, pedantic_solving) + "ecdsa_secp256k1" => { + ecdsa_secp256_verify(args, location, acvm::blackbox_solver::ecdsa_secp256k1_verify) } - "poseidon2_permutation" => { - poseidon2_permutation(interner, args, location, pedantic_solving) + // cSpell:disable-next-line + "ecdsa_secp256r1" => { + ecdsa_secp256_verify(args, location, acvm::blackbox_solver::ecdsa_secp256r1_verify) } - "keccakf1600" => keccakf1600(interner, args, location), + "embedded_curve_add" => embedded_curve_add(args, return_type, location, pedantic_solving), + "multi_scalar_mul" => multi_scalar_mul(args, return_type, location, pedantic_solving), + "poseidon2_permutation" => poseidon2_permutation(args, location, pedantic_solving), + "keccakf1600" => keccakf1600(args, location), "range" => apply_range_constraint(args, location), - "sha256_compression" => sha256_compression(interner, args, location), + "sha256_compression" => sha256_compression(args, location), _ => { let explanation = match name { "and" | "xor" => "It should be turned into a binary operation.".into(), @@ -103,16 +84,12 @@ fn call_foreign( } /// `pub fn aes128_encrypt(input: [u8; N], iv: [u8; 16], key: [u8; 16]) -> [u8]` -fn aes128_encrypt( - interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn aes128_encrypt(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let (inputs, iv, key) = check_three_arguments(arguments, location)?; - let (inputs, _) = get_array_map(interner, inputs, get_u8)?; - let (iv, _) = get_fixed_array_map(interner, iv, get_u8)?; - let (key, _) = get_fixed_array_map(interner, key, get_u8)?; + let (inputs, _) = get_array_map(inputs, get_u8)?; + let (iv, _) = get_fixed_array_map(iv, get_u8)?; + let (key, _) = get_fixed_array_map(key, get_u8)?; let output = acvm::blackbox_solver::aes128_encrypt(&inputs, iv, key) .map_err(|e| InterpreterError::BlackBoxError(e, location))?; @@ -147,14 +124,13 @@ fn apply_range_constraint(arguments: Vec<(Value, Location)>, location: Location) /// pub fn blake3(input: [u8; N]) -> [u8; 32] /// ``` fn blake_hash( - interner: &mut NodeInterner, arguments: Vec<(Value, Location)>, location: Location, f: impl Fn(&[u8]) -> Result<[u8; 32], BlackBoxResolutionError>, ) -> IResult { let inputs = check_one_argument(arguments, location)?; - let (inputs, _) = get_array_map(interner, inputs, get_u8)?; + let (inputs, _) = get_array_map(inputs, get_u8)?; let output = f(&inputs).map_err(|e| InterpreterError::BlackBoxError(e, location))?; Ok(to_byte_array(&output)) @@ -171,7 +147,6 @@ fn blake_hash( /// ) -> bool // cSpell:disable-next-line fn ecdsa_secp256_verify( - interner: &mut NodeInterner, arguments: Vec<(Value, Location)>, location: Location, f: impl Fn(&[u8; 32], &[u8; 32], &[u8; 32], &[u8; 64]) -> Result, @@ -179,10 +154,10 @@ fn ecdsa_secp256_verify( let [pub_key_x, pub_key_y, sig, msg_hash, predicate] = check_arguments(arguments, location)?; assert_eq!(predicate.0, Value::Bool(true), "verify_signature predicate should be true"); - let (pub_key_x, _) = get_fixed_array_map(interner, pub_key_x, get_u8)?; - let (pub_key_y, _) = get_fixed_array_map(interner, pub_key_y, get_u8)?; - let (sig, _) = get_fixed_array_map(interner, sig, get_u8)?; - let (msg_hash, _) = get_fixed_array_map(interner, msg_hash.clone(), get_u8)?; + let (pub_key_x, _) = get_fixed_array_map(pub_key_x, get_u8)?; + let (pub_key_y, _) = get_fixed_array_map(pub_key_y, get_u8)?; + let (sig, _) = get_fixed_array_map(sig, get_u8)?; + let (msg_hash, _) = get_fixed_array_map(msg_hash.clone(), get_u8)?; let is_valid = f(&msg_hash, &pub_key_x, &pub_key_y, &sig) .map_err(|e| InterpreterError::BlackBoxError(e, location))?; @@ -235,7 +210,6 @@ fn embedded_curve_add( /// ) -> [EmbeddedCurvePoint; 1] /// ``` fn multi_scalar_mul( - interner: &mut NodeInterner, arguments: Vec<(Value, Location)>, return_type: Type, location: Location, @@ -244,8 +218,8 @@ fn multi_scalar_mul( let (points, scalars, predicate) = check_three_arguments(arguments, location)?; assert_eq!(predicate.0, Value::Bool(true), "verify_signature predicate should be true"); - let (points, _) = get_array_map(interner, points, get_embedded_curve_point)?; - let (scalars, _) = get_array_map(interner, scalars, get_embedded_curve_scalar)?; + let (points, _) = get_array_map(points, get_embedded_curve_point)?; + let (scalars, _) = get_array_map(scalars, get_embedded_curve_scalar)?; let points: Vec<_> = points.into_iter().flat_map(|(x, y, inf)| [x, y, inf.into()]).collect(); let mut scalars_lo = Vec::new(); @@ -268,10 +242,7 @@ fn multi_scalar_mul( Type::Array(_, item_type) => item_type.as_ref().clone(), _ => { return Err(InterpreterError::TypeMismatch { - expected: Type::Array( - Box::new(Type::Constant(1_usize.into(), Kind::u32())), - Box::new(interner.next_type_variable()), // EmbeddedCurvePoint - ), + expected: "[EmbeddedCurvePoint; 1]".to_string(), actual: return_type.clone(), location, }); @@ -286,14 +257,13 @@ fn multi_scalar_mul( /// `poseidon2_permutation(_input: [Field; N], _state_length: u32) -> [Field; N]` fn poseidon2_permutation( - interner: &mut NodeInterner, arguments: Vec<(Value, Location)>, location: Location, pedantic_solving: bool, ) -> IResult { let input = check_one_argument(arguments, location)?; - let (input, typ) = get_array_map(interner, input, get_field)?; + let (input, typ) = get_array_map(input, get_field)?; let input = vecmap(input, SignedField::to_field_element); let fields = Bn254BlackBoxSolver(pedantic_solving) @@ -305,14 +275,10 @@ fn poseidon2_permutation( } /// `fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}` -fn keccakf1600( - interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn keccakf1600(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let input = check_one_argument(arguments, location)?; - let (state, typ) = get_fixed_array_map(interner, input, get_u64)?; + let (state, typ) = get_fixed_array_map(input, get_u64)?; let result_lanes = acvm::blackbox_solver::keccakf1600(state) .map_err(|error| InterpreterError::BlackBoxError(error, location))?; @@ -322,15 +288,11 @@ fn keccakf1600( } /// `pub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8]` -fn sha256_compression( - interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, - location: Location, -) -> IResult { +fn sha256_compression(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let (input, state) = check_two_arguments(arguments, location)?; - let (input, _) = get_fixed_array_map(interner, input, get_u32)?; - let (mut state, typ) = get_fixed_array_map(interner, state, get_u32)?; + let (input, _) = get_fixed_array_map(input, get_u32)?; + let (mut state, typ) = get_fixed_array_map(state, get_u32)?; acvm::blackbox_solver::sha256_compression(&mut state, &input); @@ -389,48 +351,30 @@ mod tests { use crate::hir::comptime::InterpreterError::{ ArgumentCountMismatch, InvalidInComptimeContext, Unimplemented, }; - use crate::hir::comptime::tests::with_interpreter; use super::call_foreign; /// Check that all `BlackBoxFunc` are covered by `call_foreign`. #[test] fn test_blackbox_implemented() { - let dummy = " - comptime fn main() -> pub u8 { - 0 + let no_location = Location::dummy(); + let mut not_implemented = Vec::new(); + + for blackbox in BlackBoxFunc::iter() { + let name = blackbox.name(); + let pedantic_solving = true; + match call_foreign(name, Vec::new(), Type::Unit, no_location, pedantic_solving) { + Ok(_) => { + // Exists and works with no args (unlikely) + } + Err(ArgumentCountMismatch { .. }) => { + // Exists but doesn't work with no args (expected) + } + Err(InvalidInComptimeContext { .. }) => {} + Err(Unimplemented { .. }) => not_implemented.push(name), + Err(other) => panic!("unexpected error: {other:?}"), + }; } - "; - - let not_implemented = with_interpreter(dummy, |interpreter, _, _| { - let no_location = Location::dummy(); - let mut not_implemented = Vec::new(); - - for blackbox in BlackBoxFunc::iter() { - let name = blackbox.name(); - let pedantic_solving = true; - match call_foreign( - interpreter.elaborator.interner, - name, - Vec::new(), - Type::Unit, - no_location, - pedantic_solving, - ) { - Ok(_) => { - // Exists and works with no args (unlikely) - } - Err(ArgumentCountMismatch { .. }) => { - // Exists but doesn't work with no args (expected) - } - Err(InvalidInComptimeContext { .. }) => {} - Err(Unimplemented { .. }) => not_implemented.push(name), - Err(other) => panic!("unexpected error: {other:?}"), - }; - } - - not_implemented - }); assert!( not_implemented.is_empty(), diff --git a/compiler/noirc_frontend/src/hir/def_map/mod.rs b/compiler/noirc_frontend/src/hir/def_map/mod.rs index 6028f4f92cf..437b9fa78c1 100644 --- a/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -33,10 +33,6 @@ impl LocalModuleId { LocalModuleId(index) } - pub fn dummy_id() -> LocalModuleId { - LocalModuleId(Index::dummy()) - } - /// Gets the index that underlies this local module ID. pub fn as_index(self) -> Index { self.0 @@ -50,10 +46,6 @@ pub struct ModuleId { } impl ModuleId { - pub fn dummy_id() -> ModuleId { - ModuleId { krate: CrateId::dummy_id(), local_id: LocalModuleId::dummy_id() } - } - pub fn module(self, def_maps: &DefMaps) -> &ModuleData { &def_maps[&self.krate].modules()[self.local_id.0] } diff --git a/compiler/noirc_frontend/src/node_interner/function.rs b/compiler/noirc_frontend/src/node_interner/function.rs index 3f9a52eb877..ff00dbc0d24 100644 --- a/compiler/noirc_frontend/src/node_interner/function.rs +++ b/compiler/noirc_frontend/src/node_interner/function.rs @@ -52,18 +52,6 @@ impl NodeInterner { self.func_meta.insert(func_id, func_data); } - /// Push a function with the default modifiers and [`ModuleId`] for testing - #[cfg(test)] - pub fn push_test_function_definition(&mut self, name: String) -> FuncId { - let id = self.push_fn(HirFunction::empty()); - let mut modifiers = FunctionModifiers::new(); - modifiers.name = name; - let module = ModuleId::dummy_id(); - let location = Location::dummy(); - self.push_function_definition(id, modifiers, module, location); - id - } - pub fn push_function( &mut self, id: FuncId, diff --git a/compiler/noirc_frontend/src/node_interner/globals.rs b/compiler/noirc_frontend/src/node_interner/globals.rs index 5365beaa1fd..2d8535ac759 100644 --- a/compiler/noirc_frontend/src/node_interner/globals.rs +++ b/compiler/noirc_frontend/src/node_interner/globals.rs @@ -16,13 +16,6 @@ use super::NodeInterner; #[derive(Debug, Eq, PartialEq, Hash, Clone, Copy, PartialOrd, Ord)] pub struct GlobalId(usize); -impl GlobalId { - // Dummy id for error reporting - pub fn dummy_id() -> Self { - GlobalId(usize::MAX) - } -} - #[derive(Debug, Clone)] pub struct GlobalInfo { pub id: GlobalId, diff --git a/compiler/noirc_frontend/src/node_interner/ids.rs b/compiler/noirc_frontend/src/node_interner/ids.rs index a7835e383dd..f671b0ec97a 100644 --- a/compiler/noirc_frontend/src/node_interner/ids.rs +++ b/compiler/noirc_frontend/src/node_interner/ids.rs @@ -45,30 +45,12 @@ impl DefinitionId { #[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)] pub struct StmtId(pub(super) Index); -impl StmtId { - //dummy id for error reporting - // This can be anything, as the program will ultimately fail - // after resolution - pub fn dummy_id() -> StmtId { - StmtId(Index::dummy()) - } -} - #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, PartialOrd, Ord)] pub struct ExprId(pub(super) Index); #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] pub struct FuncId(pub(super) Index); -impl FuncId { - //dummy id for error reporting - // This can be anything, as the program will ultimately fail - // after resolution - pub fn dummy_id() -> FuncId { - FuncId(Index::dummy()) - } -} - impl fmt::Display for FuncId { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) @@ -79,13 +61,6 @@ impl fmt::Display for FuncId { pub struct TypeId(pub(super) ModuleId); impl TypeId { - //dummy id for error reporting - // This can be anything, as the program will ultimately fail - // after resolution - pub fn dummy_id() -> TypeId { - TypeId(ModuleId { krate: CrateId::dummy_id(), local_id: LocalModuleId::dummy_id() }) - } - pub fn module_id(self) -> ModuleId { self.0 } @@ -110,15 +85,6 @@ pub struct TypeAliasId(pub usize); #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct TraitId(pub ModuleId); -impl TraitId { - // dummy id for error reporting - // This can be anything, as the program will ultimately fail - // after resolution - pub fn dummy_id() -> TraitId { - TraitId(ModuleId { krate: CrateId::dummy_id(), local_id: LocalModuleId::dummy_id() }) - } -} - #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, PartialOrd, Ord)] pub struct TraitAssociatedTypeId(pub usize); diff --git a/compiler/noirc_frontend/src/node_interner/mod.rs b/compiler/noirc_frontend/src/node_interner/mod.rs index 9734650dc39..99e6285c51c 100644 --- a/compiler/noirc_frontend/src/node_interner/mod.rs +++ b/compiler/noirc_frontend/src/node_interner/mod.rs @@ -1167,7 +1167,7 @@ impl NodeInterner { let mut usize_arena = Arena::default(); let index = usize_arena.insert(0); let stdlib = CrateId::Stdlib(0); - let func_id = FuncId::dummy_id(); + let func_id = self.push_empty_fn(); // Use a definition ID that won't clash with anything else, and isn't the dummy one let definition_id = DefinitionId(usize::MAX - 1); self.function_definition_ids.insert(func_id, definition_id);