Skip to content

Commit

Permalink
fix: error on missing function parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite committed Jan 7, 2025
1 parent 7cc8dbf commit 08e481d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
9 changes: 9 additions & 0 deletions compiler/noirc_frontend/src/parser/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ pub enum ParserErrorReason {
DeprecatedAttributeExpectsAStringArgument,
#[error("Unsafe block must start with a safety comment")]
MissingSafetyComment,
#[error("Missing parameters for function definition")]
MissingParametersForFunctionDefinition,
}

/// Represents a parsing error, or a parsing error in the making.
Expand Down Expand Up @@ -285,6 +287,13 @@ impl<'a> From<&'a ParserError> for Diagnostic {
"Unsafe block must start with a safety comment: //@safety".into(),
error.span,
),
ParserErrorReason::MissingParametersForFunctionDefinition => {
Diagnostic::simple_error(
"Missing parameters for function definition".into(),
"Add a parameter list: `()`".into(),
error.span,
)
}
other => Diagnostic::simple_error(format!("{other}"), String::new(), error.span),
},
None => {
Expand Down
31 changes: 27 additions & 4 deletions compiler/noirc_frontend/src/parser/parser/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@ impl<'a> Parser<'a> {
let generics = self.parse_generics();
let parameters = self.parse_function_parameters(allow_self);

let parameters = match parameters {
Some(parameters) => parameters,
None => {
self.push_error(
ParserErrorReason::MissingParametersForFunctionDefinition,
name.span(),
);
Vec::new()
}
};

let (return_type, return_visibility) = if self.eat(Token::Arrow) {
let visibility = self.parse_visibility();
(FunctionReturnType::Ty(self.parse_type_or_error()), visibility)
Expand Down Expand Up @@ -131,14 +142,14 @@ impl<'a> Parser<'a> {
/// FunctionParametersList = FunctionParameter ( ',' FunctionParameter )* ','?
///
/// FunctionParameter = Visibility PatternOrSelf ':' Type
fn parse_function_parameters(&mut self, allow_self: bool) -> Vec<Param> {
fn parse_function_parameters(&mut self, allow_self: bool) -> Option<Vec<Param>> {
if !self.eat_left_paren() {
return Vec::new();
return None;
}

self.parse_many("parameters", separated_by_comma_until_right_paren(), |parser| {
Some(self.parse_many("parameters", separated_by_comma_until_right_paren(), |parser| {
parser.parse_function_parameter(allow_self)
})
}))
}

fn parse_function_parameter(&mut self, allow_self: bool) -> Option<Param> {
Expand Down Expand Up @@ -490,4 +501,16 @@ mod tests {
assert!(noir_function.def.is_unconstrained);
assert_eq!(noir_function.def.visibility, ItemVisibility::Public);
}

#[test]
fn parse_function_without_parentheses() {
let src = "
fn foo {}
^^^
";
let (src, span) = get_source_with_error_span(src);
let (_, errors) = parse_program(&src);
let reason = get_single_error_reason(&errors, span);
assert!(matches!(reason, ParserErrorReason::MissingParametersForFunctionDefinition));
}
}

0 comments on commit 08e481d

Please sign in to comment.