diff --git a/compiler/src/errors/function.rs b/compiler/src/errors/function.rs index 8f22e1fb87..49dfae9467 100644 --- a/compiler/src/errors/function.rs +++ b/compiler/src/errors/function.rs @@ -82,12 +82,6 @@ impl FunctionError { FunctionError::Error(FormattedError::new_from_span(message, span)) } - pub fn arguments_length(expected: usize, actual: usize, span: Span) -> Self { - let message = format!("function expected {} input variables, found {}", expected, actual); - - Self::new_from_span(message, span) - } - pub fn invalid_array(actual: String, span: Span) -> Self { let message = format!("Expected function input array, found `{}`", actual); diff --git a/compiler/src/function/function.rs b/compiler/src/function/function.rs index 270d824862..9a385452c2 100644 --- a/compiler/src/function/function.rs +++ b/compiler/src/function/function.rs @@ -23,22 +23,13 @@ use crate::{ GroupType, }; -use leo_ast::{Expression, Function, FunctionInput, Span, Type}; +use leo_ast::{Expression, Function, FunctionInput, Type}; use snarkos_models::{ curves::{Field, PrimeField}, gadgets::r1cs::ConstraintSystem, }; -pub fn check_arguments_length(expected: usize, actual: usize, span: &Span) -> Result<(), FunctionError> { - // Make sure we are given the correct number of arguments - if expected != actual { - Err(FunctionError::arguments_length(expected, actual, span.to_owned())) - } else { - Ok(()) - } -} - impl> ConstrainedProgram { pub(crate) fn enforce_function>( &mut self, @@ -51,9 +42,6 @@ impl> ConstrainedProgram { ) -> Result, FunctionError> { let function_name = new_scope(scope, function.get_name()); - // Make sure we are given the correct number of input variables - check_arguments_length(function.input.len(), input.len(), &function.span)?; - // Store input values as new variables in resolved program for (input_model, input_expression) in function.input.iter().zip(input.into_iter()) { let (name, value) = match input_model { diff --git a/symbol-table/src/types/functions/function.rs b/symbol-table/src/types/functions/function.rs index 0abdc87aa9..6d3d7700ba 100644 --- a/symbol-table/src/types/functions/function.rs +++ b/symbol-table/src/types/functions/function.rs @@ -119,6 +119,16 @@ impl FunctionType { Ok(()) } + + /// + /// Returns the number of input variables to the function. + /// The `self` and `mut self` keywords are not counted as input variables. + /// + pub fn num_inputs(&self) -> usize { + self.inputs + .iter() + .fold(0, |acc, function_input| acc + function_input.count()) + } } impl PartialEq for FunctionType { diff --git a/symbol-table/src/types/functions/function_input.rs b/symbol-table/src/types/functions/function_input.rs index ccbd0c5670..8819563112 100644 --- a/symbol-table/src/types/functions/function_input.rs +++ b/symbol-table/src/types/functions/function_input.rs @@ -64,6 +64,20 @@ impl FunctionInputType { } } + /// + /// Returns `1` if a variable must be provided in a call to the function. + /// Returns `0` if the function input is a `self` or `mut self` keyword which does not have to + /// provided in a call to the function. + /// + pub fn count(&self) -> usize { + match self { + FunctionInputType::InputKeyword(_) => 1, + FunctionInputType::SelfKeyword(_) => 0, + FunctionInputType::MutSelfKeyword(_) => 0, + FunctionInputType::Variable(_) => 1, + } + } + /// /// Return a new `FunctionInputType` from a given `FunctionInput`. /// diff --git a/type-inference/src/objects/frame.rs b/type-inference/src/objects/frame.rs index 72a4d57be8..f61a84550c 100644 --- a/type-inference/src/objects/frame.rs +++ b/type-inference/src/objects/frame.rs @@ -1097,8 +1097,8 @@ impl Frame { let function_type = self.parse_function_name(expression, span)?; // Check the length of arguments - if function_type.inputs.len() != inputs.len() { - return Err(FrameError::num_inputs(function_type.inputs.len(), inputs.len(), span)); + if function_type.num_inputs() != inputs.len() { + return Err(FrameError::num_inputs(function_type.num_inputs(), inputs.len(), span)); } // Assert function inputs are correct types.