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

Error on futures in arrays, structs, or mappings. #28466

Merged
merged 1 commit into from
Nov 27, 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
12 changes: 10 additions & 2 deletions compiler/passes/src/type_checking/check_program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,13 @@ impl<'a, N: Network> ProgramVisitor<'a> for TypeChecker<'a, N> {
if input.is_record { "record" } else { "struct" },
identifier.span,
));
} else if matches!(type_, Type::Future(..)) {
self.emit_err(TypeCheckerError::composite_data_type_cannot_contain_future(
if input.is_record { "record" } else { "struct" },
identifier.span,
));
}

// Ensure that there are no record members.
self.assert_member_is_not_record(identifier.span, input.identifier.name, type_);
// If the member is a struct, add it to the struct dependency graph.
Expand Down Expand Up @@ -194,8 +200,9 @@ impl<'a, N: Network> ProgramVisitor<'a> for TypeChecker<'a, N> {
fn visit_mapping(&mut self, input: &'a Mapping) {
// Check that a mapping's key type is valid.
self.assert_type_is_valid(&input.key_type, input.span);
// Check that a mapping's key type is not a tuple, record, or mapping.
// Check that a mapping's key type is not a future, tuple, record, or mapping.
match input.key_type.clone() {
Type::Future(_) => self.emit_err(TypeCheckerError::invalid_mapping_type("key", "future", input.span)),
Type::Tuple(_) => self.emit_err(TypeCheckerError::invalid_mapping_type("key", "tuple", input.span)),
Type::Composite(struct_type) => {
if let Some(struct_) = self.lookup_struct(struct_type.program, struct_type.id.name) {
Expand All @@ -211,8 +218,9 @@ impl<'a, N: Network> ProgramVisitor<'a> for TypeChecker<'a, N> {

// Check that a mapping's value type is valid.
self.assert_type_is_valid(&input.value_type, input.span);
// Check that a mapping's value type is not a tuple, record or mapping.
// Check that a mapping's value type is not a future, tuple, record or mapping.
match input.value_type.clone() {
Type::Future(_) => self.emit_err(TypeCheckerError::invalid_mapping_type("value", "future", input.span)),
Type::Tuple(_) => self.emit_err(TypeCheckerError::invalid_mapping_type("value", "tuple", input.span)),
Type::Composite(struct_type) => {
if let Some(struct_) = self.lookup_struct(struct_type.program, struct_type.id.name) {
Expand Down
2 changes: 2 additions & 0 deletions compiler/passes/src/type_checking/checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,8 @@ impl<'a, N: Network> TypeChecker<'a, N> {
}
// Check that the array element type is valid.
match array_type.element_type() {
// Array elements cannot be futures.
Type::Future(_) => self.emit_err(TypeCheckerError::array_element_cannot_be_future(span)),
// Array elements cannot be tuples.
Type::Tuple(_) => self.emit_err(TypeCheckerError::array_element_cannot_be_tuple(span)),
// Array elements cannot be records.
Expand Down
14 changes: 14 additions & 0 deletions errors/src/errors/type_checker/type_checker_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -898,4 +898,18 @@ create_messages!(
msg: format!("Cannot define a function with no parameters."),
help: None,
}

@formatted
composite_data_type_cannot_contain_future {
args: (data_type: impl Display),
msg: format!("A {data_type} cannot contain a future."),
help: None,
}

@formatted
array_element_cannot_be_future {
args: (),
msg: format!("An array cannot have a future as an element type."),
help: None,
}
);
24 changes: 24 additions & 0 deletions tests/expectations/compiler/futures/future_in_composite_fail.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace = "Compile"
expectation = "Fail"
outputs = ["""
Error [ETYC0372114]: A struct cannot contain a future.
--> compiler-test:7:9
|
7 | member: Future,
| ^^^^^^
Error [ETYC0372031]: A mapping's key cannot be a future
--> compiler-test:4:5
|
4 | mapping x: Future => Future;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error [ETYC0372031]: A mapping's value cannot be a future
--> compiler-test:4:5
|
4 | mapping x: Future => Future;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error [ETYC0372115]: An array cannot have a future as an element type.
--> compiler-test:12:9
|
12 | let an_array: [Future; 1] = [future];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"""]
22 changes: 22 additions & 0 deletions tests/tests/compiler/futures/future_in_composite_fail.leo
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
namespace = "Compile"
expectation = "Fail"
*/

program test.aleo {
mapping x: Future => Future;

struct S {
member: Future,
}

async transition main() -> Future {
let future: Future = finish();
let an_array: [Future; 1] = [future];
return an_array[0u32];
}

async function finish() {
assert_eq(1u8, 1u8);
}
}
Loading