Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle closures that are invalid for Aleo. #28417

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading