Skip to content

Commit

Permalink
Handle closures that are invalid for Aleo.
Browse files Browse the repository at this point in the history
In particular,

1. Insert a dummy instruction for empty closures.
SnarkVM won't parse closures with no instructions.

2. Give a parse error for Leo functions with
no parameters (rather than just generating
an invalid Aleo closure).

Fixes #28401
  • Loading branch information
mikebenfield committed Oct 23, 2024
1 parent a15db14 commit 5cadd8c
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 25 deletions.
6 changes: 5 additions & 1 deletion compiler/parser/src/parser/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,11 @@ impl<N: Network> ParserContext<'_, N> {
let name = self.expect_identifier()?;

// Parse parameters.
let (inputs, ..) = self.parse_paren_comma_list(|p| p.parse_input().map(Some))?;
let (inputs, _, span) = self.parse_paren_comma_list(|p| p.parse_input().map(Some))?;

if inputs.is_empty() && matches!(variant, Variant::Function) {
return Err(ParserError::empty_function_arglist(span).into());
}

// Parse return type.
let output = match self.eat(&Token::Arrow) {
Expand Down
6 changes: 6 additions & 0 deletions compiler/passes/src/code_generation/visit_program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,12 @@ impl<'a> CodeGenerator<'a> {

// Construct and append the function body.
let block_string = self.visit_block(&function.block);
if block_string.lines().all(|line| line.starts_with(" output ")) {
// There are no real instructions, which is invalid in Aleo, so
// add a dummy instruction.
function_string.push_str(" assert.eq true true;\n");
}

function_string.push_str(&block_string);

function_string
Expand Down
7 changes: 7 additions & 0 deletions errors/src/errors/parser/parser_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,4 +365,11 @@ create_messages!(
msg: format!("Digit {digit} invalid in radix {radix} (token {token})."),
help: None,
}

@formatted
empty_function_arglist {
args: (),
msg: format!("Cannot define a function with no parameters."),
help: None,
}
);
28 changes: 7 additions & 21 deletions tests/expectations/parser/functions/empty2.out
Original file line number Diff line number Diff line change
@@ -1,22 +1,8 @@
namespace = "Parse"
expectation = "Pass"

[[outputs]]

[outputs.imports]

[outputs.stubs]

[outputs.program_scopes.test]
program_id = '{"name":"test","network":"\"{\\\"id\\\":\\\"1\\\",\\\"name\\\":\\\"aleo\\\",\\\"span\\\":\\\"{\\\\\\\"lo\\\\\\\":0,\\\\\\\"hi\\\\\\\":0}\\\"}\""}'
consts = []
structs = []
mappings = []
functions = [[
"x",
{ annotations = [], variant = "Function", identifier = '{"id":"2","name":"x","span":"{\"lo\":39,\"hi\":40}"}', input = [], id = 5, output = [{ mode = "None", id = 3, type_ = { Integer = "U8" }, span = { lo = 46, hi = 48 } }], output_type = { Integer = "U8" }, block = { statements = [], id = 4, span = { lo = 49, hi = 51 } }, span = { lo = 30, hi = 51 } },
]]

[outputs.program_scopes.test.span]
lo = 2
hi = 52
expectation = "Fail"
outputs = ["""
Error [EPAR0370044]: Cannot define a function with no parameters.
--> test:4:15
|
4 | function x() -> u8 {}
| ^^"""]
2 changes: 1 addition & 1 deletion tests/tests/compiler/records/owner_wrong_ty.leo
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ program test.aleo {
owner: bool,
}

function main() -> bool {
function main(x: field) -> bool {
return true;
}
}
5 changes: 3 additions & 2 deletions tests/tests/parser/functions/empty2.leo
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/*
namespace = "Parse"
expectation = "Pass"
expectation = "Fail"
*/

program test.aleo {
function x() -> u8 {}}
function x() -> u8 {}
}

0 comments on commit 5cadd8c

Please sign in to comment.