From d3828b8579ad33993c04a839af066951b7457b84 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 11:12:47 -0300 Subject: [PATCH 01/22] feat: add mutating `FunctionDefinition` functions --- .../noirc_frontend/src/elaborator/patterns.rs | 2 +- .../noirc_frontend/src/hir/comptime/errors.rs | 8 + .../src/hir/comptime/interpreter/builtin.rs | 186 +++++++++++++++++- .../interpreter/builtin/builtin_helpers.rs | 16 ++ compiler/noirc_frontend/src/node_interner.rs | 4 + compiler/noirc_frontend/src/parser/mod.rs | 4 +- compiler/noirc_frontend/src/parser/parser.rs | 6 +- noir_stdlib/src/meta/function_def.nr | 9 + .../comptime_function_definition/src/main.nr | 23 ++- 9 files changed, 249 insertions(+), 9 deletions(-) diff --git a/compiler/noirc_frontend/src/elaborator/patterns.rs b/compiler/noirc_frontend/src/elaborator/patterns.rs index ade5420bce4..bd44e087e70 100644 --- a/compiler/noirc_frontend/src/elaborator/patterns.rs +++ b/compiler/noirc_frontend/src/elaborator/patterns.rs @@ -39,7 +39,7 @@ impl<'context> Elaborator<'context> { /// Equivalent to `elaborate_pattern`, this version just also /// adds any new DefinitionIds that were created to the given Vec. - pub(super) fn elaborate_pattern_and_store_ids( + pub fn elaborate_pattern_and_store_ids( &mut self, pattern: Pattern, expected_type: Type, diff --git a/compiler/noirc_frontend/src/hir/comptime/errors.rs b/compiler/noirc_frontend/src/hir/comptime/errors.rs index 7898f13945f..26e17faf2ac 100644 --- a/compiler/noirc_frontend/src/hir/comptime/errors.rs +++ b/compiler/noirc_frontend/src/hir/comptime/errors.rs @@ -185,6 +185,9 @@ pub enum InterpreterError { FailedToResolveTraitDefinition { location: Location, }, + CannotMutateFunction { + location: Location, + }, Unimplemented { item: String, @@ -255,6 +258,7 @@ impl InterpreterError { | InterpreterError::TraitDefinitionMustBeAPath { location } | InterpreterError::FailedToResolveTraitDefinition { location } | InterpreterError::FailedToResolveTraitBound { location, .. } => *location, + InterpreterError::CannotMutateFunction { location, .. } => *location, InterpreterError::FailedToParseMacro { error, file, .. } => { Location::new(error.span(), *file) @@ -516,6 +520,10 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { let msg = "Failed to resolve to a trait definition".to_string(); CustomDiagnostic::simple_error(msg, String::new(), location.span) } + InterpreterError::CannotMutateFunction { location } => { + let msg = "Cannot mutate function at this point".to_string(); + CustomDiagnostic::simple_error(msg, String::new(), location.span) + } } } } diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index c12fb4d1113..0e0d4c0945d 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -7,7 +7,7 @@ use acvm::{AcirField, FieldElement}; use builtin_helpers::{ check_argument_count, check_one_argument, check_three_arguments, check_two_arguments, get_function_def, get_module, get_quoted, get_slice, get_trait_constraint, get_trait_def, - get_type, get_u32, hir_pattern_to_tokens, + get_tuple, get_type, get_u32, hir_pattern_to_tokens, }; use chumsky::Parser; use iter_extended::{try_vecmap, vecmap}; @@ -15,11 +15,16 @@ use noirc_errors::Location; use rustc_hash::FxHashMap as HashMap; use crate::{ - ast::IntegerBitSize, + ast::{ + FunctionKind, FunctionReturnType, IntegerBitSize, UnresolvedType, UnresolvedTypeData, + Visibility, + }, hir::comptime::{errors::IResult, value::add_token_spans, InterpreterError, Value}, + hir_def::function::FunctionBody, macros_api::{ModuleDefId, NodeInterner, Signedness}, + node_interner::DefinitionKind, parser, - token::Token, + token::{SpannedToken, Token}, QuotedType, Shared, Type, }; @@ -43,6 +48,11 @@ impl<'local, 'context> Interpreter<'local, 'context> { "function_def_name" => function_def_name(interner, arguments, location), "function_def_parameters" => function_def_parameters(interner, arguments, location), "function_def_return_type" => function_def_return_type(interner, arguments, location), + "function_def_set_body" => function_def_set_body(self, arguments, location), + "function_def_set_parameters" => function_def_set_parameters(self, arguments, location), + "function_def_set_return_type" => { + function_def_set_return_type(self, arguments, location) + } "module_functions" => module_functions(self, arguments, location), "module_is_contract" => module_is_contract(self, arguments, location), "module_name" => module_name(interner, arguments, location), @@ -734,6 +744,176 @@ fn function_def_return_type( Ok(Value::Type(func_meta.return_type().follow_bindings())) } +// fn set_body(self, body: Quoted) +fn function_def_set_body( + interpreter: &mut Interpreter, + arguments: Vec<(Value, Location)>, + location: Location, +) -> IResult { + let (self_argument, body_argument) = check_two_arguments(arguments, location)?; + let func_id = get_function_def(self_argument, location)?; + + let func_meta = interpreter.elaborator.interner.function_meta(&func_id); + match func_meta.function_body { + FunctionBody::Unresolved(_, _, _) => (), + FunctionBody::Resolving | FunctionBody::Resolved => { + return Err(InterpreterError::CannotMutateFunction { location }) + } + } + + let body_tokens = get_quoted(body_argument, location)?; + let mut body_quoted = add_token_spans(body_tokens.clone(), location.span); + + // Surround the body in `{ ... }` so we can parse it as a block + body_quoted.0.insert(0, SpannedToken::new(Token::LeftBrace, location.span)); + body_quoted.0.push(SpannedToken::new(Token::RightBrace, location.span)); + + let body = + parser::block(parser::fresh_statement()).parse(body_quoted).map_err(|mut errors| { + let error = errors.swap_remove(0); + let rule = "a block"; + InterpreterError::FailedToParseMacro { + error, + tokens: body_tokens, + rule, + file: location.file, + } + })?; + + let func_meta = interpreter.elaborator.interner.function_meta_mut(&func_id); + func_meta.has_body = true; + func_meta.function_body = FunctionBody::Unresolved(FunctionKind::Normal, body, location.span); + + Ok(Value::Unit) +} + +// fn set_parameters(self, parameters: [(Quoted, Type)]) +fn function_def_set_parameters( + interpreter: &mut Interpreter, + arguments: Vec<(Value, Location)>, + location: Location, +) -> IResult { + let (self_argument, parameters_argument) = check_two_arguments(arguments, location)?; + + let func_id = get_function_def(self_argument, location)?; + let func_meta = interpreter.elaborator.interner.function_meta(&func_id); + match func_meta.function_body { + FunctionBody::Unresolved(_, _, _) => (), + FunctionBody::Resolving | FunctionBody::Resolved => { + return Err(InterpreterError::CannotMutateFunction { location }) + } + } + + let (input_parameters, _type) = + get_slice(interpreter.elaborator.interner, parameters_argument, location)?; + + // What follows is very similar to what happens in Elaborator::define_function_meta + let mut parameters = Vec::new(); + let mut parameter_types = Vec::new(); + let mut parameter_idents = Vec::new(); + + for input_parameter in input_parameters { + let mut tuple = get_tuple(interpreter.elaborator.interner, input_parameter, location)?; + let parameter_type = get_type(tuple.pop().unwrap(), location)?; + let parameter_name_tokens = get_quoted(tuple.pop().unwrap(), location)?; + let parameter_name_quoted = add_token_spans(parameter_name_tokens.clone(), location.span); + let parameter_pattern = + parser::pattern().parse(parameter_name_quoted).map_err(|mut errors| { + let error = errors.swap_remove(0); + let rule = "a pattern"; + InterpreterError::FailedToParseMacro { + error, + tokens: parameter_name_tokens, + rule, + file: location.file, + } + })?; + + let hir_pattern = interpreter.elaborate_item(interpreter.current_function, |elaborator| { + elaborator.elaborate_pattern_and_store_ids( + parameter_pattern, + parameter_type.clone(), + DefinitionKind::Local(None), + &mut parameter_idents, + None, + ) + }); + + parameters.push((hir_pattern, parameter_type.clone(), Visibility::Private)); + parameter_types.push(parameter_type); + } + + let func_meta = interpreter.elaborator.interner.function_meta(&func_id); + let function_type = Type::Function( + parameter_types, + Box::new(func_meta.return_type().clone()), + Box::new(Type::Unit), + ); + + // TODO: generics. In Elaborator::define_function_meta there's this code: + // + // if !generics.is_empty() { + // typ = Type::Forall(generics, Box::new(typ)); + // } + + interpreter.elaborator.interner.push_definition_type(func_meta.name.id, function_type.clone()); + + { + let func_meta = interpreter.elaborator.interner.function_meta_mut(&func_id); + func_meta.parameters = parameters.into(); + func_meta.parameter_idents = parameter_idents; + func_meta.typ = function_type; + } + + Ok(Value::Unit) +} + +// fn set_return_type(self, return_type: Type) +fn function_def_set_return_type( + interpreter: &mut Interpreter, + arguments: Vec<(Value, Location)>, + location: Location, +) -> IResult { + let (self_argument, return_type_argument) = check_two_arguments(arguments, location)?; + let return_type = get_type(return_type_argument, location)?; + + let func_id = get_function_def(self_argument, location)?; + let func_meta = interpreter.elaborator.interner.function_meta(&func_id); + match func_meta.function_body { + FunctionBody::Unresolved(_, _, _) => (), + FunctionBody::Resolving | FunctionBody::Resolved => { + return Err(InterpreterError::CannotMutateFunction { location }) + } + } + + let parameter_types = func_meta.parameters.iter().map(|(_, typ, _)| typ.clone()).collect(); + + let func_meta = interpreter.elaborator.interner.function_meta(&func_id); + let function_type = + Type::Function(parameter_types, Box::new(return_type.clone()), Box::new(Type::Unit)); + + // TODO: generics. In Elaborator::define_function_meta there's this code: + // + // if !generics.is_empty() { + // typ = Type::Forall(generics, Box::new(typ)); + // } + + interpreter.elaborator.interner.push_definition_type(func_meta.name.id, function_type.clone()); + + let quoted_type_id = interpreter.elaborator.interner.push_quoted_type(return_type); + + { + let func_meta = interpreter.elaborator.interner.function_meta_mut(&func_id); + func_meta.return_type = FunctionReturnType::Ty(UnresolvedType { + typ: UnresolvedTypeData::Resolved(quoted_type_id), + span: Some(location.span), + }); + func_meta.typ = function_type; + } + + Ok(Value::Unit) +} + // fn functions(self) -> [FunctionDefinition] fn module_functions( interpreter: &Interpreter, 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 1c73f946587..f8f75f7f90d 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 @@ -95,6 +95,22 @@ pub(crate) fn get_slice( } } +pub(crate) fn get_tuple( + interner: &NodeInterner, + value: Value, + location: 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 actual = value.get_type().into_owned(); + Err(InterpreterError::TypeMismatch { expected, actual, location }) + } + } +} + pub(crate) fn get_field(value: Value, location: Location) -> IResult { match value { Value::Field(value) => Ok(value), diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index c701b29f898..43e742b940e 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -980,6 +980,10 @@ impl NodeInterner { self.func_meta.get(func_id).expect("ice: all function ids should have metadata") } + pub fn function_meta_mut(&mut self, func_id: &FuncId) -> &mut FuncMeta { + self.func_meta.get_mut(func_id).expect("ice: all function ids should have metadata") + } + pub fn try_function_meta(&self, func_id: &FuncId) -> Option<&FuncMeta> { self.func_meta.get(func_id) } diff --git a/compiler/noirc_frontend/src/parser/mod.rs b/compiler/noirc_frontend/src/parser/mod.rs index cba1aa931ef..f1972bcb9b5 100644 --- a/compiler/noirc_frontend/src/parser/mod.rs +++ b/compiler/noirc_frontend/src/parser/mod.rs @@ -24,7 +24,9 @@ pub use errors::ParserErrorReason; use noirc_errors::Span; pub use parser::path::path_no_turbofish; pub use parser::traits::trait_bound; -pub use parser::{expression, parse_program, parse_type, top_level_items}; +pub use parser::{ + block, expression, fresh_statement, parse_program, parse_type, pattern, top_level_items, +}; #[derive(Debug, Clone)] pub enum TopLevelStatement { diff --git a/compiler/noirc_frontend/src/parser/parser.rs b/compiler/noirc_frontend/src/parser/parser.rs index 4ccb158fad6..6ea8b10a993 100644 --- a/compiler/noirc_frontend/src/parser/parser.rs +++ b/compiler/noirc_frontend/src/parser/parser.rs @@ -372,7 +372,7 @@ fn block_expr<'a>( block(statement).map(ExpressionKind::Block).map_with_span(Expression::new) } -fn block<'a>( +pub fn block<'a>( statement: impl NoirParser + 'a, ) -> impl NoirParser + 'a { use Token::*; @@ -474,7 +474,7 @@ where }) } -fn fresh_statement() -> impl NoirParser { +pub fn fresh_statement() -> impl NoirParser { statement(expression(), expression_no_constructors(expression())) } @@ -530,7 +530,7 @@ where p.map(StatementKind::new_let) } -fn pattern() -> impl NoirParser { +pub fn pattern() -> impl NoirParser { recursive(|pattern| { let ident_pattern = ident().map(Pattern::Identifier).map_err(|mut error| { if matches!(error.found(), Token::IntType(..)) { diff --git a/noir_stdlib/src/meta/function_def.nr b/noir_stdlib/src/meta/function_def.nr index fca6a3641fa..dc1e9163411 100644 --- a/noir_stdlib/src/meta/function_def.nr +++ b/noir_stdlib/src/meta/function_def.nr @@ -7,4 +7,13 @@ impl FunctionDefinition { #[builtin(function_def_return_type)] fn return_type(self) -> Type {} + + #[builtin(function_def_set_body)] + fn set_body(mut self, body: Quoted) {} + + #[builtin(function_def_set_parameters)] + fn set_parameters(mut self, parameters: [(Quoted, Type)]) {} + + #[builtin(function_def_set_return_type)] + fn set_return_type(mut self, return_type: Type) {} } diff --git a/test_programs/compile_success_empty/comptime_function_definition/src/main.nr b/test_programs/compile_success_empty/comptime_function_definition/src/main.nr index 9297bdb4dfb..6ded326e0cf 100644 --- a/test_programs/compile_success_empty/comptime_function_definition/src/main.nr +++ b/test_programs/compile_success_empty/comptime_function_definition/src/main.nr @@ -4,9 +4,13 @@ struct Foo { x: Field, field: Field } #[function_attr] fn foo(w: i32, y: Field, Foo { x, field: some_field }: Foo, mut a: bool, (b, c): (i32, i32)) -> i32 { + let _ = (w, y, x, some_field, a, b, c); 1 } +#[mutate_add_one] +fn add_one() {} + comptime fn function_attr(f: FunctionDefinition) { // Check FunctionDefinition::parameters let parameters = f.parameters(); @@ -33,4 +37,21 @@ comptime fn function_attr(f: FunctionDefinition) { assert_eq(f.name(), quote { foo }); } -fn main() {} +comptime fn mutate_add_one(f: FunctionDefinition) { + // fn add_one(x: Field) + assert_eq(f.parameters().len(), 0); + f.set_parameters(&[(quote { x }, type_of(0))]); + assert_eq(f.parameters().len(), 1); + + // fn add_one(x: Field) -> Field + assert_eq(f.return_type(), type_of(())); + f.set_return_type(type_of(0)); + assert_eq(f.return_type(), type_of(0)); + + // fn add_one(x: Field) -> Field { x + 1 } + f.set_body(quote { x + 1 }); +} + +fn main() { + assert_eq(add_one(41), 42); +} From d208141919f30fc1d0af13d6b8440f53dad9d9d2 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 12:56:56 -0300 Subject: [PATCH 02/22] Use correct locations for errors --- .../src/hir/comptime/interpreter/builtin.rs | 192 ++++++++++-------- .../interpreter/builtin/builtin_helpers.rs | 18 +- .../src/hir/comptime/interpreter/foreign.rs | 7 +- 3 files changed, 125 insertions(+), 92 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 0e0d4c0945d..38890e24c4c 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -109,7 +109,7 @@ fn array_len( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let argument = check_one_argument(arguments, location)?; + let (argument, argument_location) = check_one_argument(arguments, location)?; match argument { Value::Array(values, _) | Value::Slice(values, _) => Ok(Value::U32(values.len() as u32)), @@ -117,7 +117,7 @@ fn array_len( let type_var = Box::new(interner.next_type_variable()); let expected = Type::Array(type_var.clone(), type_var); let actual = value.get_type().into_owned(); - Err(InterpreterError::TypeMismatch { expected, actual, location }) + Err(InterpreterError::TypeMismatch { expected, actual, location: argument_location }) } } } @@ -127,7 +127,7 @@ fn as_slice( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let array = check_one_argument(arguments, location)?; + let (array, array_location) = check_one_argument(arguments, location)?; match array { Value::Array(values, Type::Array(_, typ)) => Ok(Value::Slice(values, Type::Slice(typ))), @@ -135,7 +135,7 @@ fn as_slice( let type_var = Box::new(interner.next_type_variable()); let expected = Type::Array(type_var.clone(), type_var); let actual = value.get_type().into_owned(); - Err(InterpreterError::TypeMismatch { expected, actual, location }) + Err(InterpreterError::TypeMismatch { expected, actual, location: array_location }) } } } @@ -145,9 +145,9 @@ fn slice_push_back( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (slice, element) = check_two_arguments(arguments, location)?; + let ((slice, slice_location), (element, _)) = check_two_arguments(arguments, location)?; - let (mut values, typ) = get_slice(interner, slice, location)?; + let (mut values, typ) = get_slice(interner, slice, slice_location)?; values.push_back(element); Ok(Value::Slice(values, typ)) } @@ -158,14 +158,18 @@ fn struct_def_as_type( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let argument = check_one_argument(arguments, location)?; + let (argument, argument_location) = check_one_argument(arguments, location)?; let struct_def = match argument { Value::StructDefinition(id) => id, value => { let expected = Type::Quoted(QuotedType::StructDefinition); let actual = value.get_type().into_owned(); - return Err(InterpreterError::TypeMismatch { expected, location, actual }); + return Err(InterpreterError::TypeMismatch { + expected, + location: argument_location, + actual, + }); } }; @@ -186,14 +190,18 @@ fn struct_def_generics( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let argument = check_one_argument(arguments, location)?; + let (argument, argument_location) = check_one_argument(arguments, location)?; let struct_def = match argument { Value::StructDefinition(id) => id, value => { let expected = Type::Quoted(QuotedType::StructDefinition); let actual = value.get_type().into_owned(); - return Err(InterpreterError::TypeMismatch { expected, location, actual }); + return Err(InterpreterError::TypeMismatch { + expected, + location: argument_location, + actual, + }); } }; @@ -214,14 +222,18 @@ fn struct_def_fields( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let argument = check_one_argument(arguments, location)?; + let (argument, argument_location) = check_one_argument(arguments, location)?; let struct_def = match argument { Value::StructDefinition(id) => id, value => { let expected = Type::Quoted(QuotedType::StructDefinition); let actual = value.get_type().into_owned(); - return Err(InterpreterError::TypeMismatch { expected, location, actual }); + return Err(InterpreterError::TypeMismatch { + expected, + location: argument_location, + actual, + }); } }; @@ -248,10 +260,11 @@ fn slice_remove( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (slice, index) = check_two_arguments(arguments, location)?; + let ((slice, slice_location), (index, index_location)) = + check_two_arguments(arguments, location)?; - let index = get_u32(index, location)? as usize; - let (mut values, typ) = get_slice(interner, slice, location)?; + let index = get_u32(index, index_location)? as usize; + let (mut values, typ) = get_slice(interner, slice, slice_location)?; if values.is_empty() { return failing_constraint("slice_remove called on empty slice", location); @@ -274,9 +287,9 @@ fn slice_push_front( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (slice, element) = check_two_arguments(arguments, location)?; + let ((slice, slice_location), (element, _)) = check_two_arguments(arguments, location)?; - let (mut values, typ) = get_slice(interner, slice, location)?; + let (mut values, typ) = get_slice(interner, slice, slice_location)?; values.push_front(element); Ok(Value::Slice(values, typ)) } @@ -286,9 +299,9 @@ fn slice_pop_front( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let argument = check_one_argument(arguments, location)?; + let (argument, argument_location) = check_one_argument(arguments, location)?; - let (mut values, typ) = get_slice(interner, argument, location)?; + let (mut values, typ) = get_slice(interner, argument, argument_location)?; match values.pop_front() { Some(element) => Ok(Value::Tuple(vec![element, Value::Slice(values, typ)])), None => failing_constraint("slice_pop_front called on empty slice", location), @@ -300,9 +313,9 @@ fn slice_pop_back( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let argument = check_one_argument(arguments, location)?; + let (argument, argument_location) = check_one_argument(arguments, location)?; - let (mut values, typ) = get_slice(interner, argument, location)?; + let (mut values, typ) = get_slice(interner, argument, argument_location)?; match values.pop_back() { Some(element) => Ok(Value::Tuple(vec![Value::Slice(values, typ), element])), None => failing_constraint("slice_pop_back called on empty slice", location), @@ -314,10 +327,11 @@ fn slice_insert( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (slice, index, element) = check_three_arguments(arguments, location)?; + let ((slice, slice_location), (index, index_location), (element, _)) = + check_three_arguments(arguments, location)?; - let index = get_u32(index, location)? as usize; - let (mut values, typ) = get_slice(interner, slice, location)?; + let index = get_u32(index, index_location)? as usize; + let (mut values, typ) = get_slice(interner, slice, slice_location)?; values.insert(index, element); Ok(Value::Slice(values, typ)) } @@ -329,10 +343,10 @@ fn quoted_as_module( return_type: Type, location: Location, ) -> IResult { - let argument = check_one_argument(arguments, location)?; + let (argument, argument_location) = check_one_argument(arguments, location)?; - let tokens = get_quoted(argument, location)?; - let quoted = add_token_spans(tokens.clone(), location.span); + let tokens = get_quoted(argument, argument_location)?; + let quoted = add_token_spans(tokens.clone(), argument_location.span); let path = parser::path_no_turbofish().parse(quoted).ok(); let option_value = path.and_then(|path| { @@ -351,10 +365,10 @@ fn quoted_as_trait_constraint( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let argument = check_one_argument(arguments, location)?; + let (argument, argument_location) = check_one_argument(arguments, location)?; - let tokens = get_quoted(argument, location)?; - let quoted = add_token_spans(tokens.clone(), location.span); + let tokens = get_quoted(argument, argument_location)?; + let quoted = add_token_spans(tokens.clone(), argument_location.span); let trait_bound = parser::trait_bound().parse(quoted).map_err(|mut errors| { let error = errors.swap_remove(0); @@ -377,10 +391,10 @@ fn quoted_as_type( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let argument = check_one_argument(arguments, location)?; + let (argument, argument_location) = check_one_argument(arguments, location)?; - let tokens = get_quoted(argument, location)?; - let quoted = add_token_spans(tokens.clone(), location.span); + let tokens = get_quoted(argument, argument_location)?; + let quoted = add_token_spans(tokens.clone(), argument_location.span); let typ = parser::parse_type().parse(quoted).map_err(|mut errors| { let error = errors.swap_remove(0); @@ -506,8 +520,8 @@ fn type_as( where F: FnOnce(Type) -> Option, { - let value = check_one_argument(arguments, location)?; - let typ = get_type(value, location)?; + let (value, value_location) = check_one_argument(arguments, location)?; + let typ = get_type(value, value_location)?; let option_value = f(typ); @@ -516,33 +530,34 @@ where // fn type_eq(_first: Type, _second: Type) -> bool fn type_eq(arguments: Vec<(Value, Location)>, location: Location) -> IResult { - let (self_type, other_type) = check_two_arguments(arguments, location)?; + let ((self_type, self_type_location), (other_type, other_type_location)) = + check_two_arguments(arguments, location)?; - let self_type = get_type(self_type, location)?; - let other_type = get_type(other_type, location)?; + let self_type = get_type(self_type, self_type_location)?; + let other_type = get_type(other_type, other_type_location)?; Ok(Value::Bool(self_type == other_type)) } // fn is_bool(self) -> bool fn type_is_bool(arguments: Vec<(Value, Location)>, location: Location) -> IResult { - let value = check_one_argument(arguments, location)?; - let typ = get_type(value, location)?; + let (value, value_location) = check_one_argument(arguments, location)?; + let typ = get_type(value, value_location)?; Ok(Value::Bool(matches!(typ, Type::Bool))) } // fn is_field(self) -> bool fn type_is_field(arguments: Vec<(Value, Location)>, location: Location) -> IResult { - let value = check_one_argument(arguments, location)?; - let typ = get_type(value, location)?; + let (value, value_location) = check_one_argument(arguments, location)?; + let typ = get_type(value, value_location)?; Ok(Value::Bool(matches!(typ, Type::FieldElement))) } // fn type_of(x: T) -> Type fn type_of(arguments: Vec<(Value, Location)>, location: Location) -> IResult { - let value = check_one_argument(arguments, location)?; + let (value, _) = check_one_argument(arguments, location)?; let typ = value.get_type().into_owned(); Ok(Value::Type(typ)) } @@ -553,9 +568,9 @@ fn trait_constraint_hash( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let argument = check_one_argument(arguments, location)?; + let (argument, argument_location) = check_one_argument(arguments, location)?; - let bound = get_trait_constraint(argument, location)?; + let bound = get_trait_constraint(argument, argument_location)?; let mut hasher = std::collections::hash_map::DefaultHasher::new(); bound.hash(&mut hasher); @@ -570,10 +585,11 @@ fn trait_constraint_eq( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (value_a, value_b) = check_two_arguments(arguments, location)?; + let ((value_a, value_a_location), (value_b, value_b_location)) = + check_two_arguments(arguments, location)?; - let constraint_a = get_trait_constraint(value_a, location)?; - let constraint_b = get_trait_constraint(value_b, location)?; + let constraint_a = get_trait_constraint(value_a, value_a_location)?; + let constraint_b = get_trait_constraint(value_b, value_b_location)?; Ok(Value::Bool(constraint_a == constraint_b)) } @@ -696,8 +712,8 @@ fn function_def_name( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let self_argument = check_one_argument(arguments, location)?; - let func_id = get_function_def(self_argument, location)?; + let (self_argument, self_argument_location) = check_one_argument(arguments, location)?; + let func_id = get_function_def(self_argument, self_argument_location)?; let name = interner.function_name(&func_id).to_string(); let tokens = Rc::new(vec![Token::Ident(name)]); Ok(Value::Quoted(tokens)) @@ -709,8 +725,8 @@ fn function_def_parameters( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let self_argument = check_one_argument(arguments, location)?; - let func_id = get_function_def(self_argument, location)?; + let (self_argument, self_argument_location) = check_one_argument(arguments, location)?; + let func_id = get_function_def(self_argument, self_argument_location)?; let func_meta = interner.function_meta(&func_id); let parameters = func_meta @@ -737,8 +753,8 @@ fn function_def_return_type( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let self_argument = check_one_argument(arguments, location)?; - let func_id = get_function_def(self_argument, location)?; + let (self_argument, self_argument_location) = check_one_argument(arguments, location)?; + let func_id = get_function_def(self_argument, self_argument_location)?; let func_meta = interner.function_meta(&func_id); Ok(Value::Type(func_meta.return_type().follow_bindings())) @@ -750,8 +766,9 @@ fn function_def_set_body( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (self_argument, body_argument) = check_two_arguments(arguments, location)?; - let func_id = get_function_def(self_argument, location)?; + let ((self_argument, self_argument_location), (body_argument, body_argument_location)) = + check_two_arguments(arguments, location)?; + let func_id = get_function_def(self_argument, self_argument_location)?; let func_meta = interpreter.elaborator.interner.function_meta(&func_id); match func_meta.function_body { @@ -761,8 +778,8 @@ fn function_def_set_body( } } - let body_tokens = get_quoted(body_argument, location)?; - let mut body_quoted = add_token_spans(body_tokens.clone(), location.span); + let body_tokens = get_quoted(body_argument, body_argument_location)?; + let mut body_quoted = add_token_spans(body_tokens.clone(), body_argument_location.span); // Surround the body in `{ ... }` so we can parse it as a block body_quoted.0.insert(0, SpannedToken::new(Token::LeftBrace, location.span)); @@ -793,9 +810,12 @@ fn function_def_set_parameters( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (self_argument, parameters_argument) = check_two_arguments(arguments, location)?; + let ( + (self_argument, self_argument_location), + (parameters_argument, parameters_argument_location), + ) = check_two_arguments(arguments, location)?; - let func_id = get_function_def(self_argument, location)?; + let func_id = get_function_def(self_argument, self_argument_location)?; let func_meta = interpreter.elaborator.interner.function_meta(&func_id); match func_meta.function_body { FunctionBody::Unresolved(_, _, _) => (), @@ -804,8 +824,11 @@ fn function_def_set_parameters( } } - let (input_parameters, _type) = - get_slice(interpreter.elaborator.interner, parameters_argument, location)?; + let (input_parameters, _type) = get_slice( + interpreter.elaborator.interner, + parameters_argument, + parameters_argument_location, + )?; // What follows is very similar to what happens in Elaborator::define_function_meta let mut parameters = Vec::new(); @@ -813,10 +836,15 @@ 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, location)?; - let parameter_type = get_type(tuple.pop().unwrap(), location)?; - let parameter_name_tokens = get_quoted(tuple.pop().unwrap(), location)?; - let parameter_name_quoted = add_token_spans(parameter_name_tokens.clone(), location.span); + let mut tuple = get_tuple( + interpreter.elaborator.interner, + input_parameter, + parameters_argument_location, + )?; + let parameter_type = get_type(tuple.pop().unwrap(), parameters_argument_location)?; + let parameter_name_tokens = get_quoted(tuple.pop().unwrap(), parameters_argument_location)?; + let parameter_name_quoted = + add_token_spans(parameter_name_tokens.clone(), parameters_argument_location.span); let parameter_pattern = parser::pattern().parse(parameter_name_quoted).map_err(|mut errors| { let error = errors.swap_remove(0); @@ -874,10 +902,13 @@ fn function_def_set_return_type( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (self_argument, return_type_argument) = check_two_arguments(arguments, location)?; - let return_type = get_type(return_type_argument, location)?; + let ( + (self_argument, self_argument_location), + (return_type_argument, return_type_argument_location), + ) = check_two_arguments(arguments, location)?; + let return_type = get_type(return_type_argument, return_type_argument_location)?; - let func_id = get_function_def(self_argument, location)?; + let func_id = get_function_def(self_argument, self_argument_location)?; let func_meta = interpreter.elaborator.interner.function_meta(&func_id); match func_meta.function_body { FunctionBody::Unresolved(_, _, _) => (), @@ -920,8 +951,8 @@ fn module_functions( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let self_argument = check_one_argument(arguments, location)?; - let module_id = get_module(self_argument, location)?; + let (self_argument, self_argument_location) = check_one_argument(arguments, location)?; + let module_id = get_module(self_argument, self_argument_location)?; let module_data = interpreter.elaborator.get_module(module_id); let func_ids = module_data .value_definitions() @@ -944,8 +975,8 @@ fn module_is_contract( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let self_argument = check_one_argument(arguments, location)?; - let module_id = get_module(self_argument, location)?; + let (self_argument, self_argument_location) = check_one_argument(arguments, location)?; + let module_id = get_module(self_argument, self_argument_location)?; Ok(Value::Bool(interpreter.elaborator.module_is_contract(module_id))) } @@ -955,8 +986,8 @@ fn module_name( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let self_argument = check_one_argument(arguments, location)?; - let module_id = get_module(self_argument, location)?; + let (self_argument, self_argument_location) = check_one_argument(arguments, location)?; + let module_id = get_module(self_argument, self_argument_location)?; let name = &interner.module_attributes(&module_id).name; let tokens = Rc::new(vec![Token::Ident(name.clone())]); Ok(Value::Quoted(tokens)) @@ -1028,10 +1059,11 @@ fn modulus_num_bits( // fn quoted_eq(_first: Quoted, _second: Quoted) -> bool fn quoted_eq(arguments: Vec<(Value, Location)>, location: Location) -> IResult { - let (self_value, other_value) = check_two_arguments(arguments, location)?; + let ((self_value, self_value_location), (other_value, other_value_location)) = + check_two_arguments(arguments, location)?; - let self_quoted = get_quoted(self_value, location)?; - let other_quoted = get_quoted(other_value, location)?; + let self_quoted = get_quoted(self_value, self_value_location)?; + let other_quoted = get_quoted(other_value, other_value_location)?; Ok(Value::Bool(self_quoted == other_quoted)) } @@ -1041,9 +1073,9 @@ fn trait_def_as_trait_constraint( arguments: Vec<(Value, Location)>, location: Location, ) -> Result { - let argument = check_one_argument(arguments, location)?; + let (argument, argument_location) = check_one_argument(arguments, location)?; - let trait_id = get_trait_def(argument, location)?; + let trait_id = get_trait_def(argument, argument_location)?; let the_trait = interner.get_trait(trait_id); let trait_generics = vecmap(&the_trait.generics, |generic| { Type::NamedGeneric(generic.type_var.clone(), generic.name.clone(), generic.kind.clone()) 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 f8f75f7f90d..99379fc4e33 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 @@ -32,20 +32,20 @@ pub(crate) fn check_argument_count( pub(crate) fn check_one_argument( mut arguments: Vec<(Value, Location)>, location: Location, -) -> IResult { +) -> IResult<(Value, Location)> { check_argument_count(1, &arguments, location)?; - Ok(arguments.pop().unwrap().0) + Ok(arguments.pop().unwrap()) } pub(crate) fn check_two_arguments( mut arguments: Vec<(Value, Location)>, location: Location, -) -> IResult<(Value, Value)> { +) -> IResult<((Value, Location), (Value, Location))> { check_argument_count(2, &arguments, location)?; - let argument2 = arguments.pop().unwrap().0; - let argument1 = arguments.pop().unwrap().0; + let argument2 = arguments.pop().unwrap(); + let argument1 = arguments.pop().unwrap(); Ok((argument1, argument2)) } @@ -53,12 +53,12 @@ pub(crate) fn check_two_arguments( pub(crate) fn check_three_arguments( mut arguments: Vec<(Value, Location)>, location: Location, -) -> IResult<(Value, Value, Value)> { +) -> IResult<((Value, Location), (Value, Location), (Value, Location))> { check_argument_count(3, &arguments, location)?; - let argument3 = arguments.pop().unwrap().0; - let argument2 = arguments.pop().unwrap().0; - let argument1 = arguments.pop().unwrap().0; + let argument3 = arguments.pop().unwrap(); + let argument2 = arguments.pop().unwrap(); + let argument1 = arguments.pop().unwrap(); Ok((argument1, argument2, argument3)) } diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs index d6e4553d142..3db58ee5b3f 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs @@ -31,10 +31,11 @@ fn poseidon2_permutation( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (input, state_length) = check_two_arguments(arguments, location)?; + let ((input, input_location), (state_length, state_length_location)) = + check_two_arguments(arguments, location)?; - let (input, typ) = get_array(interner, input, location)?; - let state_length = get_u32(state_length, location)?; + let (input, typ) = get_array(interner, input, input_location)?; + let state_length = get_u32(state_length, state_length_location)?; let input = try_vecmap(input, |integer| get_field(integer, location))?; From 698eefb0273adae53505be4532d053d6ba1922f7 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 14:22:34 -0300 Subject: [PATCH 03/22] Elaborate parameters in the target function --- compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 38890e24c4c..57146d5675f 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -857,7 +857,7 @@ fn function_def_set_parameters( } })?; - let hir_pattern = interpreter.elaborate_item(interpreter.current_function, |elaborator| { + let hir_pattern = interpreter.elaborate_item(Some(func_id), |elaborator| { elaborator.elaborate_pattern_and_store_ids( parameter_pattern, parameter_type.clone(), From 44e64b4e5bf9b280261d6d7ad17a507f1d664bfa Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 14:52:06 -0300 Subject: [PATCH 04/22] Let the many `get_...` functions take tuples --- .../src/hir/comptime/interpreter/builtin.rs | 226 +++++++----------- .../interpreter/builtin/builtin_helpers.rs | 39 +-- .../src/hir/comptime/interpreter/foreign.rs | 10 +- 3 files changed, 117 insertions(+), 158 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 57146d5675f..fdc20694c49 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -6,8 +6,8 @@ use std::{ use acvm::{AcirField, FieldElement}; use builtin_helpers::{ check_argument_count, check_one_argument, check_three_arguments, check_two_arguments, - get_function_def, get_module, get_quoted, get_slice, get_trait_constraint, get_trait_def, - get_tuple, get_type, get_u32, hir_pattern_to_tokens, + get_function_def, get_module, get_quoted, get_slice, get_struct, get_trait_constraint, + get_trait_def, get_tuple, get_type, get_u32, hir_pattern_to_tokens, }; use chumsky::Parser; use iter_extended::{try_vecmap, vecmap}; @@ -145,9 +145,9 @@ fn slice_push_back( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let ((slice, slice_location), (element, _)) = check_two_arguments(arguments, location)?; + let (slice, (element, _)) = check_two_arguments(arguments, location)?; - let (mut values, typ) = get_slice(interner, slice, slice_location)?; + let (mut values, typ) = get_slice(interner, slice)?; values.push_back(element); Ok(Value::Slice(values, typ)) } @@ -158,22 +158,9 @@ fn struct_def_as_type( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (argument, argument_location) = check_one_argument(arguments, location)?; - - let struct_def = match argument { - Value::StructDefinition(id) => id, - value => { - let expected = Type::Quoted(QuotedType::StructDefinition); - let actual = value.get_type().into_owned(); - return Err(InterpreterError::TypeMismatch { - expected, - location: argument_location, - actual, - }); - } - }; - - let struct_def_rc = interner.get_struct(struct_def); + let argument = check_one_argument(arguments, location)?; + let struct_id = get_struct(argument)?; + let struct_def_rc = interner.get_struct(struct_id); let struct_def = struct_def_rc.borrow(); let generics = vecmap(&struct_def.generics, |generic| { @@ -190,22 +177,9 @@ fn struct_def_generics( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (argument, argument_location) = check_one_argument(arguments, location)?; - - let struct_def = match argument { - Value::StructDefinition(id) => id, - value => { - let expected = Type::Quoted(QuotedType::StructDefinition); - let actual = value.get_type().into_owned(); - return Err(InterpreterError::TypeMismatch { - expected, - location: argument_location, - actual, - }); - } - }; - - let struct_def = interner.get_struct(struct_def); + let argument = check_one_argument(arguments, location)?; + let struct_id = get_struct(argument)?; + let struct_def = interner.get_struct(struct_id); let struct_def = struct_def.borrow(); let generics = @@ -222,22 +196,9 @@ fn struct_def_fields( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (argument, argument_location) = check_one_argument(arguments, location)?; - - let struct_def = match argument { - Value::StructDefinition(id) => id, - value => { - let expected = Type::Quoted(QuotedType::StructDefinition); - let actual = value.get_type().into_owned(); - return Err(InterpreterError::TypeMismatch { - expected, - location: argument_location, - actual, - }); - } - }; - - let struct_def = interner.get_struct(struct_def); + let argument = check_one_argument(arguments, location)?; + let struct_id = get_struct(argument)?; + let struct_def = interner.get_struct(struct_id); let struct_def = struct_def.borrow(); let mut fields = im::Vector::new(); @@ -260,11 +221,10 @@ fn slice_remove( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let ((slice, slice_location), (index, index_location)) = - check_two_arguments(arguments, location)?; + let (slice, index) = check_two_arguments(arguments, location)?; - let index = get_u32(index, index_location)? as usize; - let (mut values, typ) = get_slice(interner, slice, slice_location)?; + let (mut values, typ) = get_slice(interner, slice)?; + let index = get_u32(index)? as usize; if values.is_empty() { return failing_constraint("slice_remove called on empty slice", location); @@ -287,9 +247,9 @@ fn slice_push_front( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let ((slice, slice_location), (element, _)) = check_two_arguments(arguments, location)?; + let (slice, (element, _)) = check_two_arguments(arguments, location)?; - let (mut values, typ) = get_slice(interner, slice, slice_location)?; + let (mut values, typ) = get_slice(interner, slice)?; values.push_front(element); Ok(Value::Slice(values, typ)) } @@ -299,9 +259,9 @@ fn slice_pop_front( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (argument, argument_location) = check_one_argument(arguments, location)?; + let argument = check_one_argument(arguments, location)?; - let (mut values, typ) = get_slice(interner, argument, argument_location)?; + let (mut values, typ) = get_slice(interner, argument)?; match values.pop_front() { Some(element) => Ok(Value::Tuple(vec![element, Value::Slice(values, typ)])), None => failing_constraint("slice_pop_front called on empty slice", location), @@ -313,9 +273,9 @@ fn slice_pop_back( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (argument, argument_location) = check_one_argument(arguments, location)?; + let argument = check_one_argument(arguments, location)?; - let (mut values, typ) = get_slice(interner, argument, argument_location)?; + let (mut values, typ) = get_slice(interner, argument)?; match values.pop_back() { Some(element) => Ok(Value::Tuple(vec![Value::Slice(values, typ), element])), None => failing_constraint("slice_pop_back called on empty slice", location), @@ -327,11 +287,10 @@ fn slice_insert( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let ((slice, slice_location), (index, index_location), (element, _)) = - check_three_arguments(arguments, location)?; + let (slice, index, (element, _)) = check_three_arguments(arguments, location)?; - let index = get_u32(index, index_location)? as usize; - let (mut values, typ) = get_slice(interner, slice, slice_location)?; + let (mut values, typ) = get_slice(interner, slice)?; + let index = get_u32(index)? as usize; values.insert(index, element); Ok(Value::Slice(values, typ)) } @@ -343,9 +302,10 @@ fn quoted_as_module( return_type: Type, location: Location, ) -> IResult { - let (argument, argument_location) = check_one_argument(arguments, location)?; + let argument = check_one_argument(arguments, location)?; + let argument_location = argument.1; - let tokens = get_quoted(argument, argument_location)?; + let tokens = get_quoted(argument)?; let quoted = add_token_spans(tokens.clone(), argument_location.span); let path = parser::path_no_turbofish().parse(quoted).ok(); @@ -365,9 +325,10 @@ fn quoted_as_trait_constraint( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (argument, argument_location) = check_one_argument(arguments, location)?; + let argument = check_one_argument(arguments, location)?; + let argument_location = argument.1; - let tokens = get_quoted(argument, argument_location)?; + let tokens = get_quoted(argument)?; let quoted = add_token_spans(tokens.clone(), argument_location.span); let trait_bound = parser::trait_bound().parse(quoted).map_err(|mut errors| { @@ -391,9 +352,10 @@ fn quoted_as_type( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (argument, argument_location) = check_one_argument(arguments, location)?; + let argument = check_one_argument(arguments, location)?; + let argument_location = argument.1; - let tokens = get_quoted(argument, argument_location)?; + let tokens = get_quoted(argument)?; let quoted = add_token_spans(tokens.clone(), argument_location.span); let typ = parser::parse_type().parse(quoted).map_err(|mut errors| { @@ -520,8 +482,8 @@ fn type_as( where F: FnOnce(Type) -> Option, { - let (value, value_location) = check_one_argument(arguments, location)?; - let typ = get_type(value, value_location)?; + let value = check_one_argument(arguments, location)?; + let typ = get_type(value)?; let option_value = f(typ); @@ -530,27 +492,26 @@ where // fn type_eq(_first: Type, _second: Type) -> bool fn type_eq(arguments: Vec<(Value, Location)>, location: Location) -> IResult { - let ((self_type, self_type_location), (other_type, other_type_location)) = - check_two_arguments(arguments, location)?; + let (self_type, other_type) = check_two_arguments(arguments, location)?; - let self_type = get_type(self_type, self_type_location)?; - let other_type = get_type(other_type, other_type_location)?; + let self_type = get_type(self_type)?; + let other_type = get_type(other_type)?; Ok(Value::Bool(self_type == other_type)) } // fn is_bool(self) -> bool fn type_is_bool(arguments: Vec<(Value, Location)>, location: Location) -> IResult { - let (value, value_location) = check_one_argument(arguments, location)?; - let typ = get_type(value, value_location)?; + let value = check_one_argument(arguments, location)?; + let typ = get_type(value)?; Ok(Value::Bool(matches!(typ, Type::Bool))) } // fn is_field(self) -> bool fn type_is_field(arguments: Vec<(Value, Location)>, location: Location) -> IResult { - let (value, value_location) = check_one_argument(arguments, location)?; - let typ = get_type(value, value_location)?; + let value = check_one_argument(arguments, location)?; + let typ = get_type(value)?; Ok(Value::Bool(matches!(typ, Type::FieldElement))) } @@ -568,9 +529,9 @@ fn trait_constraint_hash( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (argument, argument_location) = check_one_argument(arguments, location)?; + let argument = check_one_argument(arguments, location)?; - let bound = get_trait_constraint(argument, argument_location)?; + let bound = get_trait_constraint(argument)?; let mut hasher = std::collections::hash_map::DefaultHasher::new(); bound.hash(&mut hasher); @@ -585,11 +546,10 @@ fn trait_constraint_eq( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let ((value_a, value_a_location), (value_b, value_b_location)) = - check_two_arguments(arguments, location)?; + let (value_a, value_b) = check_two_arguments(arguments, location)?; - let constraint_a = get_trait_constraint(value_a, value_a_location)?; - let constraint_b = get_trait_constraint(value_b, value_b_location)?; + let constraint_a = get_trait_constraint(value_a)?; + let constraint_b = get_trait_constraint(value_b)?; Ok(Value::Bool(constraint_a == constraint_b)) } @@ -597,12 +557,12 @@ fn trait_constraint_eq( // fn trait_def_hash(def: TraitDefinition) -> Field fn trait_def_hash( _interner: &mut NodeInterner, - mut arguments: Vec<(Value, Location)>, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - check_argument_count(1, &arguments, location)?; + let argument = check_one_argument(arguments, location)?; - let id = get_trait_def(arguments.pop().unwrap().0, location)?; + let id = get_trait_def(argument)?; let mut hasher = std::collections::hash_map::DefaultHasher::new(); id.hash(&mut hasher); @@ -614,13 +574,13 @@ fn trait_def_hash( // fn trait_def_eq(def_a: TraitDefinition, def_b: TraitDefinition) -> bool fn trait_def_eq( _interner: &mut NodeInterner, - mut arguments: Vec<(Value, Location)>, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - check_argument_count(2, &arguments, location)?; + let (id_a, id_b) = check_two_arguments(arguments, location)?; - let id_b = get_trait_def(arguments.pop().unwrap().0, location)?; - let id_a = get_trait_def(arguments.pop().unwrap().0, location)?; + let id_a = get_trait_def(id_a)?; + let id_b = get_trait_def(id_b)?; Ok(Value::Bool(id_a == id_b)) } @@ -712,8 +672,8 @@ fn function_def_name( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (self_argument, self_argument_location) = check_one_argument(arguments, location)?; - let func_id = get_function_def(self_argument, self_argument_location)?; + let self_argument = check_one_argument(arguments, location)?; + let func_id = get_function_def(self_argument)?; let name = interner.function_name(&func_id).to_string(); let tokens = Rc::new(vec![Token::Ident(name)]); Ok(Value::Quoted(tokens)) @@ -725,8 +685,8 @@ fn function_def_parameters( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (self_argument, self_argument_location) = check_one_argument(arguments, location)?; - let func_id = get_function_def(self_argument, self_argument_location)?; + let self_argument = check_one_argument(arguments, location)?; + let func_id = get_function_def(self_argument)?; let func_meta = interner.function_meta(&func_id); let parameters = func_meta @@ -753,8 +713,8 @@ fn function_def_return_type( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (self_argument, self_argument_location) = check_one_argument(arguments, location)?; - let func_id = get_function_def(self_argument, self_argument_location)?; + let self_argument = check_one_argument(arguments, location)?; + let func_id = get_function_def(self_argument)?; let func_meta = interner.function_meta(&func_id); Ok(Value::Type(func_meta.return_type().follow_bindings())) @@ -766,9 +726,10 @@ fn function_def_set_body( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let ((self_argument, self_argument_location), (body_argument, body_argument_location)) = - check_two_arguments(arguments, location)?; - let func_id = get_function_def(self_argument, self_argument_location)?; + let (self_argument, body_argument) = check_two_arguments(arguments, location)?; + let body_argument_location = body_argument.1; + + let func_id = get_function_def(self_argument)?; let func_meta = interpreter.elaborator.interner.function_meta(&func_id); match func_meta.function_body { @@ -778,7 +739,7 @@ fn function_def_set_body( } } - let body_tokens = get_quoted(body_argument, body_argument_location)?; + let body_tokens = get_quoted(body_argument)?; let mut body_quoted = add_token_spans(body_tokens.clone(), body_argument_location.span); // Surround the body in `{ ... }` so we can parse it as a block @@ -810,12 +771,10 @@ fn function_def_set_parameters( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let ( - (self_argument, self_argument_location), - (parameters_argument, parameters_argument_location), - ) = check_two_arguments(arguments, location)?; + let (self_argument, parameters_argument) = check_two_arguments(arguments, location)?; + let parameters_argument_location = parameters_argument.1; - let func_id = get_function_def(self_argument, self_argument_location)?; + let func_id = get_function_def(self_argument)?; let func_meta = interpreter.elaborator.interner.function_meta(&func_id); match func_meta.function_body { FunctionBody::Unresolved(_, _, _) => (), @@ -824,11 +783,8 @@ fn function_def_set_parameters( } } - let (input_parameters, _type) = get_slice( - interpreter.elaborator.interner, - parameters_argument, - parameters_argument_location, - )?; + let (input_parameters, _type) = + get_slice(interpreter.elaborator.interner, parameters_argument)?; // What follows is very similar to what happens in Elaborator::define_function_meta let mut parameters = Vec::new(); @@ -838,11 +794,11 @@ fn function_def_set_parameters( for input_parameter in input_parameters { let mut tuple = get_tuple( interpreter.elaborator.interner, - input_parameter, - parameters_argument_location, + (input_parameter, parameters_argument_location), )?; - let parameter_type = get_type(tuple.pop().unwrap(), parameters_argument_location)?; - let parameter_name_tokens = get_quoted(tuple.pop().unwrap(), parameters_argument_location)?; + let parameter_type = get_type((tuple.pop().unwrap(), parameters_argument_location))?; + let parameter_name_tokens = + get_quoted((tuple.pop().unwrap(), parameters_argument_location))?; let parameter_name_quoted = add_token_spans(parameter_name_tokens.clone(), parameters_argument_location.span); let parameter_pattern = @@ -902,13 +858,10 @@ fn function_def_set_return_type( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let ( - (self_argument, self_argument_location), - (return_type_argument, return_type_argument_location), - ) = check_two_arguments(arguments, location)?; - let return_type = get_type(return_type_argument, return_type_argument_location)?; + let (self_argument, return_type_argument) = check_two_arguments(arguments, location)?; + let return_type = get_type(return_type_argument)?; - let func_id = get_function_def(self_argument, self_argument_location)?; + let func_id = get_function_def(self_argument)?; let func_meta = interpreter.elaborator.interner.function_meta(&func_id); match func_meta.function_body { FunctionBody::Unresolved(_, _, _) => (), @@ -951,8 +904,8 @@ fn module_functions( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (self_argument, self_argument_location) = check_one_argument(arguments, location)?; - let module_id = get_module(self_argument, self_argument_location)?; + let self_argument = check_one_argument(arguments, location)?; + let module_id = get_module(self_argument)?; let module_data = interpreter.elaborator.get_module(module_id); let func_ids = module_data .value_definitions() @@ -975,8 +928,8 @@ fn module_is_contract( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (self_argument, self_argument_location) = check_one_argument(arguments, location)?; - let module_id = get_module(self_argument, self_argument_location)?; + let self_argument = check_one_argument(arguments, location)?; + let module_id = get_module(self_argument)?; Ok(Value::Bool(interpreter.elaborator.module_is_contract(module_id))) } @@ -986,8 +939,8 @@ fn module_name( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (self_argument, self_argument_location) = check_one_argument(arguments, location)?; - let module_id = get_module(self_argument, self_argument_location)?; + let self_argument = check_one_argument(arguments, location)?; + let module_id = get_module(self_argument)?; let name = &interner.module_attributes(&module_id).name; let tokens = Rc::new(vec![Token::Ident(name.clone())]); Ok(Value::Quoted(tokens)) @@ -1059,11 +1012,10 @@ fn modulus_num_bits( // fn quoted_eq(_first: Quoted, _second: Quoted) -> bool fn quoted_eq(arguments: Vec<(Value, Location)>, location: Location) -> IResult { - let ((self_value, self_value_location), (other_value, other_value_location)) = - check_two_arguments(arguments, location)?; + let (self_value, other_value) = check_two_arguments(arguments, location)?; - let self_quoted = get_quoted(self_value, self_value_location)?; - let other_quoted = get_quoted(other_value, other_value_location)?; + let self_quoted = get_quoted(self_value)?; + let other_quoted = get_quoted(other_value)?; Ok(Value::Bool(self_quoted == other_quoted)) } @@ -1073,9 +1025,9 @@ fn trait_def_as_trait_constraint( arguments: Vec<(Value, Location)>, location: Location, ) -> Result { - let (argument, argument_location) = check_one_argument(arguments, location)?; + let argument = check_one_argument(arguments, location)?; - let trait_id = get_trait_def(argument, argument_location)?; + let trait_id = get_trait_def(argument)?; let the_trait = interner.get_trait(trait_id); let trait_generics = vecmap(&the_trait.generics, |generic| { Type::NamedGeneric(generic.type_var.clone(), generic.name.clone(), generic.kind.clone()) 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 99379fc4e33..e440f37840c 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 @@ -10,7 +10,7 @@ use crate::{ def_map::ModuleId, }, hir_def::stmt::HirPattern, - macros_api::NodeInterner, + macros_api::{NodeInterner, StructId}, node_interner::{FuncId, TraitId}, token::Token, QuotedType, Type, @@ -65,8 +65,7 @@ pub(crate) fn check_three_arguments( pub(crate) fn get_array( interner: &NodeInterner, - value: Value, - location: Location, + (value, location): (Value, Location), ) -> IResult<(im::Vector, Type)> { match value { Value::Array(values, typ) => Ok((values, typ)), @@ -81,8 +80,7 @@ pub(crate) fn get_array( pub(crate) fn get_slice( interner: &NodeInterner, - value: Value, - location: Location, + (value, location): (Value, Location), ) -> IResult<(im::Vector, Type)> { match value { Value::Slice(values, typ) => Ok((values, typ)), @@ -97,8 +95,7 @@ pub(crate) fn get_slice( pub(crate) fn get_tuple( interner: &NodeInterner, - value: Value, - location: Location, + (value, location): (Value, Location), ) -> IResult> { match value { Value::Tuple(values) => Ok(values), @@ -111,7 +108,7 @@ pub(crate) fn get_tuple( } } -pub(crate) fn get_field(value: Value, location: Location) -> IResult { +pub(crate) fn get_field((value, location): (Value, Location)) -> IResult { match value { Value::Field(value) => Ok(value), value => { @@ -121,7 +118,7 @@ pub(crate) fn get_field(value: Value, location: Location) -> IResult IResult { +pub(crate) fn get_u32((value, location): (Value, Location)) -> IResult { match value { Value::U32(value) => Ok(value), value => { @@ -132,7 +129,7 @@ pub(crate) fn get_u32(value: Value, location: Location) -> IResult { } } -pub(crate) fn get_function_def(value: Value, location: Location) -> IResult { +pub(crate) fn get_function_def((value, location): (Value, Location)) -> IResult { match value { Value::FunctionDefinition(id) => Ok(id), value => { @@ -143,7 +140,7 @@ pub(crate) fn get_function_def(value: Value, location: Location) -> IResult IResult { +pub(crate) fn get_module((value, location): (Value, Location)) -> IResult { match value { Value::ModuleDefinition(module_id) => Ok(module_id), value => { @@ -154,9 +151,19 @@ pub(crate) fn get_module(value: Value, location: Location) -> IResult } } +pub(crate) fn get_struct((value, location): (Value, Location)) -> IResult { + match value { + Value::StructDefinition(id) => Ok(id), + _ => { + let expected = Type::Quoted(QuotedType::StructDefinition); + let actual = value.get_type().into_owned(); + return Err(InterpreterError::TypeMismatch { expected, location, actual }); + } + } +} + pub(crate) fn get_trait_constraint( - value: Value, - location: Location, + (value, location): (Value, Location), ) -> IResult<(TraitId, Vec)> { match value { Value::TraitConstraint(trait_id, generics) => Ok((trait_id, generics)), @@ -168,7 +175,7 @@ pub(crate) fn get_trait_constraint( } } -pub(crate) fn get_trait_def(value: Value, location: Location) -> IResult { +pub(crate) fn get_trait_def((value, location): (Value, Location)) -> IResult { match value { Value::TraitDefinition(id) => Ok(id), value => { @@ -179,7 +186,7 @@ pub(crate) fn get_trait_def(value: Value, location: Location) -> IResult IResult { +pub(crate) fn get_type((value, location): (Value, Location)) -> IResult { match value { Value::Type(typ) => Ok(typ), value => { @@ -190,7 +197,7 @@ pub(crate) fn get_type(value: Value, location: Location) -> IResult { } } -pub(crate) fn get_quoted(value: Value, location: Location) -> IResult>> { +pub(crate) fn get_quoted((value, location): (Value, Location)) -> IResult>> { match value { Value::Quoted(tokens) => Ok(tokens), value => { diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs index 3db58ee5b3f..f7caf84ec42 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs @@ -31,13 +31,13 @@ fn poseidon2_permutation( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let ((input, input_location), (state_length, state_length_location)) = - check_two_arguments(arguments, location)?; + let (input, state_length) = check_two_arguments(arguments, location)?; + let input_location = input.1; - let (input, typ) = get_array(interner, input, input_location)?; - let state_length = get_u32(state_length, state_length_location)?; + let (input, typ) = get_array(interner, input)?; + let state_length = get_u32(state_length)?; - let input = try_vecmap(input, |integer| get_field(integer, location))?; + let input = try_vecmap(input, |integer| get_field((integer, input_location)))?; // Currently locked to only bn254! let fields = Bn254BlackBoxSolver From 4bb9052ce4ed66ab928ac3d062eed75e0298bb19 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 14:52:51 -0300 Subject: [PATCH 05/22] Remove unneeded mut --- noir_stdlib/src/meta/function_def.nr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/noir_stdlib/src/meta/function_def.nr b/noir_stdlib/src/meta/function_def.nr index dc1e9163411..2b5ddd008ea 100644 --- a/noir_stdlib/src/meta/function_def.nr +++ b/noir_stdlib/src/meta/function_def.nr @@ -9,11 +9,11 @@ impl FunctionDefinition { fn return_type(self) -> Type {} #[builtin(function_def_set_body)] - fn set_body(mut self, body: Quoted) {} + fn set_body(self, body: Quoted) {} #[builtin(function_def_set_parameters)] - fn set_parameters(mut self, parameters: [(Quoted, Type)]) {} + fn set_parameters(self, parameters: [(Quoted, Type)]) {} #[builtin(function_def_set_return_type)] - fn set_return_type(mut self, return_type: Type) {} + fn set_return_type(self, return_type: Type) {} } From 134461a6f2b3a03c77defc0aabea12f7714dcfc4 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 14:54:54 -0300 Subject: [PATCH 06/22] Format --- .../src/hir/comptime/interpreter/builtin.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index fdc20694c49..79dea94b8fd 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -748,12 +748,10 @@ fn function_def_set_body( let body = parser::block(parser::fresh_statement()).parse(body_quoted).map_err(|mut errors| { - let error = errors.swap_remove(0); - let rule = "a block"; InterpreterError::FailedToParseMacro { - error, + error: errors.swap_remove(0), tokens: body_tokens, - rule, + rule: "a block", file: location.file, } })?; @@ -803,12 +801,10 @@ fn function_def_set_parameters( add_token_spans(parameter_name_tokens.clone(), parameters_argument_location.span); let parameter_pattern = parser::pattern().parse(parameter_name_quoted).map_err(|mut errors| { - let error = errors.swap_remove(0); - let rule = "a pattern"; InterpreterError::FailedToParseMacro { - error, + error: errors.swap_remove(0), tokens: parameter_name_tokens, - rule, + rule: "a pattern", file: location.file, } })?; From 1df883b55d50379e93c1f13a95e7c11175bf2c23 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 14:59:56 -0300 Subject: [PATCH 07/22] Extract `check_can_mutate_function` --- .../src/hir/comptime/interpreter/builtin.rs | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 79dea94b8fd..a1dd1c42c7e 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -20,9 +20,9 @@ use crate::{ Visibility, }, hir::comptime::{errors::IResult, value::add_token_spans, InterpreterError, Value}, - hir_def::function::FunctionBody, + hir_def::function::{FuncMeta, FunctionBody}, macros_api::{ModuleDefId, NodeInterner, Signedness}, - node_interner::DefinitionKind, + node_interner::{DefinitionKind, FuncId}, parser, token::{SpannedToken, Token}, QuotedType, Shared, Type, @@ -730,14 +730,7 @@ fn function_def_set_body( let body_argument_location = body_argument.1; let func_id = get_function_def(self_argument)?; - - let func_meta = interpreter.elaborator.interner.function_meta(&func_id); - match func_meta.function_body { - FunctionBody::Unresolved(_, _, _) => (), - FunctionBody::Resolving | FunctionBody::Resolved => { - return Err(InterpreterError::CannotMutateFunction { location }) - } - } + check_can_mutate_function(interpreter, func_id, location)?; let body_tokens = get_quoted(body_argument)?; let mut body_quoted = add_token_spans(body_tokens.clone(), body_argument_location.span); @@ -773,13 +766,7 @@ fn function_def_set_parameters( let parameters_argument_location = parameters_argument.1; let func_id = get_function_def(self_argument)?; - let func_meta = interpreter.elaborator.interner.function_meta(&func_id); - match func_meta.function_body { - FunctionBody::Unresolved(_, _, _) => (), - FunctionBody::Resolving | FunctionBody::Resolved => { - return Err(InterpreterError::CannotMutateFunction { location }) - } - } + check_can_mutate_function(interpreter, func_id, location)?; let (input_parameters, _type) = get_slice(interpreter.elaborator.interner, parameters_argument)?; @@ -858,13 +845,7 @@ fn function_def_set_return_type( let return_type = get_type(return_type_argument)?; let func_id = get_function_def(self_argument)?; - let func_meta = interpreter.elaborator.interner.function_meta(&func_id); - match func_meta.function_body { - FunctionBody::Unresolved(_, _, _) => (), - FunctionBody::Resolving | FunctionBody::Resolved => { - return Err(InterpreterError::CannotMutateFunction { location }) - } - } + let func_meta = check_can_mutate_function(interpreter, func_id, location)?; let parameter_types = func_meta.parameters.iter().map(|(_, typ, _)| typ.clone()).collect(); @@ -1059,3 +1040,17 @@ pub(crate) fn extract_option_generic_type(typ: Type) -> Type { generics.pop().expect("Expected Option to have a T generic type") } + +fn check_can_mutate_function<'a>( + interpreter: &'a Interpreter, + func_id: FuncId, + location: Location, +) -> Result<&'a FuncMeta, InterpreterError> { + let func_meta = interpreter.elaborator.interner.function_meta(&func_id); + match func_meta.function_body { + FunctionBody::Unresolved(_, _, _) => Ok(func_meta), + FunctionBody::Resolving | FunctionBody::Resolved => { + return Err(InterpreterError::CannotMutateFunction { location }) + } + } +} From a496d871de028585581acc5bc2da5a52f60b7b5e Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 15:15:59 -0300 Subject: [PATCH 08/22] Extract a `parse` helper function --- .../src/hir/comptime/interpreter/builtin.rs | 94 ++++++++----------- 1 file changed, 40 insertions(+), 54 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index a1dd1c42c7e..b3f1d18371e 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -9,7 +9,6 @@ use builtin_helpers::{ get_function_def, get_module, get_quoted, get_slice, get_struct, get_trait_constraint, get_trait_def, get_tuple, get_type, get_u32, hir_pattern_to_tokens, }; -use chumsky::Parser; use iter_extended::{try_vecmap, vecmap}; use noirc_errors::Location; use rustc_hash::FxHashMap as HashMap; @@ -23,8 +22,8 @@ use crate::{ hir_def::function::{FuncMeta, FunctionBody}, macros_api::{ModuleDefId, NodeInterner, Signedness}, node_interner::{DefinitionKind, FuncId}, - parser, - token::{SpannedToken, Token}, + parser::{self, NoirParser}, + token::{SpannedToken, Token, Tokens}, QuotedType, Shared, Type, }; @@ -303,12 +302,8 @@ fn quoted_as_module( location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; - let argument_location = argument.1; - let tokens = get_quoted(argument)?; - let quoted = add_token_spans(tokens.clone(), argument_location.span); - - let path = parser::path_no_turbofish().parse(quoted).ok(); + let path = parse(argument, parser::path_no_turbofish(), "a path").ok(); let option_value = path.and_then(|path| { let module = interpreter.elaborate_item(interpreter.current_function, |elaborator| { elaborator.resolve_module_by_path(path) @@ -326,23 +321,12 @@ fn quoted_as_trait_constraint( location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; - let argument_location = argument.1; - - let tokens = get_quoted(argument)?; - let quoted = add_token_spans(tokens.clone(), argument_location.span); - - let trait_bound = parser::trait_bound().parse(quoted).map_err(|mut errors| { - let error = errors.swap_remove(0); - let rule = "a trait constraint"; - InterpreterError::FailedToParseMacro { error, tokens, rule, file: location.file } - })?; - + let trait_bound = parse(argument, parser::trait_bound(), "a trait constraint")?; let bound = interpreter .elaborate_item(interpreter.current_function, |elaborator| { elaborator.resolve_trait_bound(&trait_bound, Type::Unit) }) .ok_or(InterpreterError::FailedToResolveTraitBound { trait_bound, location })?; - Ok(Value::TraitConstraint(bound.trait_id, bound.trait_generics)) } @@ -353,20 +337,9 @@ fn quoted_as_type( location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; - let argument_location = argument.1; - - let tokens = get_quoted(argument)?; - let quoted = add_token_spans(tokens.clone(), argument_location.span); - - let typ = parser::parse_type().parse(quoted).map_err(|mut errors| { - let error = errors.swap_remove(0); - let rule = "a type"; - InterpreterError::FailedToParseMacro { error, tokens, rule, file: location.file } - })?; - + let typ = parse(argument, parser::parse_type(), "a type")?; let typ = interpreter.elaborate_item(interpreter.current_function, |elab| elab.resolve_type(typ)); - Ok(Value::Type(typ)) } @@ -739,15 +712,13 @@ fn function_def_set_body( body_quoted.0.insert(0, SpannedToken::new(Token::LeftBrace, location.span)); body_quoted.0.push(SpannedToken::new(Token::RightBrace, location.span)); - let body = - parser::block(parser::fresh_statement()).parse(body_quoted).map_err(|mut errors| { - InterpreterError::FailedToParseMacro { - error: errors.swap_remove(0), - tokens: body_tokens, - rule: "a block", - file: location.file, - } - })?; + let body = parse_tokens( + body_tokens, + body_quoted, + body_argument_location, + parser::block(parser::fresh_statement()), + "a block", + )?; let func_meta = interpreter.elaborator.interner.function_meta_mut(&func_id); func_meta.has_body = true; @@ -782,19 +753,11 @@ fn function_def_set_parameters( (input_parameter, parameters_argument_location), )?; let parameter_type = get_type((tuple.pop().unwrap(), parameters_argument_location))?; - let parameter_name_tokens = - get_quoted((tuple.pop().unwrap(), parameters_argument_location))?; - let parameter_name_quoted = - add_token_spans(parameter_name_tokens.clone(), parameters_argument_location.span); - let parameter_pattern = - parser::pattern().parse(parameter_name_quoted).map_err(|mut errors| { - InterpreterError::FailedToParseMacro { - error: errors.swap_remove(0), - tokens: parameter_name_tokens, - rule: "a pattern", - file: location.file, - } - })?; + let parameter_pattern = parse( + (tuple.pop().unwrap(), parameters_argument_location), + parser::pattern(), + "a pattern", + )?; let hir_pattern = interpreter.elaborate_item(Some(func_id), |elaborator| { elaborator.elaborate_pattern_and_store_ids( @@ -1054,3 +1017,26 @@ fn check_can_mutate_function<'a>( } } } + +fn parse( + (value, location): (Value, Location), + parser: impl NoirParser, + rule: &'static str, +) -> IResult { + let tokens = get_quoted((value, location))?; + let quoted = add_token_spans(tokens.clone(), location.span); + parse_tokens(tokens, quoted, location, parser, rule) +} + +fn parse_tokens( + tokens: Rc>, + quoted: Tokens, + location: Location, + parser: impl NoirParser, + rule: &'static str, +) -> IResult { + parser.parse(quoted).map_err(|mut errors| { + let error = errors.swap_remove(0); + InterpreterError::FailedToParseMacro { error, tokens, rule, file: location.file } + }) +} From 0d284c95a0c1bf5128a6e502dd800d6170b9aa0e Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 15:20:48 -0300 Subject: [PATCH 09/22] Handle generics --- .../src/hir/comptime/interpreter/builtin.rs | 20 ++++++++----------- .../comptime_function_definition/src/main.nr | 6 +++--- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index b3f1d18371e..ef6639f85c2 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -774,17 +774,15 @@ fn function_def_set_parameters( } let func_meta = interpreter.elaborator.interner.function_meta(&func_id); - let function_type = Type::Function( + let mut function_type = Type::Function( parameter_types, Box::new(func_meta.return_type().clone()), Box::new(Type::Unit), ); - // TODO: generics. In Elaborator::define_function_meta there's this code: - // - // if !generics.is_empty() { - // typ = Type::Forall(generics, Box::new(typ)); - // } + if let Type::Forall(generics, _) = &func_meta.typ { + function_type = Type::Forall(generics.clone(), Box::new(function_type)); + } interpreter.elaborator.interner.push_definition_type(func_meta.name.id, function_type.clone()); @@ -813,14 +811,12 @@ fn function_def_set_return_type( let parameter_types = func_meta.parameters.iter().map(|(_, typ, _)| typ.clone()).collect(); let func_meta = interpreter.elaborator.interner.function_meta(&func_id); - let function_type = + let mut function_type = Type::Function(parameter_types, Box::new(return_type.clone()), Box::new(Type::Unit)); - // TODO: generics. In Elaborator::define_function_meta there's this code: - // - // if !generics.is_empty() { - // typ = Type::Forall(generics, Box::new(typ)); - // } + if let Type::Forall(generics, _) = &func_meta.typ { + function_type = Type::Forall(generics.clone(), Box::new(function_type)); + } interpreter.elaborator.interner.push_definition_type(func_meta.name.id, function_type.clone()); diff --git a/test_programs/compile_success_empty/comptime_function_definition/src/main.nr b/test_programs/compile_success_empty/comptime_function_definition/src/main.nr index 6ded326e0cf..ce09ba86e49 100644 --- a/test_programs/compile_success_empty/comptime_function_definition/src/main.nr +++ b/test_programs/compile_success_empty/comptime_function_definition/src/main.nr @@ -8,9 +8,6 @@ fn foo(w: i32, y: Field, Foo { x, field: some_field }: Foo, mut a: bool, (b, c): 1 } -#[mutate_add_one] -fn add_one() {} - comptime fn function_attr(f: FunctionDefinition) { // Check FunctionDefinition::parameters let parameters = f.parameters(); @@ -37,6 +34,9 @@ comptime fn function_attr(f: FunctionDefinition) { assert_eq(f.name(), quote { foo }); } +#[mutate_add_one] +fn add_one() {} + comptime fn mutate_add_one(f: FunctionDefinition) { // fn add_one(x: Field) assert_eq(f.parameters().len(), 0); From 2b1a1ee84a3a525ca3b5efeede66282c3f442416 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 15:21:14 -0300 Subject: [PATCH 10/22] Remove unneeded blocks --- .../src/hir/comptime/interpreter/builtin.rs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index ef6639f85c2..e134ebb0323 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -786,12 +786,10 @@ fn function_def_set_parameters( interpreter.elaborator.interner.push_definition_type(func_meta.name.id, function_type.clone()); - { - let func_meta = interpreter.elaborator.interner.function_meta_mut(&func_id); - func_meta.parameters = parameters.into(); - func_meta.parameter_idents = parameter_idents; - func_meta.typ = function_type; - } + let func_meta = interpreter.elaborator.interner.function_meta_mut(&func_id); + func_meta.parameters = parameters.into(); + func_meta.parameter_idents = parameter_idents; + func_meta.typ = function_type; Ok(Value::Unit) } @@ -822,14 +820,12 @@ fn function_def_set_return_type( let quoted_type_id = interpreter.elaborator.interner.push_quoted_type(return_type); - { - let func_meta = interpreter.elaborator.interner.function_meta_mut(&func_id); - func_meta.return_type = FunctionReturnType::Ty(UnresolvedType { - typ: UnresolvedTypeData::Resolved(quoted_type_id), - span: Some(location.span), - }); - func_meta.typ = function_type; - } + let func_meta = interpreter.elaborator.interner.function_meta_mut(&func_id); + func_meta.return_type = FunctionReturnType::Ty(UnresolvedType { + typ: UnresolvedTypeData::Resolved(quoted_type_id), + span: Some(location.span), + }); + func_meta.typ = function_type; Ok(Value::Unit) } From ff3e3a5917c7b2b47c822c4f9805ef038b6e2f9d Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 15:24:58 -0300 Subject: [PATCH 11/22] Better message for when a function is already resolved --- compiler/noirc_frontend/src/hir/comptime/errors.rs | 13 ++++++++----- .../src/hir/comptime/interpreter/builtin.rs | 10 +++++----- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/errors.rs b/compiler/noirc_frontend/src/hir/comptime/errors.rs index 26e17faf2ac..b7b49090232 100644 --- a/compiler/noirc_frontend/src/hir/comptime/errors.rs +++ b/compiler/noirc_frontend/src/hir/comptime/errors.rs @@ -185,7 +185,7 @@ pub enum InterpreterError { FailedToResolveTraitDefinition { location: Location, }, - CannotMutateFunction { + FunctionAlreadyResolved { location: Location, }, @@ -258,7 +258,7 @@ impl InterpreterError { | InterpreterError::TraitDefinitionMustBeAPath { location } | InterpreterError::FailedToResolveTraitDefinition { location } | InterpreterError::FailedToResolveTraitBound { location, .. } => *location, - InterpreterError::CannotMutateFunction { location, .. } => *location, + InterpreterError::FunctionAlreadyResolved { location, .. } => *location, InterpreterError::FailedToParseMacro { error, file, .. } => { Location::new(error.span(), *file) @@ -520,9 +520,12 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { let msg = "Failed to resolve to a trait definition".to_string(); CustomDiagnostic::simple_error(msg, String::new(), location.span) } - InterpreterError::CannotMutateFunction { location } => { - let msg = "Cannot mutate function at this point".to_string(); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + InterpreterError::FunctionAlreadyResolved { location } => { + let msg = "Function already resolved".to_string(); + let secondary = + "The function was previously called at compile-time or is in another crate" + .to_string(); + CustomDiagnostic::simple_error(msg, secondary, location.span) } } } diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index e134ebb0323..5c03f21786b 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -703,7 +703,7 @@ fn function_def_set_body( let body_argument_location = body_argument.1; let func_id = get_function_def(self_argument)?; - check_can_mutate_function(interpreter, func_id, location)?; + check_function_not_yet_resolved(interpreter, func_id, location)?; let body_tokens = get_quoted(body_argument)?; let mut body_quoted = add_token_spans(body_tokens.clone(), body_argument_location.span); @@ -737,7 +737,7 @@ fn function_def_set_parameters( let parameters_argument_location = parameters_argument.1; let func_id = get_function_def(self_argument)?; - check_can_mutate_function(interpreter, func_id, location)?; + check_function_not_yet_resolved(interpreter, func_id, location)?; let (input_parameters, _type) = get_slice(interpreter.elaborator.interner, parameters_argument)?; @@ -804,7 +804,7 @@ fn function_def_set_return_type( let return_type = get_type(return_type_argument)?; let func_id = get_function_def(self_argument)?; - let func_meta = check_can_mutate_function(interpreter, func_id, location)?; + let func_meta = check_function_not_yet_resolved(interpreter, func_id, location)?; let parameter_types = func_meta.parameters.iter().map(|(_, typ, _)| typ.clone()).collect(); @@ -996,7 +996,7 @@ pub(crate) fn extract_option_generic_type(typ: Type) -> Type { generics.pop().expect("Expected Option to have a T generic type") } -fn check_can_mutate_function<'a>( +fn check_function_not_yet_resolved<'a>( interpreter: &'a Interpreter, func_id: FuncId, location: Location, @@ -1005,7 +1005,7 @@ fn check_can_mutate_function<'a>( match func_meta.function_body { FunctionBody::Unresolved(_, _, _) => Ok(func_meta), FunctionBody::Resolving | FunctionBody::Resolved => { - return Err(InterpreterError::CannotMutateFunction { location }) + return Err(InterpreterError::FunctionAlreadyResolved { location }) } } } From becdfb62db513cf67598bf6f5842e51508f32340 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 15:45:16 -0300 Subject: [PATCH 12/22] Mutate function meta's typ --- .../src/hir/comptime/interpreter/builtin.rs | 82 +++++++++++-------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 5c03f21786b..94edaef0788 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -773,23 +773,11 @@ fn function_def_set_parameters( parameter_types.push(parameter_type); } - let func_meta = interpreter.elaborator.interner.function_meta(&func_id); - let mut function_type = Type::Function( - parameter_types, - Box::new(func_meta.return_type().clone()), - Box::new(Type::Unit), - ); - - if let Type::Forall(generics, _) = &func_meta.typ { - function_type = Type::Forall(generics.clone(), Box::new(function_type)); - } - - interpreter.elaborator.interner.push_definition_type(func_meta.name.id, function_type.clone()); - - let func_meta = interpreter.elaborator.interner.function_meta_mut(&func_id); - func_meta.parameters = parameters.into(); - func_meta.parameter_idents = parameter_idents; - func_meta.typ = function_type; + mutate_func_meta(&mut interpreter.elaborator.interner, func_id, |func_meta| { + func_meta.parameters = parameters.into(); + func_meta.parameter_idents = parameter_idents; + replace_func_meta_parameters(&mut func_meta.typ, parameter_types); + }); Ok(Value::Unit) } @@ -804,28 +792,17 @@ fn function_def_set_return_type( let return_type = get_type(return_type_argument)?; let func_id = get_function_def(self_argument)?; - let func_meta = check_function_not_yet_resolved(interpreter, func_id, location)?; - - let parameter_types = func_meta.parameters.iter().map(|(_, typ, _)| typ.clone()).collect(); - - let func_meta = interpreter.elaborator.interner.function_meta(&func_id); - let mut function_type = - Type::Function(parameter_types, Box::new(return_type.clone()), Box::new(Type::Unit)); - - if let Type::Forall(generics, _) = &func_meta.typ { - function_type = Type::Forall(generics.clone(), Box::new(function_type)); - } - - interpreter.elaborator.interner.push_definition_type(func_meta.name.id, function_type.clone()); + check_function_not_yet_resolved(interpreter, func_id, location)?; - let quoted_type_id = interpreter.elaborator.interner.push_quoted_type(return_type); + let quoted_type_id = interpreter.elaborator.interner.push_quoted_type(return_type.clone()); - let func_meta = interpreter.elaborator.interner.function_meta_mut(&func_id); - func_meta.return_type = FunctionReturnType::Ty(UnresolvedType { - typ: UnresolvedTypeData::Resolved(quoted_type_id), - span: Some(location.span), + mutate_func_meta(&mut interpreter.elaborator.interner, func_id, |func_meta| { + func_meta.return_type = FunctionReturnType::Ty(UnresolvedType { + typ: UnresolvedTypeData::Resolved(quoted_type_id), + span: Some(location.span), + }); + replace_func_meta_return_type(&mut func_meta.typ, return_type); }); - func_meta.typ = function_type; Ok(Value::Unit) } @@ -1032,3 +1009,36 @@ fn parse_tokens( InterpreterError::FailedToParseMacro { error, tokens, rule, file: location.file } }) } + +fn mutate_func_meta(interner: &mut NodeInterner, func_id: FuncId, f: F) +where + F: FnOnce(&mut FuncMeta), +{ + let (name_id, function_type) = { + let func_meta = interner.function_meta_mut(&func_id); + f(func_meta); + (func_meta.name.id, func_meta.typ.clone()) + }; + + interner.push_definition_type(name_id, function_type); +} + +fn replace_func_meta_parameters(typ: &mut Type, parameter_types: Vec) { + match typ { + Type::Function(parameters, _, _) => { + *parameters = parameter_types; + } + Type::Forall(_, typ) => replace_func_meta_parameters(typ, parameter_types), + _ => {} + } +} + +fn replace_func_meta_return_type(typ: &mut Type, return_type: Type) { + match typ { + Type::Function(_, ret, _) => { + *ret = Box::new(return_type); + } + Type::Forall(_, typ) => replace_func_meta_return_type(typ, return_type), + _ => {} + } +} From 44e2a44ba648e92808e0605f67215aab41e2f8c9 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 15:46:09 -0300 Subject: [PATCH 13/22] mutate_func_meta -> mutate_func_meta_type --- .../noirc_frontend/src/hir/comptime/interpreter/builtin.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 94edaef0788..c1b5c8353fd 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -773,7 +773,7 @@ fn function_def_set_parameters( parameter_types.push(parameter_type); } - mutate_func_meta(&mut interpreter.elaborator.interner, func_id, |func_meta| { + mutate_func_meta_type(&mut interpreter.elaborator.interner, func_id, |func_meta| { func_meta.parameters = parameters.into(); func_meta.parameter_idents = parameter_idents; replace_func_meta_parameters(&mut func_meta.typ, parameter_types); @@ -796,7 +796,7 @@ fn function_def_set_return_type( let quoted_type_id = interpreter.elaborator.interner.push_quoted_type(return_type.clone()); - mutate_func_meta(&mut interpreter.elaborator.interner, func_id, |func_meta| { + mutate_func_meta_type(&mut interpreter.elaborator.interner, func_id, |func_meta| { func_meta.return_type = FunctionReturnType::Ty(UnresolvedType { typ: UnresolvedTypeData::Resolved(quoted_type_id), span: Some(location.span), @@ -1010,7 +1010,7 @@ fn parse_tokens( }) } -fn mutate_func_meta(interner: &mut NodeInterner, func_id: FuncId, f: F) +fn mutate_func_meta_type(interner: &mut NodeInterner, func_id: FuncId, f: F) where F: FnOnce(&mut FuncMeta), { From 47a6df0f4842c7ce148731e9d4b9755eda4a088a Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 15:47:13 -0300 Subject: [PATCH 14/22] Let `check_function_not_yet_resolved` return nothing --- .../src/hir/comptime/interpreter/builtin.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index c1b5c8353fd..5bd714c7d73 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -973,14 +973,14 @@ pub(crate) fn extract_option_generic_type(typ: Type) -> Type { generics.pop().expect("Expected Option to have a T generic type") } -fn check_function_not_yet_resolved<'a>( - interpreter: &'a Interpreter, +fn check_function_not_yet_resolved( + interpreter: &Interpreter, func_id: FuncId, location: Location, -) -> Result<&'a FuncMeta, InterpreterError> { +) -> Result<(), InterpreterError> { let func_meta = interpreter.elaborator.interner.function_meta(&func_id); match func_meta.function_body { - FunctionBody::Unresolved(_, _, _) => Ok(func_meta), + FunctionBody::Unresolved(_, _, _) => Ok(()), FunctionBody::Resolving | FunctionBody::Resolved => { return Err(InterpreterError::FunctionAlreadyResolved { location }) } From b0f04cfa1551a7d4dca71c2e932ee0b3ee1300be Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 15:54:29 -0300 Subject: [PATCH 15/22] Introduce `type ValueAndLocation` --- .../src/hir/comptime/interpreter/builtin.rs | 96 ++++++++++--------- .../interpreter/builtin/builtin_helpers.rs | 40 ++++---- 2 files changed, 70 insertions(+), 66 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 5bd714c7d73..f523e6ff67f 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -31,11 +31,13 @@ use super::Interpreter; pub(crate) mod builtin_helpers; +pub(crate) type ValueAndLocation = (Value, Location); + impl<'local, 'context> Interpreter<'local, 'context> { pub(super) fn call_builtin( &mut self, name: &str, - arguments: Vec<(Value, Location)>, + arguments: Vec, return_type: Type, location: Location, ) -> IResult { @@ -105,7 +107,7 @@ fn failing_constraint(message: impl Into, location: Location) -> IRes fn array_len( interner: &NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let (argument, argument_location) = check_one_argument(arguments, location)?; @@ -123,7 +125,7 @@ fn array_len( fn as_slice( interner: &NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let (array, array_location) = check_one_argument(arguments, location)?; @@ -141,7 +143,7 @@ fn as_slice( fn slice_push_back( interner: &NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let (slice, (element, _)) = check_two_arguments(arguments, location)?; @@ -154,7 +156,7 @@ fn slice_push_back( /// fn as_type(self) -> Type fn struct_def_as_type( interner: &NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -173,7 +175,7 @@ fn struct_def_as_type( /// fn generics(self) -> [Type] fn struct_def_generics( interner: &NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -192,7 +194,7 @@ fn struct_def_generics( /// Returns (name, type) pairs of each field of this StructDefinition fn struct_def_fields( interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -217,7 +219,7 @@ fn struct_def_fields( fn slice_remove( interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let (slice, index) = check_two_arguments(arguments, location)?; @@ -243,7 +245,7 @@ fn slice_remove( fn slice_push_front( interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let (slice, (element, _)) = check_two_arguments(arguments, location)?; @@ -255,7 +257,7 @@ fn slice_push_front( fn slice_pop_front( interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -269,7 +271,7 @@ fn slice_pop_front( fn slice_pop_back( interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -283,7 +285,7 @@ fn slice_pop_back( fn slice_insert( interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let (slice, index, (element, _)) = check_three_arguments(arguments, location)?; @@ -297,7 +299,7 @@ fn slice_insert( // fn as_module(quoted: Quoted) -> Option fn quoted_as_module( interpreter: &mut Interpreter, - arguments: Vec<(Value, Location)>, + arguments: Vec, return_type: Type, location: Location, ) -> IResult { @@ -317,7 +319,7 @@ fn quoted_as_module( // fn as_trait_constraint(quoted: Quoted) -> TraitConstraint fn quoted_as_trait_constraint( interpreter: &mut Interpreter, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -333,7 +335,7 @@ fn quoted_as_trait_constraint( // fn as_type(quoted: Quoted) -> Type fn quoted_as_type( interpreter: &mut Interpreter, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -345,7 +347,7 @@ fn quoted_as_type( // fn as_array(self) -> Option<(Type, Type)> fn type_as_array( - arguments: Vec<(Value, Location)>, + arguments: Vec, return_type: Type, location: Location, ) -> IResult { @@ -360,7 +362,7 @@ fn type_as_array( // fn as_constant(self) -> Option fn type_as_constant( - arguments: Vec<(Value, Location)>, + arguments: Vec, return_type: Type, location: Location, ) -> IResult { @@ -375,7 +377,7 @@ fn type_as_constant( // fn as_integer(self) -> Option<(bool, u8)> fn type_as_integer( - arguments: Vec<(Value, Location)>, + arguments: Vec, return_type: Type, location: Location, ) -> IResult { @@ -390,7 +392,7 @@ fn type_as_integer( // fn as_slice(self) -> Option fn type_as_slice( - arguments: Vec<(Value, Location)>, + arguments: Vec, return_type: Type, location: Location, ) -> IResult { @@ -405,7 +407,7 @@ fn type_as_slice( // fn as_struct(self) -> Option<(StructDefinition, [Type])> fn type_as_struct( - arguments: Vec<(Value, Location)>, + arguments: Vec, return_type: Type, location: Location, ) -> IResult { @@ -426,7 +428,7 @@ fn type_as_struct( // fn as_tuple(self) -> Option<[Type]> fn type_as_tuple( - arguments: Vec<(Value, Location)>, + arguments: Vec, return_type: Type, location: Location, ) -> IResult { @@ -447,7 +449,7 @@ fn type_as_tuple( // Helper function for implementing the `type_as_...` functions. fn type_as( - arguments: Vec<(Value, Location)>, + arguments: Vec, return_type: Type, location: Location, f: F, @@ -464,7 +466,7 @@ where } // fn type_eq(_first: Type, _second: Type) -> bool -fn type_eq(arguments: Vec<(Value, Location)>, location: Location) -> IResult { +fn type_eq(arguments: Vec, location: Location) -> IResult { let (self_type, other_type) = check_two_arguments(arguments, location)?; let self_type = get_type(self_type)?; @@ -474,7 +476,7 @@ fn type_eq(arguments: Vec<(Value, Location)>, location: Location) -> IResult bool -fn type_is_bool(arguments: Vec<(Value, Location)>, location: Location) -> IResult { +fn type_is_bool(arguments: Vec, location: Location) -> IResult { let value = check_one_argument(arguments, location)?; let typ = get_type(value)?; @@ -482,7 +484,7 @@ fn type_is_bool(arguments: Vec<(Value, Location)>, location: Location) -> IResul } // fn is_field(self) -> bool -fn type_is_field(arguments: Vec<(Value, Location)>, location: Location) -> IResult { +fn type_is_field(arguments: Vec, location: Location) -> IResult { let value = check_one_argument(arguments, location)?; let typ = get_type(value)?; @@ -490,7 +492,7 @@ fn type_is_field(arguments: Vec<(Value, Location)>, location: Location) -> IResu } // fn type_of(x: T) -> Type -fn type_of(arguments: Vec<(Value, Location)>, location: Location) -> IResult { +fn type_of(arguments: Vec, location: Location) -> IResult { let (value, _) = check_one_argument(arguments, location)?; let typ = value.get_type().into_owned(); Ok(Value::Type(typ)) @@ -499,7 +501,7 @@ fn type_of(arguments: Vec<(Value, Location)>, location: Location) -> IResult Field fn trait_constraint_hash( _interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -516,7 +518,7 @@ fn trait_constraint_hash( // fn constraint_eq(constraint_a: TraitConstraint, constraint_b: TraitConstraint) -> bool fn trait_constraint_eq( _interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let (value_a, value_b) = check_two_arguments(arguments, location)?; @@ -530,7 +532,7 @@ fn trait_constraint_eq( // fn trait_def_hash(def: TraitDefinition) -> Field fn trait_def_hash( _interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -547,7 +549,7 @@ fn trait_def_hash( // fn trait_def_eq(def_a: TraitDefinition, def_b: TraitDefinition) -> bool fn trait_def_eq( _interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let (id_a, id_b) = check_two_arguments(arguments, location)?; @@ -642,7 +644,7 @@ fn zeroed(return_type: Type) -> IResult { // fn name(self) -> Quoted fn function_def_name( interner: &NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let self_argument = check_one_argument(arguments, location)?; @@ -655,7 +657,7 @@ fn function_def_name( // fn parameters(self) -> [(Quoted, Type)] fn function_def_parameters( interner: &NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let self_argument = check_one_argument(arguments, location)?; @@ -683,7 +685,7 @@ fn function_def_parameters( // fn return_type(self) -> Type fn function_def_return_type( interner: &NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let self_argument = check_one_argument(arguments, location)?; @@ -696,7 +698,7 @@ fn function_def_return_type( // fn set_body(self, body: Quoted) fn function_def_set_body( interpreter: &mut Interpreter, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let (self_argument, body_argument) = check_two_arguments(arguments, location)?; @@ -730,7 +732,7 @@ fn function_def_set_body( // fn set_parameters(self, parameters: [(Quoted, Type)]) fn function_def_set_parameters( interpreter: &mut Interpreter, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let (self_argument, parameters_argument) = check_two_arguments(arguments, location)?; @@ -785,7 +787,7 @@ fn function_def_set_parameters( // fn set_return_type(self, return_type: Type) fn function_def_set_return_type( interpreter: &mut Interpreter, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let (self_argument, return_type_argument) = check_two_arguments(arguments, location)?; @@ -810,7 +812,7 @@ fn function_def_set_return_type( // fn functions(self) -> [FunctionDefinition] fn module_functions( interpreter: &Interpreter, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let self_argument = check_one_argument(arguments, location)?; @@ -834,7 +836,7 @@ fn module_functions( // fn is_contract(self) -> bool fn module_is_contract( interpreter: &Interpreter, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let self_argument = check_one_argument(arguments, location)?; @@ -845,7 +847,7 @@ fn module_is_contract( // fn name(self) -> Quoted fn module_name( interner: &NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let self_argument = check_one_argument(arguments, location)?; @@ -857,7 +859,7 @@ fn module_name( fn modulus_be_bits( _interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { check_argument_count(0, &arguments, location)?; @@ -872,7 +874,7 @@ fn modulus_be_bits( fn modulus_be_bytes( _interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { check_argument_count(0, &arguments, location)?; @@ -887,7 +889,7 @@ fn modulus_be_bytes( fn modulus_le_bits( interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let Value::Slice(bits, typ) = modulus_be_bits(interner, arguments, location)? else { @@ -899,7 +901,7 @@ fn modulus_le_bits( fn modulus_le_bytes( interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let Value::Slice(bytes, typ) = modulus_be_bytes(interner, arguments, location)? else { @@ -911,7 +913,7 @@ fn modulus_le_bytes( fn modulus_num_bits( _interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { check_argument_count(0, &arguments, location)?; @@ -920,7 +922,7 @@ fn modulus_num_bits( } // fn quoted_eq(_first: Quoted, _second: Quoted) -> bool -fn quoted_eq(arguments: Vec<(Value, Location)>, location: Location) -> IResult { +fn quoted_eq(arguments: Vec, location: Location) -> IResult { let (self_value, other_value) = check_two_arguments(arguments, location)?; let self_quoted = get_quoted(self_value)?; @@ -931,7 +933,7 @@ fn quoted_eq(arguments: Vec<(Value, Location)>, location: Location) -> IResult, + arguments: Vec, location: Location, ) -> Result { let argument = check_one_argument(arguments, location)?; @@ -988,7 +990,7 @@ fn check_function_not_yet_resolved( } fn parse( - (value, location): (Value, Location), + (value, location): ValueAndLocation, parser: impl NoirParser, rule: &'static str, ) -> IResult { 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 e440f37840c..45da0f3ffa1 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 @@ -16,9 +16,11 @@ use crate::{ QuotedType, Type, }; +use super::ValueAndLocation; + pub(crate) fn check_argument_count( expected: usize, - arguments: &[(Value, Location)], + arguments: &[ValueAndLocation], location: Location, ) -> IResult<()> { if arguments.len() == expected { @@ -30,18 +32,18 @@ pub(crate) fn check_argument_count( } pub(crate) fn check_one_argument( - mut arguments: Vec<(Value, Location)>, + mut arguments: Vec, location: Location, -) -> IResult<(Value, Location)> { +) -> IResult { check_argument_count(1, &arguments, location)?; Ok(arguments.pop().unwrap()) } pub(crate) fn check_two_arguments( - mut arguments: Vec<(Value, Location)>, + mut arguments: Vec, location: Location, -) -> IResult<((Value, Location), (Value, Location))> { +) -> IResult<(ValueAndLocation, ValueAndLocation)> { check_argument_count(2, &arguments, location)?; let argument2 = arguments.pop().unwrap(); @@ -51,9 +53,9 @@ pub(crate) fn check_two_arguments( } pub(crate) fn check_three_arguments( - mut arguments: Vec<(Value, Location)>, + mut arguments: Vec, location: Location, -) -> IResult<((Value, Location), (Value, Location), (Value, Location))> { +) -> IResult<(ValueAndLocation, ValueAndLocation, ValueAndLocation)> { check_argument_count(3, &arguments, location)?; let argument3 = arguments.pop().unwrap(); @@ -65,7 +67,7 @@ pub(crate) fn check_three_arguments( pub(crate) fn get_array( interner: &NodeInterner, - (value, location): (Value, Location), + (value, location): ValueAndLocation, ) -> IResult<(im::Vector, Type)> { match value { Value::Array(values, typ) => Ok((values, typ)), @@ -80,7 +82,7 @@ pub(crate) fn get_array( pub(crate) fn get_slice( interner: &NodeInterner, - (value, location): (Value, Location), + (value, location): ValueAndLocation, ) -> IResult<(im::Vector, Type)> { match value { Value::Slice(values, typ) => Ok((values, typ)), @@ -95,7 +97,7 @@ pub(crate) fn get_slice( pub(crate) fn get_tuple( interner: &NodeInterner, - (value, location): (Value, Location), + (value, location): ValueAndLocation, ) -> IResult> { match value { Value::Tuple(values) => Ok(values), @@ -108,7 +110,7 @@ pub(crate) fn get_tuple( } } -pub(crate) fn get_field((value, location): (Value, Location)) -> IResult { +pub(crate) fn get_field((value, location): ValueAndLocation) -> IResult { match value { Value::Field(value) => Ok(value), value => { @@ -118,7 +120,7 @@ pub(crate) fn get_field((value, location): (Value, Location)) -> IResult IResult { +pub(crate) fn get_u32((value, location): ValueAndLocation) -> IResult { match value { Value::U32(value) => Ok(value), value => { @@ -129,7 +131,7 @@ pub(crate) fn get_u32((value, location): (Value, Location)) -> IResult { } } -pub(crate) fn get_function_def((value, location): (Value, Location)) -> IResult { +pub(crate) fn get_function_def((value, location): ValueAndLocation) -> IResult { match value { Value::FunctionDefinition(id) => Ok(id), value => { @@ -140,7 +142,7 @@ pub(crate) fn get_function_def((value, location): (Value, Location)) -> IResult< } } -pub(crate) fn get_module((value, location): (Value, Location)) -> IResult { +pub(crate) fn get_module((value, location): ValueAndLocation) -> IResult { match value { Value::ModuleDefinition(module_id) => Ok(module_id), value => { @@ -151,7 +153,7 @@ pub(crate) fn get_module((value, location): (Value, Location)) -> IResult IResult { +pub(crate) fn get_struct((value, location): ValueAndLocation) -> IResult { match value { Value::StructDefinition(id) => Ok(id), _ => { @@ -163,7 +165,7 @@ pub(crate) fn get_struct((value, location): (Value, Location)) -> IResult IResult<(TraitId, Vec)> { match value { Value::TraitConstraint(trait_id, generics) => Ok((trait_id, generics)), @@ -175,7 +177,7 @@ pub(crate) fn get_trait_constraint( } } -pub(crate) fn get_trait_def((value, location): (Value, Location)) -> IResult { +pub(crate) fn get_trait_def((value, location): ValueAndLocation) -> IResult { match value { Value::TraitDefinition(id) => Ok(id), value => { @@ -186,7 +188,7 @@ pub(crate) fn get_trait_def((value, location): (Value, Location)) -> IResult IResult { +pub(crate) fn get_type((value, location): ValueAndLocation) -> IResult { match value { Value::Type(typ) => Ok(typ), value => { @@ -197,7 +199,7 @@ pub(crate) fn get_type((value, location): (Value, Location)) -> IResult { } } -pub(crate) fn get_quoted((value, location): (Value, Location)) -> IResult>> { +pub(crate) fn get_quoted((value, location): ValueAndLocation) -> IResult>> { match value { Value::Quoted(tokens) => Ok(tokens), value => { From a5380b41b2d921dde2e68adc3d5c6c61a3afc64f Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 15:56:01 -0300 Subject: [PATCH 16/22] clippy --- .../noirc_frontend/src/hir/comptime/interpreter/builtin.rs | 6 +++--- .../src/hir/comptime/interpreter/builtin/builtin_helpers.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index f523e6ff67f..df0438ee39c 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -775,7 +775,7 @@ fn function_def_set_parameters( parameter_types.push(parameter_type); } - mutate_func_meta_type(&mut interpreter.elaborator.interner, func_id, |func_meta| { + mutate_func_meta_type(interpreter.elaborator.interner, func_id, |func_meta| { func_meta.parameters = parameters.into(); func_meta.parameter_idents = parameter_idents; replace_func_meta_parameters(&mut func_meta.typ, parameter_types); @@ -798,7 +798,7 @@ fn function_def_set_return_type( let quoted_type_id = interpreter.elaborator.interner.push_quoted_type(return_type.clone()); - mutate_func_meta_type(&mut interpreter.elaborator.interner, func_id, |func_meta| { + mutate_func_meta_type(interpreter.elaborator.interner, func_id, |func_meta| { func_meta.return_type = FunctionReturnType::Ty(UnresolvedType { typ: UnresolvedTypeData::Resolved(quoted_type_id), span: Some(location.span), @@ -984,7 +984,7 @@ fn check_function_not_yet_resolved( match func_meta.function_body { FunctionBody::Unresolved(_, _, _) => Ok(()), FunctionBody::Resolving | FunctionBody::Resolved => { - return Err(InterpreterError::FunctionAlreadyResolved { location }) + Err(InterpreterError::FunctionAlreadyResolved { location }) } } } 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 45da0f3ffa1..fcb55e980f6 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 @@ -159,7 +159,7 @@ pub(crate) fn get_struct((value, location): ValueAndLocation) -> IResult { let expected = Type::Quoted(QuotedType::StructDefinition); let actual = value.get_type().into_owned(); - return Err(InterpreterError::TypeMismatch { expected, location, actual }); + Err(InterpreterError::TypeMismatch { expected, location, actual }) } } } From e93ae0f5697bb3ebb149712205e9d047ab040b20 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 15:58:25 -0300 Subject: [PATCH 17/22] Move ValueAndLocation somewhere else --- .../noirc_frontend/src/hir/comptime/interpreter.rs | 14 ++++++++------ .../src/hir/comptime/interpreter/builtin.rs | 4 +--- .../src/hir/comptime/interpreter/foreign.rs | 9 ++++++--- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index 72b92e288c7..f675e2c1f42 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -44,6 +44,8 @@ mod builtin; mod foreign; mod unquote; +pub(crate) type ValueAndLocation = (Value, Location); + #[allow(unused)] pub struct Interpreter<'local, 'interner> { /// To expand macros the Interpreter needs access to the Elaborator @@ -76,7 +78,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { pub(crate) fn call_function( &mut self, function: FuncId, - arguments: Vec<(Value, Location)>, + arguments: Vec, mut instantiation_bindings: TypeBindings, location: Location, ) -> IResult { @@ -110,7 +112,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { fn call_function_inner( &mut self, function: FuncId, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let meta = self.elaborator.interner.function_meta(&function); @@ -139,7 +141,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { fn call_user_defined_function( &mut self, function: FuncId, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let meta = self.elaborator.interner.function_meta(&function); @@ -193,7 +195,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { fn call_special( &mut self, function: FuncId, - arguments: Vec<(Value, Location)>, + arguments: Vec, return_type: Type, location: Location, ) -> IResult { @@ -227,7 +229,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { &mut self, closure: HirLambda, environment: Vec, - arguments: Vec<(Value, Location)>, + arguments: Vec, call_location: Location, ) -> IResult { let previous_state = self.enter_function(); @@ -1641,7 +1643,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { self.evaluate_statement(statement) } - fn print_oracle(&self, arguments: Vec<(Value, Location)>) -> Result { + fn print_oracle(&self, arguments: Vec) -> Result { assert_eq!(arguments.len(), 2); let print_newline = arguments[0].0 == Value::Bool(true); diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index df0438ee39c..995f6976783 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -27,12 +27,10 @@ use crate::{ QuotedType, Shared, Type, }; -use super::Interpreter; +use super::{Interpreter, ValueAndLocation}; pub(crate) mod builtin_helpers; -pub(crate) type ValueAndLocation = (Value, Location); - impl<'local, 'context> Interpreter<'local, 'context> { pub(super) fn call_builtin( &mut self, diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs index f7caf84ec42..1ab02c8aee9 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs @@ -8,12 +8,15 @@ use crate::{ macros_api::NodeInterner, }; -use super::builtin::builtin_helpers::{check_two_arguments, get_array, get_field, get_u32}; +use super::{ + builtin::builtin_helpers::{check_two_arguments, get_array, get_field, get_u32}, + ValueAndLocation, +}; pub(super) fn call_foreign( interner: &mut NodeInterner, name: &str, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { match name { @@ -28,7 +31,7 @@ pub(super) fn call_foreign( // poseidon2_permutation(_input: [Field; N], _state_length: u32) -> [Field; N] fn poseidon2_permutation( interner: &mut NodeInterner, - arguments: Vec<(Value, Location)>, + arguments: Vec, location: Location, ) -> IResult { let (input, state_length) = check_two_arguments(arguments, location)?; From e8a45ac9aac4ca7e7a56edcd2d2f73b85b703938 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 6 Aug 2024 15:58:47 -0300 Subject: [PATCH 18/22] Remove unused function --- tooling/nargo_fmt/src/items.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tooling/nargo_fmt/src/items.rs b/tooling/nargo_fmt/src/items.rs index 80b641fd830..57757982e83 100644 --- a/tooling/nargo_fmt/src/items.rs +++ b/tooling/nargo_fmt/src/items.rs @@ -111,8 +111,4 @@ pub(crate) trait HasItem { fn start(&self) -> u32 { self.span().start() } - - fn end(&self) -> u32 { - self.span().end() - } } From dc7c7056643706328fc27b99bea543b8bb680692 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Thu, 8 Aug 2024 14:42:29 -0300 Subject: [PATCH 19/22] Move helper to separate file --- .../src/hir/comptime/interpreter/builtin.rs | 21 ++++--------------- .../interpreter/builtin/builtin_helpers.rs | 18 ++++++++++++++-- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 182398735cf..4309ea9d02b 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -5,9 +5,10 @@ use std::{ use acvm::{AcirField, FieldElement}; use builtin_helpers::{ - check_argument_count, check_one_argument, check_three_arguments, check_two_arguments, - get_function_def, get_module, get_quoted, get_slice, get_struct, get_trait_constraint, - get_trait_def, get_tuple, get_type, get_u32, hir_pattern_to_tokens, + check_argument_count, check_function_not_yet_resolved, check_one_argument, + check_three_arguments, check_two_arguments, get_function_def, get_module, get_quoted, + get_slice, get_struct, get_trait_constraint, get_trait_def, get_tuple, get_type, get_u32, + hir_pattern_to_tokens, }; use iter_extended::{try_vecmap, vecmap}; use noirc_errors::Location; @@ -988,20 +989,6 @@ pub(crate) fn extract_option_generic_type(typ: Type) -> Type { generics.pop().expect("Expected Option to have a T generic type") } -fn check_function_not_yet_resolved( - interpreter: &Interpreter, - func_id: FuncId, - location: Location, -) -> Result<(), InterpreterError> { - let func_meta = interpreter.elaborator.interner.function_meta(&func_id); - match func_meta.function_body { - FunctionBody::Unresolved(_, _, _) => Ok(()), - FunctionBody::Resolving | FunctionBody::Resolved => { - Err(InterpreterError::FunctionAlreadyResolved { location }) - } - } -} - fn parse( (value, location): ValueAndLocation, parser: impl NoirParser, 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 8a8b481a6d2..147ee2b76d1 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 @@ -6,10 +6,10 @@ use noirc_errors::Location; use crate::{ ast::{IntegerBitSize, Signedness}, hir::{ - comptime::{errors::IResult, InterpreterError, Value}, + comptime::{errors::IResult, Interpreter, InterpreterError, Value}, def_map::ModuleId, }, - hir_def::stmt::HirPattern, + hir_def::{function::FunctionBody, stmt::HirPattern}, macros_api::{NodeInterner, StructId}, node_interner::{FuncId, TraitId}, token::Token, @@ -290,3 +290,17 @@ fn gather_hir_pattern_tokens( } } } + +pub(super) fn check_function_not_yet_resolved( + interpreter: &Interpreter, + func_id: FuncId, + location: Location, +) -> Result<(), InterpreterError> { + let func_meta = interpreter.elaborator.interner.function_meta(&func_id); + match func_meta.function_body { + FunctionBody::Unresolved(_, _, _) => Ok(()), + FunctionBody::Resolving | FunctionBody::Resolved => { + Err(InterpreterError::FunctionAlreadyResolved { location }) + } + } +} From bae2ef5cf4cf3481028c53b145d2c5eb3df91604 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Thu, 8 Aug 2024 14:43:37 -0300 Subject: [PATCH 20/22] Remove `ValueAndLocation` --- .../src/hir/comptime/interpreter.rs | 14 ++- .../src/hir/comptime/interpreter/builtin.rs | 96 +++++++++---------- .../interpreter/builtin/builtin_helpers.rs | 42 ++++---- .../src/hir/comptime/interpreter/foreign.rs | 9 +- 4 files changed, 77 insertions(+), 84 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index f675e2c1f42..72b92e288c7 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -44,8 +44,6 @@ mod builtin; mod foreign; mod unquote; -pub(crate) type ValueAndLocation = (Value, Location); - #[allow(unused)] pub struct Interpreter<'local, 'interner> { /// To expand macros the Interpreter needs access to the Elaborator @@ -78,7 +76,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { pub(crate) fn call_function( &mut self, function: FuncId, - arguments: Vec, + arguments: Vec<(Value, Location)>, mut instantiation_bindings: TypeBindings, location: Location, ) -> IResult { @@ -112,7 +110,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { fn call_function_inner( &mut self, function: FuncId, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let meta = self.elaborator.interner.function_meta(&function); @@ -141,7 +139,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { fn call_user_defined_function( &mut self, function: FuncId, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let meta = self.elaborator.interner.function_meta(&function); @@ -195,7 +193,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { fn call_special( &mut self, function: FuncId, - arguments: Vec, + arguments: Vec<(Value, Location)>, return_type: Type, location: Location, ) -> IResult { @@ -229,7 +227,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { &mut self, closure: HirLambda, environment: Vec, - arguments: Vec, + arguments: Vec<(Value, Location)>, call_location: Location, ) -> IResult { let previous_state = self.enter_function(); @@ -1643,7 +1641,7 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { self.evaluate_statement(statement) } - fn print_oracle(&self, arguments: Vec) -> Result { + fn print_oracle(&self, arguments: Vec<(Value, Location)>) -> Result { assert_eq!(arguments.len(), 2); let print_newline = arguments[0].0 == Value::Bool(true); diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 4309ea9d02b..6274570c160 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -29,7 +29,7 @@ use crate::{ }; use self::builtin_helpers::{get_array, get_u8}; -use super::{Interpreter, ValueAndLocation}; +use super::Interpreter; pub(crate) mod builtin_helpers; @@ -37,7 +37,7 @@ impl<'local, 'context> Interpreter<'local, 'context> { pub(super) fn call_builtin( &mut self, name: &str, - arguments: Vec, + arguments: Vec<(Value, Location)>, return_type: Type, location: Location, ) -> IResult { @@ -108,7 +108,7 @@ fn failing_constraint(message: impl Into, location: Location) -> IRes fn array_len( interner: &NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let (argument, argument_location) = check_one_argument(arguments, location)?; @@ -139,7 +139,7 @@ fn array_as_str_unchecked( fn as_slice( interner: &NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let (array, array_location) = check_one_argument(arguments, location)?; @@ -157,7 +157,7 @@ fn as_slice( fn slice_push_back( interner: &NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let (slice, (element, _)) = check_two_arguments(arguments, location)?; @@ -170,7 +170,7 @@ fn slice_push_back( /// fn as_type(self) -> Type fn struct_def_as_type( interner: &NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -189,7 +189,7 @@ fn struct_def_as_type( /// fn generics(self) -> [Type] fn struct_def_generics( interner: &NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -208,7 +208,7 @@ fn struct_def_generics( /// Returns (name, type) pairs of each field of this StructDefinition fn struct_def_fields( interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -233,7 +233,7 @@ fn struct_def_fields( fn slice_remove( interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let (slice, index) = check_two_arguments(arguments, location)?; @@ -259,7 +259,7 @@ fn slice_remove( fn slice_push_front( interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let (slice, (element, _)) = check_two_arguments(arguments, location)?; @@ -271,7 +271,7 @@ fn slice_push_front( fn slice_pop_front( interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -285,7 +285,7 @@ fn slice_pop_front( fn slice_pop_back( interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -299,7 +299,7 @@ fn slice_pop_back( fn slice_insert( interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let (slice, index, (element, _)) = check_three_arguments(arguments, location)?; @@ -313,7 +313,7 @@ fn slice_insert( // fn as_module(quoted: Quoted) -> Option fn quoted_as_module( interpreter: &mut Interpreter, - arguments: Vec, + arguments: Vec<(Value, Location)>, return_type: Type, location: Location, ) -> IResult { @@ -333,7 +333,7 @@ fn quoted_as_module( // fn as_trait_constraint(quoted: Quoted) -> TraitConstraint fn quoted_as_trait_constraint( interpreter: &mut Interpreter, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -349,7 +349,7 @@ fn quoted_as_trait_constraint( // fn as_type(quoted: Quoted) -> Type fn quoted_as_type( interpreter: &mut Interpreter, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -361,7 +361,7 @@ fn quoted_as_type( // fn as_array(self) -> Option<(Type, Type)> fn type_as_array( - arguments: Vec, + arguments: Vec<(Value, Location)>, return_type: Type, location: Location, ) -> IResult { @@ -376,7 +376,7 @@ fn type_as_array( // fn as_constant(self) -> Option fn type_as_constant( - arguments: Vec, + arguments: Vec<(Value, Location)>, return_type: Type, location: Location, ) -> IResult { @@ -391,7 +391,7 @@ fn type_as_constant( // fn as_integer(self) -> Option<(bool, u8)> fn type_as_integer( - arguments: Vec, + arguments: Vec<(Value, Location)>, return_type: Type, location: Location, ) -> IResult { @@ -406,7 +406,7 @@ fn type_as_integer( // fn as_slice(self) -> Option fn type_as_slice( - arguments: Vec, + arguments: Vec<(Value, Location)>, return_type: Type, location: Location, ) -> IResult { @@ -421,7 +421,7 @@ fn type_as_slice( // fn as_struct(self) -> Option<(StructDefinition, [Type])> fn type_as_struct( - arguments: Vec, + arguments: Vec<(Value, Location)>, return_type: Type, location: Location, ) -> IResult { @@ -442,7 +442,7 @@ fn type_as_struct( // fn as_tuple(self) -> Option<[Type]> fn type_as_tuple( - arguments: Vec, + arguments: Vec<(Value, Location)>, return_type: Type, location: Location, ) -> IResult { @@ -463,7 +463,7 @@ fn type_as_tuple( // Helper function for implementing the `type_as_...` functions. fn type_as( - arguments: Vec, + arguments: Vec<(Value, Location)>, return_type: Type, location: Location, f: F, @@ -480,7 +480,7 @@ where } // fn type_eq(_first: Type, _second: Type) -> bool -fn type_eq(arguments: Vec, location: Location) -> IResult { +fn type_eq(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let (self_type, other_type) = check_two_arguments(arguments, location)?; let self_type = get_type(self_type)?; @@ -490,7 +490,7 @@ fn type_eq(arguments: Vec, location: Location) -> IResult bool -fn type_is_bool(arguments: Vec, location: Location) -> IResult { +fn type_is_bool(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let value = check_one_argument(arguments, location)?; let typ = get_type(value)?; @@ -498,7 +498,7 @@ fn type_is_bool(arguments: Vec, location: Location) -> IResult } // fn is_field(self) -> bool -fn type_is_field(arguments: Vec, location: Location) -> IResult { +fn type_is_field(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let value = check_one_argument(arguments, location)?; let typ = get_type(value)?; @@ -506,7 +506,7 @@ fn type_is_field(arguments: Vec, location: Location) -> IResul } // fn type_of(x: T) -> Type -fn type_of(arguments: Vec, location: Location) -> IResult { +fn type_of(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let (value, _) = check_one_argument(arguments, location)?; let typ = value.get_type().into_owned(); Ok(Value::Type(typ)) @@ -515,7 +515,7 @@ fn type_of(arguments: Vec, location: Location) -> IResult Field fn trait_constraint_hash( _interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -532,7 +532,7 @@ fn trait_constraint_hash( // fn constraint_eq(constraint_a: TraitConstraint, constraint_b: TraitConstraint) -> bool fn trait_constraint_eq( _interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let (value_a, value_b) = check_two_arguments(arguments, location)?; @@ -546,7 +546,7 @@ fn trait_constraint_eq( // fn trait_def_hash(def: TraitDefinition) -> Field fn trait_def_hash( _interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let argument = check_one_argument(arguments, location)?; @@ -563,7 +563,7 @@ fn trait_def_hash( // fn trait_def_eq(def_a: TraitDefinition, def_b: TraitDefinition) -> bool fn trait_def_eq( _interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let (id_a, id_b) = check_two_arguments(arguments, location)?; @@ -658,7 +658,7 @@ fn zeroed(return_type: Type) -> IResult { // fn name(self) -> Quoted fn function_def_name( interner: &NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let self_argument = check_one_argument(arguments, location)?; @@ -671,7 +671,7 @@ fn function_def_name( // fn parameters(self) -> [(Quoted, Type)] fn function_def_parameters( interner: &NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let self_argument = check_one_argument(arguments, location)?; @@ -699,7 +699,7 @@ fn function_def_parameters( // fn return_type(self) -> Type fn function_def_return_type( interner: &NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let self_argument = check_one_argument(arguments, location)?; @@ -712,7 +712,7 @@ fn function_def_return_type( // fn set_body(self, body: Quoted) fn function_def_set_body( interpreter: &mut Interpreter, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let (self_argument, body_argument) = check_two_arguments(arguments, location)?; @@ -746,7 +746,7 @@ fn function_def_set_body( // fn set_parameters(self, parameters: [(Quoted, Type)]) fn function_def_set_parameters( interpreter: &mut Interpreter, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let (self_argument, parameters_argument) = check_two_arguments(arguments, location)?; @@ -801,7 +801,7 @@ fn function_def_set_parameters( // fn set_return_type(self, return_type: Type) fn function_def_set_return_type( interpreter: &mut Interpreter, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let (self_argument, return_type_argument) = check_two_arguments(arguments, location)?; @@ -826,7 +826,7 @@ fn function_def_set_return_type( // fn functions(self) -> [FunctionDefinition] fn module_functions( interpreter: &Interpreter, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let self_argument = check_one_argument(arguments, location)?; @@ -850,7 +850,7 @@ fn module_functions( // fn is_contract(self) -> bool fn module_is_contract( interpreter: &Interpreter, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let self_argument = check_one_argument(arguments, location)?; @@ -861,7 +861,7 @@ fn module_is_contract( // fn name(self) -> Quoted fn module_name( interner: &NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let self_argument = check_one_argument(arguments, location)?; @@ -873,7 +873,7 @@ fn module_name( fn modulus_be_bits( _interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { check_argument_count(0, &arguments, location)?; @@ -888,7 +888,7 @@ fn modulus_be_bits( fn modulus_be_bytes( _interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { check_argument_count(0, &arguments, location)?; @@ -903,7 +903,7 @@ fn modulus_be_bytes( fn modulus_le_bits( interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let Value::Slice(bits, typ) = modulus_be_bits(interner, arguments, location)? else { @@ -915,7 +915,7 @@ fn modulus_le_bits( fn modulus_le_bytes( interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let Value::Slice(bytes, typ) = modulus_be_bytes(interner, arguments, location)? else { @@ -927,7 +927,7 @@ fn modulus_le_bytes( fn modulus_num_bits( _interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { check_argument_count(0, &arguments, location)?; @@ -936,7 +936,7 @@ fn modulus_num_bits( } // fn quoted_eq(_first: Quoted, _second: Quoted) -> bool -fn quoted_eq(arguments: Vec, location: Location) -> IResult { +fn quoted_eq(arguments: Vec<(Value, Location)>, location: Location) -> IResult { let (self_value, other_value) = check_two_arguments(arguments, location)?; let self_quoted = get_quoted(self_value)?; @@ -947,7 +947,7 @@ fn quoted_eq(arguments: Vec, location: Location) -> IResult, + arguments: Vec<(Value, Location)>, location: Location, ) -> Result { let argument = check_one_argument(arguments, location)?; @@ -990,7 +990,7 @@ pub(crate) fn extract_option_generic_type(typ: Type) -> Type { } fn parse( - (value, location): ValueAndLocation, + (value, location): (Value, Location), parser: impl NoirParser, rule: &'static str, ) -> IResult { 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 147ee2b76d1..58098fb6403 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 @@ -16,11 +16,9 @@ use crate::{ QuotedType, Type, }; -use super::ValueAndLocation; - pub(crate) fn check_argument_count( expected: usize, - arguments: &[ValueAndLocation], + arguments: &[(Value, Location)], location: Location, ) -> IResult<()> { if arguments.len() == expected { @@ -32,18 +30,18 @@ pub(crate) fn check_argument_count( } pub(crate) fn check_one_argument( - mut arguments: Vec, + mut arguments: Vec<(Value, Location)>, location: Location, -) -> IResult { +) -> IResult<(Value, Location)> { check_argument_count(1, &arguments, location)?; Ok(arguments.pop().unwrap()) } pub(crate) fn check_two_arguments( - mut arguments: Vec, + mut arguments: Vec<(Value, Location)>, location: Location, -) -> IResult<(ValueAndLocation, ValueAndLocation)> { +) -> IResult<((Value, Location), (Value, Location))> { check_argument_count(2, &arguments, location)?; let argument2 = arguments.pop().unwrap(); @@ -53,9 +51,9 @@ pub(crate) fn check_two_arguments( } pub(crate) fn check_three_arguments( - mut arguments: Vec, + mut arguments: Vec<(Value, Location)>, location: Location, -) -> IResult<(ValueAndLocation, ValueAndLocation, ValueAndLocation)> { +) -> IResult<((Value, Location), (Value, Location), (Value, Location))> { check_argument_count(3, &arguments, location)?; let argument3 = arguments.pop().unwrap(); @@ -67,7 +65,7 @@ pub(crate) fn check_three_arguments( pub(crate) fn get_array( interner: &NodeInterner, - (value, location): ValueAndLocation, + (value, location): (Value, Location), ) -> IResult<(im::Vector, Type)> { match value { Value::Array(values, typ) => Ok((values, typ)), @@ -82,7 +80,7 @@ pub(crate) fn get_array( pub(crate) fn get_slice( interner: &NodeInterner, - (value, location): ValueAndLocation, + (value, location): (Value, Location), ) -> IResult<(im::Vector, Type)> { match value { Value::Slice(values, typ) => Ok((values, typ)), @@ -97,7 +95,7 @@ pub(crate) fn get_slice( pub(crate) fn get_tuple( interner: &NodeInterner, - (value, location): ValueAndLocation, + (value, location): (Value, Location), ) -> IResult> { match value { Value::Tuple(values) => Ok(values), @@ -110,7 +108,7 @@ pub(crate) fn get_tuple( } } -pub(crate) fn get_field((value, location): ValueAndLocation) -> IResult { +pub(crate) fn get_field((value, location): (Value, Location)) -> IResult { match value { Value::Field(value) => Ok(value), value => { @@ -120,7 +118,7 @@ pub(crate) fn get_field((value, location): ValueAndLocation) -> IResult IResult { +pub(crate) fn get_u8((value, location): (Value, Location)) -> IResult { match value { Value::U8(value) => Ok(value), value => { @@ -131,7 +129,7 @@ pub(crate) fn get_u8((value, location): ValueAndLocation) -> IResult { } } -pub(crate) fn get_u32((value, location): ValueAndLocation) -> IResult { +pub(crate) fn get_u32((value, location): (Value, Location)) -> IResult { match value { Value::U32(value) => Ok(value), value => { @@ -142,7 +140,7 @@ pub(crate) fn get_u32((value, location): ValueAndLocation) -> IResult { } } -pub(crate) fn get_function_def((value, location): ValueAndLocation) -> IResult { +pub(crate) fn get_function_def((value, location): (Value, Location)) -> IResult { match value { Value::FunctionDefinition(id) => Ok(id), value => { @@ -153,7 +151,7 @@ pub(crate) fn get_function_def((value, location): ValueAndLocation) -> IResult IResult { +pub(crate) fn get_module((value, location): (Value, Location)) -> IResult { match value { Value::ModuleDefinition(module_id) => Ok(module_id), value => { @@ -164,7 +162,7 @@ pub(crate) fn get_module((value, location): ValueAndLocation) -> IResult IResult { +pub(crate) fn get_struct((value, location): (Value, Location)) -> IResult { match value { Value::StructDefinition(id) => Ok(id), _ => { @@ -176,7 +174,7 @@ pub(crate) fn get_struct((value, location): ValueAndLocation) -> IResult IResult<(TraitId, Vec)> { match value { Value::TraitConstraint(trait_id, generics) => Ok((trait_id, generics)), @@ -188,7 +186,7 @@ pub(crate) fn get_trait_constraint( } } -pub(crate) fn get_trait_def((value, location): ValueAndLocation) -> IResult { +pub(crate) fn get_trait_def((value, location): (Value, Location)) -> IResult { match value { Value::TraitDefinition(id) => Ok(id), value => { @@ -199,7 +197,7 @@ pub(crate) fn get_trait_def((value, location): ValueAndLocation) -> IResult IResult { +pub(crate) fn get_type((value, location): (Value, Location)) -> IResult { match value { Value::Type(typ) => Ok(typ), value => { @@ -210,7 +208,7 @@ pub(crate) fn get_type((value, location): ValueAndLocation) -> IResult { } } -pub(crate) fn get_quoted((value, location): ValueAndLocation) -> IResult>> { +pub(crate) fn get_quoted((value, location): (Value, Location)) -> IResult>> { match value { Value::Quoted(tokens) => Ok(tokens), value => { diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs index 1ab02c8aee9..f7caf84ec42 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs @@ -8,15 +8,12 @@ use crate::{ macros_api::NodeInterner, }; -use super::{ - builtin::builtin_helpers::{check_two_arguments, get_array, get_field, get_u32}, - ValueAndLocation, -}; +use super::builtin::builtin_helpers::{check_two_arguments, get_array, get_field, get_u32}; pub(super) fn call_foreign( interner: &mut NodeInterner, name: &str, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { match name { @@ -31,7 +28,7 @@ pub(super) fn call_foreign( // poseidon2_permutation(_input: [Field; N], _state_length: u32) -> [Field; N] fn poseidon2_permutation( interner: &mut NodeInterner, - arguments: Vec, + arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { let (input, state_length) = check_two_arguments(arguments, location)?; From 2691ef1690a3e6c9c43096a405ce57ffbd3dc494 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Thu, 8 Aug 2024 14:50:28 -0300 Subject: [PATCH 21/22] clippy --- .../src/hir/comptime/interpreter/builtin/builtin_helpers.rs | 1 + 1 file changed, 1 insertion(+) 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 58098fb6403..f4c51333ddc 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 @@ -50,6 +50,7 @@ pub(crate) fn check_two_arguments( Ok((argument1, argument2)) } +#[allow(clippy::type_complexity)] pub(crate) fn check_three_arguments( mut arguments: Vec<(Value, Location)>, location: Location, From 8814ec7f8e9dd083bf736366cd73d8af8e5aaa3b Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Thu, 8 Aug 2024 15:31:36 -0300 Subject: [PATCH 22/22] Move more helper functions --- .../src/hir/comptime/interpreter/builtin.rs | 67 ++----------------- .../interpreter/builtin/builtin_helpers.rs | 66 +++++++++++++++++- 2 files changed, 69 insertions(+), 64 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 6274570c160..1eb5f211cce 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -8,7 +8,8 @@ use builtin_helpers::{ check_argument_count, check_function_not_yet_resolved, check_one_argument, check_three_arguments, check_two_arguments, get_function_def, get_module, get_quoted, get_slice, get_struct, get_trait_constraint, get_trait_def, get_tuple, get_type, get_u32, - hir_pattern_to_tokens, + hir_pattern_to_tokens, mutate_func_meta_type, parse, parse_tokens, + replace_func_meta_parameters, replace_func_meta_return_type, }; use iter_extended::{try_vecmap, vecmap}; use noirc_errors::Location; @@ -20,11 +21,11 @@ use crate::{ Visibility, }, hir::comptime::{errors::IResult, value::add_token_spans, InterpreterError, Value}, - hir_def::function::{FuncMeta, FunctionBody}, + hir_def::function::FunctionBody, macros_api::{ModuleDefId, NodeInterner, Signedness}, - node_interner::{DefinitionKind, FuncId}, - parser::{self, NoirParser}, - token::{SpannedToken, Token, Tokens}, + node_interner::DefinitionKind, + parser::{self}, + token::{SpannedToken, Token}, QuotedType, Shared, Type, }; @@ -988,59 +989,3 @@ pub(crate) fn extract_option_generic_type(typ: Type) -> Type { generics.pop().expect("Expected Option to have a T generic type") } - -fn parse( - (value, location): (Value, Location), - parser: impl NoirParser, - rule: &'static str, -) -> IResult { - let tokens = get_quoted((value, location))?; - let quoted = add_token_spans(tokens.clone(), location.span); - parse_tokens(tokens, quoted, location, parser, rule) -} - -fn parse_tokens( - tokens: Rc>, - quoted: Tokens, - location: Location, - parser: impl NoirParser, - rule: &'static str, -) -> IResult { - parser.parse(quoted).map_err(|mut errors| { - let error = errors.swap_remove(0); - InterpreterError::FailedToParseMacro { error, tokens, rule, file: location.file } - }) -} - -fn mutate_func_meta_type(interner: &mut NodeInterner, func_id: FuncId, f: F) -where - F: FnOnce(&mut FuncMeta), -{ - let (name_id, function_type) = { - let func_meta = interner.function_meta_mut(&func_id); - f(func_meta); - (func_meta.name.id, func_meta.typ.clone()) - }; - - interner.push_definition_type(name_id, function_type); -} - -fn replace_func_meta_parameters(typ: &mut Type, parameter_types: Vec) { - match typ { - Type::Function(parameters, _, _) => { - *parameters = parameter_types; - } - Type::Forall(_, typ) => replace_func_meta_parameters(typ, parameter_types), - _ => {} - } -} - -fn replace_func_meta_return_type(typ: &mut Type, return_type: Type) { - match typ { - Type::Function(_, ret, _) => { - *ret = Box::new(return_type); - } - Type::Forall(_, typ) => replace_func_meta_return_type(typ, return_type), - _ => {} - } -} 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 f4c51333ddc..fac2913ff79 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 @@ -6,13 +6,17 @@ use noirc_errors::Location; use crate::{ ast::{IntegerBitSize, Signedness}, hir::{ - comptime::{errors::IResult, Interpreter, InterpreterError, Value}, + comptime::{errors::IResult, value::add_token_spans, Interpreter, InterpreterError, Value}, def_map::ModuleId, }, - hir_def::{function::FunctionBody, stmt::HirPattern}, + hir_def::{ + function::{FuncMeta, FunctionBody}, + stmt::HirPattern, + }, macros_api::{NodeInterner, StructId}, node_interner::{FuncId, TraitId}, - token::Token, + parser::NoirParser, + token::{Token, Tokens}, QuotedType, Type, }; @@ -303,3 +307,59 @@ pub(super) fn check_function_not_yet_resolved( } } } + +pub(super) fn parse( + (value, location): (Value, Location), + parser: impl NoirParser, + rule: &'static str, +) -> IResult { + let tokens = get_quoted((value, location))?; + let quoted = add_token_spans(tokens.clone(), location.span); + parse_tokens(tokens, quoted, location, parser, rule) +} + +pub(super) fn parse_tokens( + tokens: Rc>, + quoted: Tokens, + location: Location, + parser: impl NoirParser, + rule: &'static str, +) -> IResult { + parser.parse(quoted).map_err(|mut errors| { + let error = errors.swap_remove(0); + InterpreterError::FailedToParseMacro { error, tokens, rule, file: location.file } + }) +} + +pub(super) fn mutate_func_meta_type(interner: &mut NodeInterner, func_id: FuncId, f: F) +where + F: FnOnce(&mut FuncMeta), +{ + let (name_id, function_type) = { + let func_meta = interner.function_meta_mut(&func_id); + f(func_meta); + (func_meta.name.id, func_meta.typ.clone()) + }; + + interner.push_definition_type(name_id, function_type); +} + +pub(super) fn replace_func_meta_parameters(typ: &mut Type, parameter_types: Vec) { + match typ { + Type::Function(parameters, _, _) => { + *parameters = parameter_types; + } + Type::Forall(_, typ) => replace_func_meta_parameters(typ, parameter_types), + _ => {} + } +} + +pub(super) fn replace_func_meta_return_type(typ: &mut Type, return_type: Type) { + match typ { + Type::Function(_, ret, _) => { + *ret = Box::new(return_type); + } + Type::Forall(_, typ) => replace_func_meta_return_type(typ, return_type), + _ => {} + } +}