Skip to content

Commit

Permalink
Merge pull request #28417 from ProvableHQ/empty-closure
Browse files Browse the repository at this point in the history
Handle closures that are invalid for Aleo.
  • Loading branch information
d0cd authored Oct 23, 2024
2 parents 0cda2c2 + 0a5a698 commit c505dda
Show file tree
Hide file tree
Showing 57 changed files with 145 additions and 93 deletions.
8 changes: 8 additions & 0 deletions compiler/passes/src/code_generation/visit_program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,14 @@ impl<'a> CodeGenerator<'a> {

// Construct and append the function body.
let block_string = self.visit_block(&function.block);
if matches!(self.variant.unwrap(), Variant::Function | Variant::AsyncFunction)
&& 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
9 changes: 4 additions & 5 deletions compiler/passes/src/type_checking/check_program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,11 +263,6 @@ impl<'a, N: Network> ProgramVisitor<'a> for TypeChecker<'a, N> {
self.check_function_signature(function);

if self.scope_state.variant == Some(Variant::AsyncFunction) {
// Async functions cannot have empty blocks
if function.block.statements.is_empty() {
self.emit_err(TypeCheckerError::finalize_block_must_not_be_empty(function.block.span));
}

// Initialize the list of input futures. Each one must be awaited before the end of the function.
self.await_checker.set_futures(
function
Expand All @@ -280,6 +275,10 @@ impl<'a, N: Network> ProgramVisitor<'a> for TypeChecker<'a, N> {
);
}

if function.variant == Variant::Function && function.input.is_empty() {
self.emit_err(TypeCheckerError::empty_function_arglist(function.span));
}

self.visit_block(&function.block);

// If the function has a return type, then check that it has a return.
Expand Down
2 changes: 1 addition & 1 deletion errors/src/errors/parser/parser_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ create_messages!(
}

/// For when the parser encountered a mix of commas and semi-colons in struct member variables.
// TODO unused
// TODO This error is unused. Remove it in a future version.
@formatted
mixed_commas_and_semicolons {
args: (),
Expand Down
8 changes: 8 additions & 0 deletions errors/src/errors/type_checker/type_checker_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ create_messages!(
help: None,
}

// TODO This error is unused. Remove it in a future version.
@formatted
finalize_block_must_not_be_empty {
args: (),
Expand Down Expand Up @@ -886,4 +887,11 @@ create_messages!(
msg: "A struct must have at least one member.".to_string(),
help: None,
}

@formatted
empty_function_arglist {
args: (),
msg: format!("Cannot define a function with no parameters."),
help: None,
}
);
16 changes: 16 additions & 0 deletions tests/expectations/compiler/finalize/empty_finalize.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace = "Compile"
expectation = "Pass"
outputs = [[{ compile = [{ initial_symbol_table = "1594125e96833cb52afcad4c876e44d61b2944a6c146e019b23fa0ad5d39db2a", type_checked_symbol_table = "95d8ce7541440d2568f633e1b7800d3d5d06e1147642eec802bfca4a9115e61c", unrolled_symbol_table = "95d8ce7541440d2568f633e1b7800d3d5d06e1147642eec802bfca4a9115e61c", initial_ast = "45d32cf0414a246717747dc917b07ffe55ff7587589d4c494479e18667e61a03", unrolled_ast = "45d32cf0414a246717747dc917b07ffe55ff7587589d4c494479e18667e61a03", ssa_ast = "eb6eff57864e407c245edbba3ab2949a2536643b3b864a8a42b65c348523a31f", flattened_ast = "6e8cc40e042029b3124b7b9a7e66905525207fb6cf0bfe5b71abfecbf10d7c72", destructured_ast = "22c2d4f79894ead71296929de2982b8289e2b43f7d83dc497a1be4532945ea17", inlined_ast = "e18c2f95e617c4c42c2359ea8a09924311f89c0c3a0bfa1e2ffe23c6ff933846", dce_ast = "e18c2f95e617c4c42c2359ea8a09924311f89c0c3a0bfa1e2ffe23c6ff933846", bytecode = """
program test.aleo;

function mint_public:
input r0 as address.public;
input r1 as u64.public;
async mint_public r0 r1 into r2;
output r2 as test.aleo/mint_public.future;

finalize mint_public:
input r0 as address.public;
input r1 as u64.public;
assert.eq true true;
""", errors = "", warnings = "" }] }]]
9 changes: 0 additions & 9 deletions tests/expectations/compiler/finalize/empty_finalize_fail.out

This file was deleted.

18 changes: 18 additions & 0 deletions tests/expectations/compiler/function/empty_arglist_fail.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace = "Compile"
expectation = "Fail"
outputs = ["""
Error [ETYC0372113]: Cannot define a function with no parameters.
--> compiler-test:4:5
|
4 | function x() -> u8 {
5 | return 0u8;
6 | }
| ^
Error [ETYC0372083]: A program must have at least one transition function.
--> compiler-test:1:1
|
1 |
2 |
3 | program test.aleo {
| ^^^^^^^^^^^^
"""]
15 changes: 15 additions & 0 deletions tests/expectations/compiler/function/empty_function.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace = "Compile"
expectation = "Pass"
outputs = [[{ compile = [{ initial_symbol_table = "4ccc1709fb6b2aad9ee9a247bb37098d9330087d64e14af2a5c064287f701105", type_checked_symbol_table = "979420a8fc4bfbc81aeabe709704af919277f62699a09b0858c37544622a725a", unrolled_symbol_table = "979420a8fc4bfbc81aeabe709704af919277f62699a09b0858c37544622a725a", initial_ast = "52950f91033f987381d1b9a5ff69b626a8911d003da7edb503e97bd6e6637d2c", unrolled_ast = "52950f91033f987381d1b9a5ff69b626a8911d003da7edb503e97bd6e6637d2c", ssa_ast = "5314cb0ebd490a53c7ded487668632260992a4f49a10f1e247980b5c6647ad22", flattened_ast = "85fd8c8ed0cae4cd4b711d8d909d5aec0a176028fa91452fae92fbe5f6091f63", destructured_ast = "fc6b028060914573cc2c1885155f4f2bb5c90ed03caf720bff4d5b05eb299327", inlined_ast = "6b8711898970669f70badb94f5ce2abd87be07fbb764523dd2d9e6d94336e7cd", dce_ast = "6b8711898970669f70badb94f5ce2abd87be07fbb764523dd2d9e6d94336e7cd", bytecode = """
program test.aleo;

closure x:
input r0 as boolean;
assert.eq true true;
output 0u8 as u8;

function t:
input r0 as boolean.private;
call x r0 into r1;
output r1 as u8.private;
""", errors = "", warnings = "" }] }]]
6 changes: 3 additions & 3 deletions tests/expectations/compiler/tuple/tuple_not_allowed_fail.out
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ Error [ETYC0372051]: A function cannot take in a tuple as input.
8 | function foo(a: (u8, u16)) -> (u8, u16) {
| ^
Error [ETYC0372049]: A tuple type cannot contain a tuple.
--> compiler-test:12:28
--> compiler-test:12:36
|
12 | function bar() -> (u8, (u16, u32)) {
| ^^^^^^^^^^
12 | function bar(zz: bool) -> (u8, (u16, u32)) {
| ^^^^^^^^^^
Error [ETYC0372052]: A tuple expression cannot contain another tuple expression.
--> compiler-test:13:22
|
Expand Down
22 changes: 0 additions & 22 deletions tests/expectations/parser/functions/empty2.out

This file was deleted.

2 changes: 1 addition & 1 deletion tests/tests/compiler/core/algorithms/pedersen_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() -> bool {
function main(zz: bool) -> bool {
let a: group = Pedersen64::hash_to_field(1u128); // Pedersen64 hash_to_field returns a field type

return true;
Expand Down
2 changes: 1 addition & 1 deletion tests/tests/compiler/field/no_space_between_literal.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let f = 1 field;
}}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
namespace = "Compile"
expectation = "Fail"
expectation = "Pass"
*/

program test.aleo {
Expand Down
10 changes: 10 additions & 0 deletions tests/tests/compiler/function/empty_arglist_fail.leo
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
namespace = "Compile"
expectation = "Fail"
*/

program test.aleo {
function x() -> u8 {
return 0u8;
}
}
16 changes: 16 additions & 0 deletions tests/tests/compiler/function/empty_function.leo
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
namespace = "Compile"
expectation = "Pass"
*/

program test.aleo {
// This should pass and insert
// a dummy instruction into the empty function.
function x(a: bool) -> u8 {
return 0u8;
}

transition t(a: bool) -> u8 {
return x(a);
}
}
2 changes: 1 addition & 1 deletion tests/tests/compiler/function/undefined_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() -> u8 {
function main(zz: bool) -> u8 {
my_function();
return 0u8;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/tests/compiler/group/no_space_between_literal.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() -> group {
function main(x: bool) -> group {
let g: group = (0,1) group;
return g;
}}
2 changes: 1 addition & 1 deletion tests/tests/compiler/integers/i128/max_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let a: i128 = 170141183460469231731687303715884105728i128;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let i = 1 i128;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let i = 1 i16;
}
}
2 changes: 1 addition & 1 deletion tests/tests/compiler/integers/i32/max_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let a: i32 = 2147483648i32;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let i = 1 i32;
}
}
2 changes: 1 addition & 1 deletion tests/tests/compiler/integers/i64/max_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let a: i64 = 9223372036854775808i64;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let i = 1 i64;
}
}
2 changes: 1 addition & 1 deletion tests/tests/compiler/integers/i8/max_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let a: i8 = 128i8;
}}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let i = 1 i8;
}
}
2 changes: 1 addition & 1 deletion tests/tests/compiler/integers/u128/hex_min_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let a: u128 = -0x1u128;
}
}
2 changes: 1 addition & 1 deletion tests/tests/compiler/integers/u128/max_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let a: u128 = 340282366920938463463374607431768211456u128;
}
}
2 changes: 1 addition & 1 deletion tests/tests/compiler/integers/u128/min_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let a: u128 = -1u128;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let i = 1 u128;
}
}
2 changes: 1 addition & 1 deletion tests/tests/compiler/integers/u16/hex_min_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let a: u16 = -0x1u16;
}
}
2 changes: 1 addition & 1 deletion tests/tests/compiler/integers/u16/max_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let a: u16 = 65536u16;
}
}
2 changes: 1 addition & 1 deletion tests/tests/compiler/integers/u16/min_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let a: u16 = -1u16;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let i = 1 u16;
}
}
2 changes: 1 addition & 1 deletion tests/tests/compiler/integers/u32/hex_min_fail.leo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expectation = "Fail"
*/

program test.aleo {
function main() {
function main(x: bool) {
let a: u32 = -0x1u32;
}
}
Loading

0 comments on commit c505dda

Please sign in to comment.