diff --git a/compiler/ast/src/passes/visitor.rs b/compiler/ast/src/passes/visitor.rs index 324ca942e2..4c33c8f95d 100644 --- a/compiler/ast/src/passes/visitor.rs +++ b/compiler/ast/src/passes/visitor.rs @@ -114,7 +114,12 @@ pub trait ExpressionVisitor<'a> { Default::default() } - fn visit_struct_init(&mut self, _input: &'a StructExpression, _additional: &Self::AdditionalInput) -> Self::Output { + fn visit_struct_init(&mut self, input: &'a StructExpression, additional: &Self::AdditionalInput) -> Self::Output { + for StructVariableInitializer { expression, .. } in input.members.iter() { + if let Some(expression) = expression { + self.visit_expression(expression, additional); + } + } Default::default() } diff --git a/compiler/parser/src/parser/file.rs b/compiler/parser/src/parser/file.rs index 1390c114d1..043848b879 100644 --- a/compiler/parser/src/parser/file.rs +++ b/compiler/parser/src/parser/file.rs @@ -290,9 +290,10 @@ impl ParserContext<'_, N> { let name = self.expect_identifier()?; self.expect(&Token::Colon)?; - let type_ = self.parse_type()?.0; + let (type_, type_span) = self.parse_type()?; + let span = name.span() + type_span; - Ok(functions::Input { identifier: name, mode, type_, span: name.span, id: self.node_builder.next_id() }) + Ok(functions::Input { identifier: name, mode, type_, span, id: self.node_builder.next_id() }) } /// Returns an [`Output`] AST node if the next tokens represent a function output. diff --git a/compiler/passes/src/static_analysis/analyze_program.rs b/compiler/passes/src/static_analysis/analyze_program.rs index c97a670230..1c2f90ac34 100644 --- a/compiler/passes/src/static_analysis/analyze_program.rs +++ b/compiler/passes/src/static_analysis/analyze_program.rs @@ -39,6 +39,10 @@ impl<'a, N: Network> ProgramVisitor<'a> for StaticAnalyzer<'a, N> { // Set `non_async_external_call_seen` to false. self.non_async_external_call_seen = false; + if matches!(self.variant, Some(Variant::AsyncFunction) | Some(Variant::AsyncTransition)) { + super::future_checker::future_check_function(function, self.type_table, self.handler); + } + // If the function is an async function, initialize the await checker. if self.variant == Some(Variant::AsyncFunction) { // Initialize the list of input futures. Each one must be awaited before the end of the function. diff --git a/compiler/passes/src/static_analysis/future_checker.rs b/compiler/passes/src/static_analysis/future_checker.rs new file mode 100644 index 0000000000..f4d8de0c08 --- /dev/null +++ b/compiler/passes/src/static_analysis/future_checker.rs @@ -0,0 +1,167 @@ +// Copyright (C) 2019-2024 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::TypeTable; + +use leo_ast::{CoreFunction, Expression, ExpressionVisitor, Function, Node, StatementVisitor, Type}; +use leo_errors::{StaticAnalyzerError, emitter::Handler}; + +/// Error if futures are used improperly. +/// +/// This prevents, for instance, a bare call which creates an unused future. +pub fn future_check_function(function: &Function, type_table: &TypeTable, handler: &Handler) { + let mut future_checker = FutureChecker { type_table, handler }; + future_checker.visit_block(&function.block); +} + +#[derive(Clone, Copy, Debug, Default)] +enum Position { + #[default] + Misc, + Await, + TupleAccess, + Return, + FunctionArgument, + LastTupleLiteral, + Definition, +} + +struct FutureChecker<'a> { + type_table: &'a TypeTable, + handler: &'a Handler, +} + +impl<'a> FutureChecker<'a> { + fn emit_err(&self, err: StaticAnalyzerError) { + self.handler.emit_err(err); + } +} + +impl<'a> ExpressionVisitor<'a> for FutureChecker<'a> { + type AdditionalInput = Position; + type Output = (); + + fn visit_expression(&mut self, input: &'a Expression, additional: &Self::AdditionalInput) -> Self::Output { + use Position::*; + let is_call = matches!(input, Expression::Call(..)); + match self.type_table.get(&input.id()) { + Some(Type::Future(..)) if is_call => { + // A call producing a Future may appear in any of these positions. + if !matches!(additional, Await | Return | FunctionArgument | LastTupleLiteral | Definition) { + self.emit_err(StaticAnalyzerError::misplaced_future(input.span())); + } + } + Some(Type::Future(..)) => { + // A Future expression that's not a call may appear in any of these positions. + if !matches!(additional, Await | Return | FunctionArgument | LastTupleLiteral | TupleAccess) { + self.emit_err(StaticAnalyzerError::misplaced_future(input.span())); + } + } + Some(Type::Tuple(tuple)) if !matches!(tuple.elements().last(), Some(Type::Future(_))) => {} + Some(Type::Tuple(..)) if is_call => { + // A call producing a Tuple ending in a Future may appear in any of these positions. + if !matches!(additional, Return | Definition) { + self.emit_err(StaticAnalyzerError::misplaced_future(input.span())); + } + } + Some(Type::Tuple(..)) => { + // A Tuple ending in a Future that's not a call may appear in any of these positions. + if !matches!(additional, Return | TupleAccess) { + self.emit_err(StaticAnalyzerError::misplaced_future(input.span())); + } + } + _ => {} + } + + match input { + Expression::Access(access) => self.visit_access(access, &Position::Misc), + Expression::Array(array) => self.visit_array(array, &Position::Misc), + Expression::Binary(binary) => self.visit_binary(binary, &Position::Misc), + Expression::Call(call) => self.visit_call(call, &Position::Misc), + Expression::Cast(cast) => self.visit_cast(cast, &Position::Misc), + Expression::Struct(struct_) => self.visit_struct_init(struct_, &Position::Misc), + Expression::Err(err) => self.visit_err(err, &Position::Misc), + Expression::Identifier(identifier) => self.visit_identifier(identifier, &Position::Misc), + Expression::Literal(literal) => self.visit_literal(literal, &Position::Misc), + Expression::Locator(locator) => self.visit_locator(locator, &Position::Misc), + Expression::Ternary(ternary) => self.visit_ternary(ternary, &Position::Misc), + Expression::Tuple(tuple) => self.visit_tuple(tuple, additional), + Expression::Unary(unary) => self.visit_unary(unary, &Position::Misc), + Expression::Unit(unit) => self.visit_unit(unit, &Position::Misc), + } + } + + fn visit_access( + &mut self, + input: &'a leo_ast::AccessExpression, + _additional: &Self::AdditionalInput, + ) -> Self::Output { + match input { + leo_ast::AccessExpression::Array(array) => { + self.visit_expression(&array.array, &Position::Misc); + self.visit_expression(&array.index, &Position::Misc); + } + leo_ast::AccessExpression::AssociatedFunction(function) => { + let core_function = CoreFunction::from_symbols(function.variant.name, function.name.name) + .expect("Typechecking guarantees that this function exists."); + let position = + if core_function == CoreFunction::FutureAwait { Position::Await } else { Position::Misc }; + function.arguments.iter().for_each(|arg| { + self.visit_expression(arg, &position); + }); + } + leo_ast::AccessExpression::Member(member) => { + self.visit_expression(&member.inner, &Position::Misc); + } + leo_ast::AccessExpression::Tuple(tuple) => { + self.visit_expression(&tuple.tuple, &Position::TupleAccess); + } + _ => {} + } + + Default::default() + } + + fn visit_call(&mut self, input: &'a leo_ast::CallExpression, _additional: &Self::AdditionalInput) -> Self::Output { + input.arguments.iter().for_each(|expr| { + self.visit_expression(expr, &Position::FunctionArgument); + }); + Default::default() + } + + fn visit_tuple(&mut self, input: &'a leo_ast::TupleExpression, additional: &Self::AdditionalInput) -> Self::Output { + let next_position = match additional { + Position::Definition | Position::Return => Position::LastTupleLiteral, + _ => Position::Misc, + }; + let mut iter = input.elements.iter().peekable(); + while let Some(expr) = iter.next() { + let position = if iter.peek().is_some() { &Position::Misc } else { &next_position }; + self.visit_expression(expr, position); + } + Default::default() + } +} + +impl<'a> StatementVisitor<'a> for FutureChecker<'a> { + fn visit_definition(&mut self, input: &'a leo_ast::DefinitionStatement) { + self.visit_expression(&input.value, &Position::Definition); + } + + fn visit_return(&mut self, input: &'a leo_ast::ReturnStatement) { + self.visit_expression(&input.expression, &Position::Return); + } +} diff --git a/compiler/passes/src/static_analysis/mod.rs b/compiler/passes/src/static_analysis/mod.rs index fc4ea20029..e36a13a15b 100644 --- a/compiler/passes/src/static_analysis/mod.rs +++ b/compiler/passes/src/static_analysis/mod.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with the Leo library. If not, see . +mod future_checker; + mod await_checker; pub mod analyze_expression; diff --git a/compiler/passes/src/type_checking/check_expressions.rs b/compiler/passes/src/type_checking/check_expressions.rs index 8e86fccb71..29a52a1701 100644 --- a/compiler/passes/src/type_checking/check_expressions.rs +++ b/compiler/passes/src/type_checking/check_expressions.rs @@ -147,7 +147,6 @@ impl<'a, N: Network> ExpressionVisitor<'a> for TypeChecker<'a, N> { if let Some(expected) = expected { self.check_eq_types(&Some(actual.clone()), &Some(expected.clone()), access.span()); } - // Return type of tuple index. return Some(actual); } @@ -675,6 +674,30 @@ impl<'a, N: Network> ExpressionVisitor<'a> for TypeChecker<'a, N> { let ty = self.visit_expression(argument, &Some(expected.type_().clone()))?; // Extract information about futures that are being consumed. if func.variant == Variant::AsyncFunction && matches!(expected.type_(), Type::Future(_)) { + // Consume the future. + let option_name = match argument { + Expression::Identifier(id) => Some(id.name), + Expression::Access(AccessExpression::Tuple(tuple_access)) => { + if let Expression::Identifier(id) = &*tuple_access.tuple { + Some(id.name) + } else { + None + } + } + _ => None, + }; + + if let Some(name) = option_name { + match self.scope_state.futures.shift_remove(&name) { + Some(future) => { + self.scope_state.call_location = Some(future.clone()); + } + None => { + self.emit_err(TypeCheckerError::unknown_future_consumed(name, argument.span())); + } + } + } + match argument { Expression::Identifier(_) | Expression::Call(_) @@ -857,23 +880,6 @@ impl<'a, N: Network> ExpressionVisitor<'a> for TypeChecker<'a, N> { fn visit_identifier(&mut self, input: &'a Identifier, expected: &Self::AdditionalInput) -> Self::Output { let var = self.symbol_table.borrow().lookup_variable(Location::new(None, input.name)).cloned(); if let Some(var) = &var { - if matches!(var.type_, Type::Future(_)) && matches!(expected, Some(Type::Future(_))) { - if self.scope_state.variant == Some(Variant::AsyncTransition) && self.scope_state.is_call { - // Consume future. - match self.scope_state.futures.shift_remove(&input.name) { - Some(future) => { - self.scope_state.call_location = Some(future.clone()); - return Some(var.type_.clone()); - } - None => { - self.emit_err(TypeCheckerError::unknown_future_consumed(input.name, input.span)); - } - } - } else { - // Case where accessing input argument of future. Ex `f.1`. - return Some(var.type_.clone()); - } - } Some(self.assert_and_return_type(var.type_.clone(), expected, input.span())) } else { self.emit_err(TypeCheckerError::unknown_sym("variable", input.name, input.span())); diff --git a/compiler/passes/src/type_checking/check_statements.rs b/compiler/passes/src/type_checking/check_statements.rs index d60b2ab09e..6324281f5b 100644 --- a/compiler/passes/src/type_checking/check_statements.rs +++ b/compiler/passes/src/type_checking/check_statements.rs @@ -23,8 +23,6 @@ use leo_ast::{ }; use leo_errors::TypeCheckerError; -use itertools::Itertools; - impl<'a, N: Network> StatementVisitor<'a> for TypeChecker<'a, N> { fn visit_statement(&mut self, input: &'a Statement) { // No statements can follow a return statement. @@ -248,7 +246,7 @@ impl<'a, N: Network> StatementVisitor<'a> for TypeChecker<'a, N> { // Insert the variables into the symbol table. match &input.place { Expression::Identifier(identifier) => { - self.insert_variable(inferred_type.clone(), identifier, input.type_.clone(), 0, identifier.span) + self.insert_variable(inferred_type.clone(), identifier, input.type_.clone(), identifier.span) } Expression::Tuple(tuple_expression) => { let tuple_type = match &input.type_ { @@ -265,9 +263,13 @@ impl<'a, N: Network> StatementVisitor<'a> for TypeChecker<'a, N> { )); } - for ((index, expr), type_) in - tuple_expression.elements.iter().enumerate().zip_eq(tuple_type.elements().iter()) - { + for i in 0..tuple_expression.elements.len() { + let inferred = if let Some(Type::Tuple(inferred_tuple)) = &inferred_type { + inferred_tuple.elements().get(i).cloned() + } else { + None + }; + let expr = &tuple_expression.elements[i]; let identifier = match expr { Expression::Identifier(identifier) => identifier, _ => { @@ -275,7 +277,7 @@ impl<'a, N: Network> StatementVisitor<'a> for TypeChecker<'a, N> { .emit_err(TypeCheckerError::lhs_tuple_element_must_be_an_identifier(expr.span())); } }; - self.insert_variable(inferred_type.clone(), identifier, type_.clone(), index, identifier.span); + self.insert_variable(inferred, identifier, tuple_type.elements()[i].clone(), identifier.span); } } _ => self.emit_err(TypeCheckerError::lhs_must_be_identifier_or_tuple(input.place.span())), diff --git a/compiler/passes/src/type_checking/checker.rs b/compiler/passes/src/type_checking/checker.rs index ff24e68aad..3b85386cb7 100644 --- a/compiler/passes/src/type_checking/checker.rs +++ b/compiler/passes/src/type_checking/checker.rs @@ -1220,10 +1220,21 @@ impl<'a, N: Network> TypeChecker<'a, N> { } } - // Add function inputs to the symbol table. Futures have already been added. - if !matches!(&input_var.type_(), &Type::Future(_)) { + if matches!(&input_var.type_(), Type::Future(_)) { + // Future parameters may only appear in async functions. + if !matches!(self.scope_state.variant, Some(Variant::AsyncFunction)) { + self.emit_err(TypeCheckerError::no_future_parameters(input_var.span())); + } + } + + let location = Location::new(None, input_var.identifier().name); + if !matches!(&input_var.type_(), Type::Future(_)) + || self.symbol_table.borrow().lookup_variable_in_current_scope(location.clone()).is_none() + { + // Add function inputs to the symbol table. If inference happened properly above, futures were already added. + // But if a future was not added, add it now so as not to give confusing error messages. if let Err(err) = self.symbol_table.borrow_mut().insert_variable( - Location::new(None, input_var.identifier().name), + location.clone(), self.scope_state.program_name, VariableSymbol { type_: input_var.type_().clone(), @@ -1302,32 +1313,23 @@ impl<'a, N: Network> TypeChecker<'a, N> { } /// Inserts variable to symbol table. - pub(crate) fn insert_variable( - &mut self, - inferred_type: Option, - name: &Identifier, - type_: Type, - index: usize, - span: Span, - ) { - let ty: Type = if let Type::Future(_) = type_ { - // Need to insert the fully inferred future type, or else will just be default future type. - let ret = match inferred_type.unwrap() { - Type::Future(future) => Type::Future(future), - Type::Tuple(tuple) => match tuple.elements().get(index) { - Some(Type::Future(future)) => Type::Future(future.clone()), - _ => unreachable!("Parsing guarantees that the inferred type is a future."), - }, - _ => { - unreachable!("TYC guarantees that the inferred type is a future, or tuple containing futures.") - } - }; - // Insert future into list of futures for the function. + pub(crate) fn insert_variable(&mut self, inferred_type: Option, name: &Identifier, type_: Type, span: Span) { + let is_future = match &type_ { + Type::Future(..) => true, + Type::Tuple(tuple_type) if matches!(tuple_type.elements().last(), Some(Type::Future(..))) => true, + _ => false, + }; + + if is_future { self.scope_state.futures.insert(name.name, self.scope_state.call_location.clone().unwrap()); - ret - } else { - type_ + } + + let ty = match (is_future, inferred_type) { + (false, _) => type_, + (true, Some(inferred)) => inferred, + (true, None) => unreachable!("Type checking guarantees the inferred type is present"), }; + // Insert the variable into the symbol table. if let Err(err) = self.symbol_table.borrow_mut().insert_variable( Location::new(None, name.name), diff --git a/errors/src/errors/static_analyzer/static_analyzer_error.rs b/errors/src/errors/static_analyzer/static_analyzer_error.rs index 698a717647..20f5817d44 100644 --- a/errors/src/errors/static_analyzer/static_analyzer_error.rs +++ b/errors/src/errors/static_analyzer/static_analyzer_error.rs @@ -59,4 +59,11 @@ create_messages!( msg: format!("The call to {function_name} will result in failed executions on-chain."), help: Some("There is a subtle error that occurs if an async transition call follows a non-async transition call, and the async call returns a `Future` that itself takes a `Future` as an input. See See `https://github.com/AleoNet/snarkVM/issues/2570` for more context.".to_string()), } + + @formatted + misplaced_future { + args: (), + msg: "A future may not be used in this way".to_string(), + help: Some("Futures should be created, assigned to a variable, and consumed without being moved or reassigned.".to_string()), + } ); diff --git a/errors/src/errors/type_checker/type_checker_error.rs b/errors/src/errors/type_checker/type_checker_error.rs index db2970685a..1ec82fc902 100644 --- a/errors/src/errors/type_checker/type_checker_error.rs +++ b/errors/src/errors/type_checker/type_checker_error.rs @@ -912,4 +912,11 @@ create_messages!( msg: format!("An array cannot have a future as an element type."), help: None, } + + @formatted + no_future_parameters { + args: (), + msg: format!("Futures may only appear as parameters to async functions."), + help: None, + } ); diff --git a/tests/expectations/compiler/array/array_of_records.out b/tests/expectations/compiler/array/array_of_records.out index abfecc9441..562e9ffa43 100644 --- a/tests/expectations/compiler/array/array_of_records.out +++ b/tests/expectations/compiler/array/array_of_records.out @@ -5,5 +5,5 @@ Error [ETYC0372079]: An array cannot have a record as an element type --> compiler-test:9:20 | 9 | transition foo(a: [bar; 8]) -> u8 { - | ^ + | ^^^^^^^^^^^ """] diff --git a/tests/expectations/compiler/array/array_too_large_fail.out b/tests/expectations/compiler/array/array_too_large_fail.out index c36adb1789..3972b4c52c 100644 --- a/tests/expectations/compiler/array/array_too_large_fail.out +++ b/tests/expectations/compiler/array/array_too_large_fail.out @@ -5,5 +5,5 @@ Error [ETYC0372077]: An array cannot have more than 32 elements, found one with --> compiler-test:4:20 | 4 | transition foo(a: [bool; 33]) -> bool { - | ^ + | ^^^^^^^^^^^^^ """] diff --git a/tests/expectations/compiler/array/array_too_small_fail.out b/tests/expectations/compiler/array/array_too_small_fail.out index 87b9ba7226..70f3d81ad7 100644 --- a/tests/expectations/compiler/array/array_too_small_fail.out +++ b/tests/expectations/compiler/array/array_too_small_fail.out @@ -5,5 +5,5 @@ Error [ETYC0372076]: An array cannot be empty --> compiler-test:4:20 | 4 | transition foo(a: [bool; 0]) -> bool { - | ^ + | ^^^^^^^^^^^^ """] diff --git a/tests/expectations/compiler/finalize/finalize_incorrect_modes_fail.out b/tests/expectations/compiler/finalize/finalize_incorrect_modes_fail.out index 6dfc880ef6..c312bac687 100644 --- a/tests/expectations/compiler/finalize/finalize_incorrect_modes_fail.out +++ b/tests/expectations/compiler/finalize/finalize_incorrect_modes_fail.out @@ -14,7 +14,7 @@ Error [ETYC0372032]: An input to an async function must be public. --> compiler-test:10:76 | 10 | async function finalize_mint_public(public receiver: address, constant amount: u64) -> constant u64 { - | ^^^^^^ + | ^^^^^^^^^^^ | = Use a `public` modifier to the input variable declaration or remove the visibility modifier entirely. Error [ETYC0372038]: A returned value cannot be a constant. diff --git a/tests/expectations/compiler/function/function_returns_record_fail.out b/tests/expectations/compiler/function/function_returns_record_fail.out index 0ac88be6ab..28ff80dd06 100644 --- a/tests/expectations/compiler/function/function_returns_record_fail.out +++ b/tests/expectations/compiler/function/function_returns_record_fail.out @@ -5,12 +5,12 @@ Error [ETYC0372057]: Only `transition` functions can have a record as input or o --> compiler-test:9:18 | 9 | function foo(board: Board, data: u8) -> Board { - | ^^^^^ + | ^^^^^^^^^^^^ Error [ETYC0372057]: Only `transition` functions can have a record as input or output. --> compiler-test:9:18 | 9 | function foo(board: Board, data: u8) -> Board { - | ^^^^^ + | ^^^^^^^^^^^^ Error [ETYC0372057]: Only `transition` functions can have a record as input or output. --> compiler-test:9:45 | @@ -25,10 +25,10 @@ Error [ETYC0372057]: Only `transition` functions can have a record as input or o --> compiler-test:16:18 | 16 | function bar(board: Board) { - | ^^^^^ + | ^^^^^^^^^^^^ Error [ETYC0372057]: Only `transition` functions can have a record as input or output. --> compiler-test:16:18 | 16 | function bar(board: Board) { - | ^^^^^ + | ^^^^^^^^^^^^ """] diff --git a/tests/expectations/compiler/function/non_transition_variant_input_record_fail.out b/tests/expectations/compiler/function/non_transition_variant_input_record_fail.out index 14a345ce74..5c52a9615e 100644 --- a/tests/expectations/compiler/function/non_transition_variant_input_record_fail.out +++ b/tests/expectations/compiler/function/non_transition_variant_input_record_fail.out @@ -5,12 +5,12 @@ Error [ETYC0372057]: Only `transition` functions can have a record as input or o --> compiler-test:9:18 | 9 | function foo(a: credits) -> u8 { - | ^ + | ^^^^^^^^^^ Error [ETYC0372057]: Only `transition` functions can have a record as input or output. --> compiler-test:9:18 | 9 | function foo(a: credits) -> u8 { - | ^ + | ^^^^^^^^^^ Error [ETYC0372057]: Only `transition` functions can have a record as input or output. --> compiler-test:13:41 | diff --git a/tests/expectations/compiler/function/undefined_data_type_fail.out b/tests/expectations/compiler/function/undefined_data_type_fail.out index 63f8440de1..432e2cd2f6 100644 --- a/tests/expectations/compiler/function/undefined_data_type_fail.out +++ b/tests/expectations/compiler/function/undefined_data_type_fail.out @@ -5,14 +5,14 @@ Error [ETYC0372017]: The type `Board` is not found in the current scope. --> compiler-test:4:35 | 4 | function aria192check_for_win(b: Board, p: u8) -> u128bool { - | ^ + | ^^^^^^^^ | = If you are using an external type, make sure to preface with the program name. Ex: `credits.aleo/credits` instead of `credits` Error [ETYC0372017]: The type `Board` is not found in the current scope. --> compiler-test:4:35 | 4 | function aria192check_for_win(b: Board, p: u8) -> u128bool { - | ^ + | ^^^^^^^^ | = If you are using an external type, make sure to preface with the program name. Ex: `credits.aleo/credits` instead of `credits` Error [ETYC0372017]: The type `u128bool` is not found in the current scope. diff --git a/tests/expectations/compiler/function/unknown_parameter_type_fail.out b/tests/expectations/compiler/function/unknown_parameter_type_fail.out index fb869d1b9d..e7e1376626 100644 --- a/tests/expectations/compiler/function/unknown_parameter_type_fail.out +++ b/tests/expectations/compiler/function/unknown_parameter_type_fail.out @@ -5,7 +5,7 @@ Error [ETYC0372017]: The type `Foo` is not found in the current scope. --> compiler-test:4:28 | 4 | transition main(a: u8, foo: Foo) -> u8 { - | ^^^ + | ^^^^^^^^ | = If you are using an external type, make sure to preface with the program name. Ex: `credits.aleo/credits` instead of `credits` Error [ETYC0372017]: The type `Foo` is not found in the current scope. diff --git a/tests/expectations/compiler/futures/future_access_tuple_fail.out b/tests/expectations/compiler/futures/future_access_tuple_fail.out new file mode 100644 index 0000000000..e2c2639cc3 --- /dev/null +++ b/tests/expectations/compiler/futures/future_access_tuple_fail.out @@ -0,0 +1,11 @@ +namespace = "Compile" +expectation = "Fail" +outputs = [""" +Error [ESAZ0374005]: A future may not be used in this way + --> compiler-test:9:37 + | + 9 | let start_2: Future = start.1; + | ^ + | + = Futures should be created, assigned to a variable, and consumed without being moved or reassigned. +"""] diff --git a/tests/expectations/compiler/futures/future_in_tuple.out b/tests/expectations/compiler/futures/future_in_tuple.out index e475a7a58c..143c38c3c0 100644 --- a/tests/expectations/compiler/futures/future_in_tuple.out +++ b/tests/expectations/compiler/futures/future_in_tuple.out @@ -19,7 +19,7 @@ function transfer_private_to_public: finalize transfer_private_to_public: assert.eq 1u8 1u8; """, errors = "", warnings = "" }, - { initial_symbol_table = "baa9875274a09ad91eb08326f18797401a6e98c32388e75b3b406a539acab343", type_checked_symbol_table = "610cf3eeddc2789f19854347864fbaae2dc10ecc0aae8034fe3eaaa2394ba89f", unrolled_symbol_table = "610cf3eeddc2789f19854347864fbaae2dc10ecc0aae8034fe3eaaa2394ba89f", initial_ast = "fc9f1985c1e0441e9423e67cfd4cb8252178ccc236dfabae17187c5a5cc98ebe", unrolled_ast = "c6fdd37447ee674a058e7fe314096c0df8cf0c02f307ff499e0f08b76cdc6709", ssa_ast = "d26ea69b3993a2a3c4b2660a27706c51383f9b01357d27adf6275a5dfffe6e9d", flattened_ast = "5741efe1907a4da96fbad021b725a22e8c3365fa61b2413b06743c3ed01cda35", destructured_ast = "496bea9fd498c2d4ac9d93dd143beb403e13fdf59fc2ff842d8ff932883feda1", inlined_ast = "7c87cc964f8225fd91c634c8683ee0b09aaa301cb29ab85cadc4e4aea65253ba", dce_ast = "7c87cc964f8225fd91c634c8683ee0b09aaa301cb29ab85cadc4e4aea65253ba", bytecode = """ + { initial_symbol_table = "baa9875274a09ad91eb08326f18797401a6e98c32388e75b3b406a539acab343", type_checked_symbol_table = "6cc6e544cd0fac9b595d1236775033d8f492c506570b174bd4958280c45238fb", unrolled_symbol_table = "6cc6e544cd0fac9b595d1236775033d8f492c506570b174bd4958280c45238fb", initial_ast = "fc9f1985c1e0441e9423e67cfd4cb8252178ccc236dfabae17187c5a5cc98ebe", unrolled_ast = "c6fdd37447ee674a058e7fe314096c0df8cf0c02f307ff499e0f08b76cdc6709", ssa_ast = "d26ea69b3993a2a3c4b2660a27706c51383f9b01357d27adf6275a5dfffe6e9d", flattened_ast = "5741efe1907a4da96fbad021b725a22e8c3365fa61b2413b06743c3ed01cda35", destructured_ast = "496bea9fd498c2d4ac9d93dd143beb403e13fdf59fc2ff842d8ff932883feda1", inlined_ast = "7c87cc964f8225fd91c634c8683ee0b09aaa301cb29ab85cadc4e4aea65253ba", dce_ast = "7c87cc964f8225fd91c634c8683ee0b09aaa301cb29ab85cadc4e4aea65253ba", bytecode = """ import credits.aleo; program test_credits.aleo; diff --git a/tests/expectations/compiler/futures/future_in_tuple_check_fail.out b/tests/expectations/compiler/futures/future_in_tuple_check_fail.out new file mode 100644 index 0000000000..9496f0f61a --- /dev/null +++ b/tests/expectations/compiler/futures/future_in_tuple_check_fail.out @@ -0,0 +1,11 @@ +namespace = "Compile" +expectation = "Fail" +outputs = [""" +Error [ETYC0372104]: Not all futures were consumed: result2 + --> compiler-test:9:27 + | + 9 | return (result.0, finish(result.1)); + | ^^^^^^^^^^^^^^^^ + | + = Make sure all futures are consumed exactly once. Consume by passing to an async function call. +"""] diff --git a/tests/expectations/compiler/futures/future_parameter_fail.out b/tests/expectations/compiler/futures/future_parameter_fail.out new file mode 100644 index 0000000000..57ebf24fdb --- /dev/null +++ b/tests/expectations/compiler/futures/future_parameter_fail.out @@ -0,0 +1,19 @@ +namespace = "Compile" +expectation = "Fail" +outputs = [""" +Error [ETYC0372116]: Futures may only appear as parameters to async functions. + --> compiler-test:4:28 + | + 4 | async transition first(x: Future) -> Future { + | ^^^^^^^^^ +Error [ETYC0372116]: Futures may only appear as parameters to async functions. + --> compiler-test:8:23 + | + 8 | transition second(x: Future) -> u8 { + | ^^^^^^^^^ +Error [ETYC0372116]: Futures may only appear as parameters to async functions. + --> compiler-test:12:20 + | + 12 | function third(x: Future) -> u8 { + | ^^^^^^^^^ +"""] diff --git a/tests/expectations/compiler/futures/misplaced_future_fail.out b/tests/expectations/compiler/futures/misplaced_future_fail.out new file mode 100644 index 0000000000..925066dc8b --- /dev/null +++ b/tests/expectations/compiler/futures/misplaced_future_fail.out @@ -0,0 +1,18 @@ +namespace = "Compile" +expectation = "Fail" +outputs = [""" +Error [ESAZ0374005]: A future may not be used in this way + --> compiler-test:10:9 + | + 10 | child.aleo/foo(); + | ^^^^^^^^^^^^^^^^ + | + = Futures should be created, assigned to a variable, and consumed without being moved or reassigned. +Error [ESAZ0374005]: A future may not be used in this way + --> compiler-test:12:9 + | + 12 | child.aleo/boo(); + | ^^^^^^^^^^^^^^^^ + | + = Futures should be created, assigned to a variable, and consumed without being moved or reassigned. +"""] diff --git a/tests/expectations/compiler/futures/nested.out b/tests/expectations/compiler/futures/nested.out index 6a6bd4abf5..b08dd78da1 100644 --- a/tests/expectations/compiler/futures/nested.out +++ b/tests/expectations/compiler/futures/nested.out @@ -86,7 +86,7 @@ Warning [WSAZ0374000]: Not all paths through the function await all futures. 2/4 | ^ | = Ex: `f.await()` to await a future. Remove this warning by including the `--disable-conditional-branch-type-checking` flag.""" }, - { initial_symbol_table = "539fd89c0dea3feb2b2b3844532aacc032658f2546cd011dd1aa257eb18dc0af", type_checked_symbol_table = "b3785d02f513f6e1671e4c42f2674c7ecb8da3f2c8bd20d36024d7d2e1322217", unrolled_symbol_table = "b3785d02f513f6e1671e4c42f2674c7ecb8da3f2c8bd20d36024d7d2e1322217", initial_ast = "05de2b0dcfd85ec6446f4507492e26b2093e771f44c497f92a24d6fff5e8c864", unrolled_ast = "4f09dae0678393afc3cbc5592159df83ca22b947084d3c8e779281724d07a2ca", ssa_ast = "0cb5c531ad471909089716ef6c7382fb3fcbb82dafb6edef541e4f7cff4fb8ba", flattened_ast = "46d54d4d9fe36538d34ac306780262ee1f54a6141aa2281ef7ae74ffcf4dddcf", destructured_ast = "88653b95656b6f56872d7ea452491322e4c122909879b72856b891c474aa8342", inlined_ast = "0f81029815dec13a526530eeea0e92e6eb61313421ce5a7b46ed3739d62beaf6", dce_ast = "6b852bcf601b323678eea14e096f49c72f8800d18ec811b00c31817daf630d63", bytecode = """ + { initial_symbol_table = "539fd89c0dea3feb2b2b3844532aacc032658f2546cd011dd1aa257eb18dc0af", type_checked_symbol_table = "869d309eda62dec11d14555672b7946d52fa30a015f510aeb8dcf77224f4125d", unrolled_symbol_table = "869d309eda62dec11d14555672b7946d52fa30a015f510aeb8dcf77224f4125d", initial_ast = "05de2b0dcfd85ec6446f4507492e26b2093e771f44c497f92a24d6fff5e8c864", unrolled_ast = "4f09dae0678393afc3cbc5592159df83ca22b947084d3c8e779281724d07a2ca", ssa_ast = "0cb5c531ad471909089716ef6c7382fb3fcbb82dafb6edef541e4f7cff4fb8ba", flattened_ast = "46d54d4d9fe36538d34ac306780262ee1f54a6141aa2281ef7ae74ffcf4dddcf", destructured_ast = "88653b95656b6f56872d7ea452491322e4c122909879b72856b891c474aa8342", inlined_ast = "0f81029815dec13a526530eeea0e92e6eb61313421ce5a7b46ed3739d62beaf6", dce_ast = "6b852bcf601b323678eea14e096f49c72f8800d18ec811b00c31817daf630d63", bytecode = """ import test_dep.aleo; import test.aleo; program wrapper.aleo; @@ -109,7 +109,7 @@ finalize main: await r1; await r2; """, errors = "", warnings = "" }, - { initial_symbol_table = "07bdfd403caa73ec17903694bb68a93e108011dc9d77e555fd2815e4da90a1de", type_checked_symbol_table = "9e2a9214686265f8ebc82b39d1102894360f03fd7e0f1cf3f8f8dc1cf463f0c6", unrolled_symbol_table = "9e2a9214686265f8ebc82b39d1102894360f03fd7e0f1cf3f8f8dc1cf463f0c6", initial_ast = "bf4f5dac2e3cac6f6c8b117a93b7bc9a4b9d31f66b3b0d946866da23003e6a69", unrolled_ast = "a1786c230d46f3b207f118aaaaea373cd1d9935aa7e63b99e403a8faf36df2fe", ssa_ast = "82581ca24afcd79d3e3c1346009981d4a9d3d227afc0540707b6c315ecdce107", flattened_ast = "2ff2d69c6199a5c70a8ffb96d8dc0529f6f1fbf631a1f690169d2d9162e91689", destructured_ast = "8da4c7c91fabf5edb6768e616f223e574b3415c848321f66ad9e587b76259210", inlined_ast = "a740025e070d37bd22f264e37dfd6802eb9e1b10c12c928a08acd14fbe9043d6", dce_ast = "e127a5223a49f123398009b927e96ebb44f266df7271feb7b1ff5f7f748e6ff5", bytecode = """ + { initial_symbol_table = "07bdfd403caa73ec17903694bb68a93e108011dc9d77e555fd2815e4da90a1de", type_checked_symbol_table = "0deaa782322a693add2dd04fce9b1bfc4ea73654172e59ad9c2da0e04d995820", unrolled_symbol_table = "0deaa782322a693add2dd04fce9b1bfc4ea73654172e59ad9c2da0e04d995820", initial_ast = "bf4f5dac2e3cac6f6c8b117a93b7bc9a4b9d31f66b3b0d946866da23003e6a69", unrolled_ast = "a1786c230d46f3b207f118aaaaea373cd1d9935aa7e63b99e403a8faf36df2fe", ssa_ast = "82581ca24afcd79d3e3c1346009981d4a9d3d227afc0540707b6c315ecdce107", flattened_ast = "2ff2d69c6199a5c70a8ffb96d8dc0529f6f1fbf631a1f690169d2d9162e91689", destructured_ast = "8da4c7c91fabf5edb6768e616f223e574b3415c848321f66ad9e587b76259210", inlined_ast = "a740025e070d37bd22f264e37dfd6802eb9e1b10c12c928a08acd14fbe9043d6", dce_ast = "e127a5223a49f123398009b927e96ebb44f266df7271feb7b1ff5f7f748e6ff5", bytecode = """ import test_dep.aleo; import test.aleo; import wrapper.aleo; diff --git a/tests/expectations/compiler/futures/non_async_after_complex_async.out b/tests/expectations/compiler/futures/non_async_after_complex_async.out index 1a915a53a8..15289b4f3f 100644 --- a/tests/expectations/compiler/futures/non_async_after_complex_async.out +++ b/tests/expectations/compiler/futures/non_async_after_complex_async.out @@ -36,7 +36,7 @@ finalize mid: function dummy: """, errors = "", warnings = "" }, - { initial_symbol_table = "f662e7a456e22a2d1b4b42fa3221de16e5671edc25c1d0b20610dfd0ab55c579", type_checked_symbol_table = "bc09a36414412397442b9bf24d95ddbb21d0bf2d1b70f7084df400bdd836e37a", unrolled_symbol_table = "bc09a36414412397442b9bf24d95ddbb21d0bf2d1b70f7084df400bdd836e37a", initial_ast = "5df535c99668c958f5649f0e5d24ae951023b165941ded5e9df3665a1c4bdd7d", unrolled_ast = "57200953ba2c83408d2dbc51c10e7c01143b6ed3f3dcf96616e7072ac99e2152", ssa_ast = "223b30eb9d800a33aab6105dea3b4dde8bc3435673b1be29ab4268e944406384", flattened_ast = "2ed49413ee703e36ee432a5f271fecb3327be45039477ee9bc2bc6ef77e25f41", destructured_ast = "26b81f6ad2dab39e3a9a5e1d73ebff1f5a165f794897fd770ed0f7927a34bf95", inlined_ast = "5dc7a113088ff1f7682c9b5618e381baa011609a7f2e1a876272c1fd79b6dfd3", dce_ast = "5dc7a113088ff1f7682c9b5618e381baa011609a7f2e1a876272c1fd79b6dfd3", bytecode = """ + { initial_symbol_table = "f662e7a456e22a2d1b4b42fa3221de16e5671edc25c1d0b20610dfd0ab55c579", type_checked_symbol_table = "dc5d562dfebd056cf956fd6c299ad70e99500786ddbe67c0f858bd09259d5d5f", unrolled_symbol_table = "dc5d562dfebd056cf956fd6c299ad70e99500786ddbe67c0f858bd09259d5d5f", initial_ast = "5df535c99668c958f5649f0e5d24ae951023b165941ded5e9df3665a1c4bdd7d", unrolled_ast = "57200953ba2c83408d2dbc51c10e7c01143b6ed3f3dcf96616e7072ac99e2152", ssa_ast = "223b30eb9d800a33aab6105dea3b4dde8bc3435673b1be29ab4268e944406384", flattened_ast = "2ed49413ee703e36ee432a5f271fecb3327be45039477ee9bc2bc6ef77e25f41", destructured_ast = "26b81f6ad2dab39e3a9a5e1d73ebff1f5a165f794897fd770ed0f7927a34bf95", inlined_ast = "5dc7a113088ff1f7682c9b5618e381baa011609a7f2e1a876272c1fd79b6dfd3", dce_ast = "5dc7a113088ff1f7682c9b5618e381baa011609a7f2e1a876272c1fd79b6dfd3", bytecode = """ import inner.aleo; import mid.aleo; program outer.aleo; diff --git a/tests/expectations/compiler/futures/partial_type_specification.out b/tests/expectations/compiler/futures/partial_type_specification.out index e80a77be15..d7df5ae590 100644 --- a/tests/expectations/compiler/futures/partial_type_specification.out +++ b/tests/expectations/compiler/futures/partial_type_specification.out @@ -96,7 +96,7 @@ Warning [WSAZ0374000]: Not all paths through the function await all futures. 2/4 | ^ | = Ex: `f.await()` to await a future. Remove this warning by including the `--disable-conditional-branch-type-checking` flag.""" }, - { initial_symbol_table = "cd14d130e4f9b9b92f731cb8caee6237ae4477573ea636af8775e5e02966390e", type_checked_symbol_table = "387eabcc94db2a5021555b90e0dddcb7373aa3344fe7bbc86087f32f0893fa35", unrolled_symbol_table = "387eabcc94db2a5021555b90e0dddcb7373aa3344fe7bbc86087f32f0893fa35", initial_ast = "856e56d95eaf14f6e9241001763546b7d982402ac87521e2ec3b7ea476764692", unrolled_ast = "75b69748ca1e534c95cf084164773d471f51537b50b2d517dc4be26dddb06e1b", ssa_ast = "6d38bf225e9cf5af37b9d6c595c2973ec31a32d227ca65cb590d27400d442780", flattened_ast = "65fb4138701cad86a5fcd7e024645e833aeb6e88b3ea2a3a6b69269fd1d77620", destructured_ast = "85a81c23da7e97b057ddf4ef71f375781e1dfcb90d656d694a5aa0f0c176b497", inlined_ast = "a1b2367575e170a79ace2ac7ff071bc3c770476b37ee149310c3b2cfe67b1c7f", dce_ast = "f46fa7963b327b9c75c9f7a7569e350d7f62c21964cb5df140cd2186c2043697", bytecode = """ + { initial_symbol_table = "cd14d130e4f9b9b92f731cb8caee6237ae4477573ea636af8775e5e02966390e", type_checked_symbol_table = "865ddd67b06a908cdb65e83c1bca76bc5c0d860f89ef6b2f354fd2470c94b188", unrolled_symbol_table = "865ddd67b06a908cdb65e83c1bca76bc5c0d860f89ef6b2f354fd2470c94b188", initial_ast = "856e56d95eaf14f6e9241001763546b7d982402ac87521e2ec3b7ea476764692", unrolled_ast = "75b69748ca1e534c95cf084164773d471f51537b50b2d517dc4be26dddb06e1b", ssa_ast = "6d38bf225e9cf5af37b9d6c595c2973ec31a32d227ca65cb590d27400d442780", flattened_ast = "65fb4138701cad86a5fcd7e024645e833aeb6e88b3ea2a3a6b69269fd1d77620", destructured_ast = "85a81c23da7e97b057ddf4ef71f375781e1dfcb90d656d694a5aa0f0c176b497", inlined_ast = "a1b2367575e170a79ace2ac7ff071bc3c770476b37ee149310c3b2cfe67b1c7f", dce_ast = "f46fa7963b327b9c75c9f7a7569e350d7f62c21964cb5df140cd2186c2043697", bytecode = """ import test_dep.aleo; import test.aleo; program wrapper.aleo; @@ -119,7 +119,7 @@ finalize main: await r1; await r2; """, errors = "", warnings = "" }, - { initial_symbol_table = "29aefa9acac4488265303e8b3bd52a434ae4824211df7919f6b63cfe6e1ec51f", type_checked_symbol_table = "1d1a8312d73125086e436d6463fd554fbc3aa622a2e28efc8622ddf0adfb473f", unrolled_symbol_table = "1d1a8312d73125086e436d6463fd554fbc3aa622a2e28efc8622ddf0adfb473f", initial_ast = "575e251f07e552c917ab36bc9877b13dd1638651c4023ade20701dd2a5fe27ff", unrolled_ast = "2a4969ad315e900b5a3f1eecd4e6508dc6946fb5f6c3861ee793961ce6bcc203", ssa_ast = "4a00e3d36cdd4ff4be1fc6a389aaf17cfb02b6c54fa84276fb5be66b8a78b124", flattened_ast = "885c5f8145aa1a82e5fe41abbabae12cbd15eb014b333b246c6c5401b5b6bfea", destructured_ast = "f3b5b961a498f9befec85b69b3012145a6e97774d37a8c8e354ec4e5eeb64f84", inlined_ast = "2bf37fc499b3eca18c8227e61f69f730d36e755d7879dde13bb9161936bafbfc", dce_ast = "390391c2098cf6a910eeec98fc92fdea31303a84a1d6fd6673c8dbd9d20180de", bytecode = """ + { initial_symbol_table = "29aefa9acac4488265303e8b3bd52a434ae4824211df7919f6b63cfe6e1ec51f", type_checked_symbol_table = "056ebc268a7f7adf3aa336e21ded11d39f2c1eca00a1b675fe1622c7b92704ad", unrolled_symbol_table = "056ebc268a7f7adf3aa336e21ded11d39f2c1eca00a1b675fe1622c7b92704ad", initial_ast = "575e251f07e552c917ab36bc9877b13dd1638651c4023ade20701dd2a5fe27ff", unrolled_ast = "2a4969ad315e900b5a3f1eecd4e6508dc6946fb5f6c3861ee793961ce6bcc203", ssa_ast = "4a00e3d36cdd4ff4be1fc6a389aaf17cfb02b6c54fa84276fb5be66b8a78b124", flattened_ast = "885c5f8145aa1a82e5fe41abbabae12cbd15eb014b333b246c6c5401b5b6bfea", destructured_ast = "f3b5b961a498f9befec85b69b3012145a6e97774d37a8c8e354ec4e5eeb64f84", inlined_ast = "2bf37fc499b3eca18c8227e61f69f730d36e755d7879dde13bb9161936bafbfc", dce_ast = "390391c2098cf6a910eeec98fc92fdea31303a84a1d6fd6673c8dbd9d20180de", bytecode = """ import test_dep.aleo; import test.aleo; import wrapper.aleo; diff --git a/tests/expectations/compiler/tuple/tuple_in_function_param.out b/tests/expectations/compiler/tuple/tuple_in_function_param.out index b735f9876c..3cd3c2d082 100644 --- a/tests/expectations/compiler/tuple/tuple_in_function_param.out +++ b/tests/expectations/compiler/tuple/tuple_in_function_param.out @@ -5,5 +5,5 @@ Error [ETYC0372051]: A function cannot take in a tuple as input. --> compiler-test:4:20 | 4 | transition foo(a: (u8, u16)) -> (u8, u16) { - | ^ + | ^^^^^^^^^^^^ """] diff --git a/tests/expectations/compiler/tuple/tuple_not_allowed_fail.out b/tests/expectations/compiler/tuple/tuple_not_allowed_fail.out index 0711e695a0..b8bb0647fe 100644 --- a/tests/expectations/compiler/tuple/tuple_not_allowed_fail.out +++ b/tests/expectations/compiler/tuple/tuple_not_allowed_fail.out @@ -10,7 +10,7 @@ Error [ETYC0372051]: A function cannot take in a tuple as input. --> compiler-test:8:18 | 8 | function foo(a: (u8, u16)) -> (u8, u16) { - | ^ + | ^^^^^^^^^^^^ Error [ETYC0372049]: A tuple type cannot contain a tuple. --> compiler-test:12:36 | diff --git a/tests/expectations/execution/complex_finalization.out b/tests/expectations/execution/complex_finalization.out index dc04912086..45eeaadea9 100644 --- a/tests/expectations/execution/complex_finalization.out +++ b/tests/expectations/execution/complex_finalization.out @@ -60,7 +60,7 @@ finalize b: add r3 1u64 into r4; set r4 into counts[r2]; """, errors = "", warnings = "" }, - { initial_symbol_table = "ee9c47b21aa811094b66a4cef0eef7af32effb924a2f514094b5280b4d611987", type_checked_symbol_table = "bf3047bd773d692e484ef3bddcaca86ffc8c897f658afe2f85cb592c4b856ca3", unrolled_symbol_table = "bf3047bd773d692e484ef3bddcaca86ffc8c897f658afe2f85cb592c4b856ca3", initial_ast = "387aba043fde6ead4d99bf4eb5c817051491a7d16aecd6383411e3cbc6aaefd5", unrolled_ast = "f93e4fd19542c5af01a5e0aec60e9f6265491a0952cafabfb7cdcfac00bd81b9", ssa_ast = "0ad477f1c1bc42ebcd4098caf856428e5be9a0845972cbd2908dcf53c6ce45a0", flattened_ast = "3fa8070cfe4be62533fb8b3d899c490f940686a97ae01ee0c8f6f7743527d726", destructured_ast = "5407ddb3a931cde7e50dc466557108fde8f6ebfd8d446cdb44855542208f4056", inlined_ast = "8accc3977c89a2e948b39f6abc2c7f989e52313aac237bcb25469e4bc91fc4f1", dce_ast = "8accc3977c89a2e948b39f6abc2c7f989e52313aac237bcb25469e4bc91fc4f1", bytecode = """ + { initial_symbol_table = "ee9c47b21aa811094b66a4cef0eef7af32effb924a2f514094b5280b4d611987", type_checked_symbol_table = "2d8e0167d05b2b689c8464c1eacb5947a7a30c36892eb5debe6692f948a18c88", unrolled_symbol_table = "2d8e0167d05b2b689c8464c1eacb5947a7a30c36892eb5debe6692f948a18c88", initial_ast = "387aba043fde6ead4d99bf4eb5c817051491a7d16aecd6383411e3cbc6aaefd5", unrolled_ast = "f93e4fd19542c5af01a5e0aec60e9f6265491a0952cafabfb7cdcfac00bd81b9", ssa_ast = "0ad477f1c1bc42ebcd4098caf856428e5be9a0845972cbd2908dcf53c6ce45a0", flattened_ast = "3fa8070cfe4be62533fb8b3d899c490f940686a97ae01ee0c8f6f7743527d726", destructured_ast = "5407ddb3a931cde7e50dc466557108fde8f6ebfd8d446cdb44855542208f4056", inlined_ast = "8accc3977c89a2e948b39f6abc2c7f989e52313aac237bcb25469e4bc91fc4f1", dce_ast = "8accc3977c89a2e948b39f6abc2c7f989e52313aac237bcb25469e4bc91fc4f1", bytecode = """ import zero_program.aleo; import one_program.aleo; import two_program.aleo; @@ -89,7 +89,7 @@ finalize e: add r4 1u64 into r5; set r5 into counts[r3]; """, errors = "", warnings = "" }, - { initial_symbol_table = "044526dfe3dfe09fde9004db01d837c5fe566d508d6a6045b8b64c6921179e15", type_checked_symbol_table = "ad633121ad08786628d1ddd39eddae1004962f1f6dcb2370179c751fd460fcfe", unrolled_symbol_table = "ad633121ad08786628d1ddd39eddae1004962f1f6dcb2370179c751fd460fcfe", initial_ast = "f731cdda879e0134eb5b1cf0d64d3cf5abbee2fd2ce758d3afac05ee07fb885f", unrolled_ast = "79017a53e402d0c7aad500a44936f4e06e418407b4a2b40f2bf69a185c4865c0", ssa_ast = "8a4f2ea8f8118515b8843aad5a201824dc2c6b06046f68698dde622f5ace3c4f", flattened_ast = "35f966d0d86e1e38c2c6650d83e62d701a9b9440766b78919ee0b509c3255cf7", destructured_ast = "5677314a7b55bf523441d3c40029daedf97666fb7821159b0c88654776ea2932", inlined_ast = "9c779149583480acdca132daad34c2577ec0d09e28c36b11ecf91beb556cc7b5", dce_ast = "9c779149583480acdca132daad34c2577ec0d09e28c36b11ecf91beb556cc7b5", bytecode = """ + { initial_symbol_table = "044526dfe3dfe09fde9004db01d837c5fe566d508d6a6045b8b64c6921179e15", type_checked_symbol_table = "7ccfd2a1cc75ab982ad84ed7401f7a744d99206145a4962130608634686f7cac", unrolled_symbol_table = "7ccfd2a1cc75ab982ad84ed7401f7a744d99206145a4962130608634686f7cac", initial_ast = "f731cdda879e0134eb5b1cf0d64d3cf5abbee2fd2ce758d3afac05ee07fb885f", unrolled_ast = "79017a53e402d0c7aad500a44936f4e06e418407b4a2b40f2bf69a185c4865c0", ssa_ast = "8a4f2ea8f8118515b8843aad5a201824dc2c6b06046f68698dde622f5ace3c4f", flattened_ast = "35f966d0d86e1e38c2c6650d83e62d701a9b9440766b78919ee0b509c3255cf7", destructured_ast = "5677314a7b55bf523441d3c40029daedf97666fb7821159b0c88654776ea2932", inlined_ast = "9c779149583480acdca132daad34c2577ec0d09e28c36b11ecf91beb556cc7b5", dce_ast = "9c779149583480acdca132daad34c2577ec0d09e28c36b11ecf91beb556cc7b5", bytecode = """ import zero_program.aleo; import one_program.aleo; import two_program.aleo; diff --git a/tests/expectations/parser/finalize/finalize.out b/tests/expectations/parser/finalize/finalize.out index 2cd67f7cf2..7ab35c030c 100644 --- a/tests/expectations/parser/finalize/finalize.out +++ b/tests/expectations/parser/finalize/finalize.out @@ -28,8 +28,8 @@ functions = [ [ "main", { annotations = [], variant = "AsyncFunction", identifier = '{"id":"13","name":"main","span":"{\"lo\":193,\"hi\":197}"}', id = 23, input = [ - { identifier = '{"id":"14","name":"a","span":"{\"lo\":198,\"hi\":199}"}', mode = "None", id = 16, type_ = { Composite = { id = '{"id":"15","name":"foo","span":"{\"lo\":201,\"hi\":204}"}', program = "test" } }, span = { lo = 198, hi = 199 } }, - { identifier = '{"id":"17","name":"b","span":"{\"lo\":206,\"hi\":207}"}', mode = "None", id = 19, type_ = { Composite = { id = '{"id":"18","name":"bar","span":"{\"lo\":209,\"hi\":212}"}', program = "test" } }, span = { lo = 206, hi = 207 } }, + { identifier = '{"id":"14","name":"a","span":"{\"lo\":198,\"hi\":199}"}', mode = "None", id = 16, type_ = { Composite = { id = '{"id":"15","name":"foo","span":"{\"lo\":201,\"hi\":204}"}', program = "test" } }, span = { lo = 198, hi = 204 } }, + { identifier = '{"id":"17","name":"b","span":"{\"lo\":206,\"hi\":207}"}', mode = "None", id = 19, type_ = { Composite = { id = '{"id":"18","name":"bar","span":"{\"lo\":209,\"hi\":212}"}', program = "test" } }, span = { lo = 206, hi = 212 } }, ], output = [{ mode = "None", id = 21, type_ = { Composite = { id = '{"id":"20","name":"baz","span":"{\"lo\":217,\"hi\":220}"}', program = "test" } }, span = { lo = 217, hi = 220 } }], output_type = { Composite = { id = '{"id":"20","name":"baz","span":"{\"lo\":217,\"hi\":220}"}', program = "test" } }, block = { statements = [], id = 22, span = { lo = 221, hi = 233 } }, span = { lo = 178, hi = 233 } }, ], ] diff --git a/tests/expectations/parser/functions/bounded_recursion.out b/tests/expectations/parser/functions/bounded_recursion.out index 655d7e66d5..0ca5264ebb 100644 --- a/tests/expectations/parser/functions/bounded_recursion.out +++ b/tests/expectations/parser/functions/bounded_recursion.out @@ -15,7 +15,7 @@ mappings = [] functions = [ [ "x", - { annotations = [], variant = "Function", identifier = '{"id":"2","name":"x","span":"{\"lo\":39,\"hi\":40}"}', id = 18, input = [{ identifier = '{"id":"3","name":"y","span":"{\"lo\":50,\"hi\":51}"}', mode = "Constant", id = 4, type_ = { Integer = "U32" }, span = { lo = 50, hi = 51 } }], output = [{ mode = "None", id = 5, type_ = { Integer = "U8" }, span = { lo = 61, hi = 63 } }], output_type = { Integer = "U8" }, block = { id = 17, statements = [{ Conditional = { id = 16, condition = { Binary = { op = "Lt", id = 8, left = { Identifier = '{"id":"6","name":"y","span":"{\"lo\":77,\"hi\":78}"}' }, right = { Literal = { Integer = [ + { annotations = [], variant = "Function", identifier = '{"id":"2","name":"x","span":"{\"lo\":39,\"hi\":40}"}', id = 18, input = [{ identifier = '{"id":"3","name":"y","span":"{\"lo\":50,\"hi\":51}"}', mode = "Constant", id = 4, type_ = { Integer = "U32" }, span = { lo = 50, hi = 56 } }], output = [{ mode = "None", id = 5, type_ = { Integer = "U8" }, span = { lo = 61, hi = 63 } }], output_type = { Integer = "U8" }, block = { id = 17, statements = [{ Conditional = { id = 16, condition = { Binary = { op = "Lt", id = 8, left = { Identifier = '{"id":"6","name":"y","span":"{\"lo\":77,\"hi\":78}"}' }, right = { Literal = { Integer = [ "U32", "5", { span = { lo = 81, hi = 85 } }, @@ -29,7 +29,7 @@ functions = [ ], [ "main", - { annotations = [], variant = "Function", identifier = '{"id":"19","name":"main","span":"{\"lo\":145,\"hi\":149}"}', output_type = "Boolean", id = 30, input = [{ identifier = '{"id":"20","name":"y","span":"{\"lo\":150,\"hi\":151}"}', mode = "None", type_ = "Boolean", id = 21, span = { lo = 150, hi = 151 } }], output = [{ mode = "None", type_ = "Boolean", id = 22, span = { lo = 162, hi = 166 } }], block = { id = 29, statements = [ + { annotations = [], variant = "Function", identifier = '{"id":"19","name":"main","span":"{\"lo\":145,\"hi\":149}"}', output_type = "Boolean", id = 30, input = [{ identifier = '{"id":"20","name":"y","span":"{\"lo\":150,\"hi\":151}"}', mode = "None", type_ = "Boolean", id = 21, span = { lo = 150, hi = 157 } }], output = [{ mode = "None", type_ = "Boolean", id = 22, span = { lo = 162, hi = 166 } }], block = { id = 29, statements = [ { Expression = { id = 26, expression = { Call = { program = "test", id = 25, arguments = [{ Literal = { Integer = [ "U32", "1", diff --git a/tests/expectations/parser/functions/const_param.out b/tests/expectations/parser/functions/const_param.out index 0fec13c8a4..a48d6cba76 100644 --- a/tests/expectations/parser/functions/const_param.out +++ b/tests/expectations/parser/functions/const_param.out @@ -16,8 +16,8 @@ functions = [ [ "x", { annotations = [], variant = "Function", identifier = '{"id":"2","name":"x","span":"{\"lo\":39,\"hi\":40}"}', id = 11, input = [ - { identifier = '{"id":"3","name":"x","span":"{\"lo\":41,\"hi\":42}"}', mode = "None", id = 4, type_ = { Integer = "U32" }, span = { lo = 41, hi = 42 } }, - { identifier = '{"id":"5","name":"y","span":"{\"lo\":58,\"hi\":59}"}', mode = "Constant", id = 6, type_ = { Integer = "I32" }, span = { lo = 58, hi = 59 } }, + { identifier = '{"id":"3","name":"x","span":"{\"lo\":41,\"hi\":42}"}', mode = "None", id = 4, type_ = { Integer = "U32" }, span = { lo = 41, hi = 47 } }, + { identifier = '{"id":"5","name":"y","span":"{\"lo\":58,\"hi\":59}"}', mode = "Constant", id = 6, type_ = { Integer = "I32" }, span = { lo = 58, hi = 64 } }, ], output = [{ mode = "None", id = 7, type_ = { Integer = "U8" }, span = { lo = 69, hi = 71 } }], output_type = { Integer = "U8" }, block = { id = 10, statements = [{ Return = { id = 9, expression = { Literal = { Integer = [ "U8", "0", @@ -28,8 +28,8 @@ functions = [ [ "x", { annotations = [], variant = "Function", identifier = '{"id":"12","name":"x","span":"{\"lo\":118,\"hi\":119}"}', id = 21, input = [ - { identifier = '{"id":"13","name":"x","span":"{\"lo\":129,\"hi\":130}"}', mode = "Constant", id = 14, type_ = { Integer = "U32" }, span = { lo = 129, hi = 130 } }, - { identifier = '{"id":"15","name":"y","span":"{\"lo\":137,\"hi\":138}"}', mode = "None", id = 16, type_ = { Integer = "I32" }, span = { lo = 137, hi = 138 } }, + { identifier = '{"id":"13","name":"x","span":"{\"lo\":129,\"hi\":130}"}', mode = "Constant", id = 14, type_ = { Integer = "U32" }, span = { lo = 129, hi = 135 } }, + { identifier = '{"id":"15","name":"y","span":"{\"lo\":137,\"hi\":138}"}', mode = "None", id = 16, type_ = { Integer = "I32" }, span = { lo = 137, hi = 143 } }, ], output = [{ mode = "None", id = 17, type_ = { Integer = "U8" }, span = { lo = 148, hi = 150 } }], output_type = { Integer = "U8" }, block = { id = 20, statements = [{ Return = { id = 19, expression = { Literal = { Integer = [ "U8", "0", diff --git a/tests/expectations/parser/functions/constant_input.out b/tests/expectations/parser/functions/constant_input.out index 26778a1f31..adc4d740a1 100644 --- a/tests/expectations/parser/functions/constant_input.out +++ b/tests/expectations/parser/functions/constant_input.out @@ -14,7 +14,7 @@ structs = [] mappings = [] functions = [[ "x", - { annotations = [], variant = "Function", identifier = '{"id":"2","name":"x","span":"{\"lo\":39,\"hi\":40}"}', id = 7, input = [{ identifier = '{"id":"3","name":"x","span":"{\"lo\":50,\"hi\":51}"}', mode = "Constant", id = 4, type_ = { Integer = "U8" }, span = { lo = 50, hi = 51 } }], output = [{ mode = "None", id = 5, type_ = { Integer = "U8" }, span = { lo = 60, hi = 62 } }], output_type = { Integer = "U8" }, block = { statements = [], id = 6, span = { lo = 63, hi = 65 } }, span = { lo = 30, hi = 65 } }, + { annotations = [], variant = "Function", identifier = '{"id":"2","name":"x","span":"{\"lo\":39,\"hi\":40}"}', id = 7, input = [{ identifier = '{"id":"3","name":"x","span":"{\"lo\":50,\"hi\":51}"}', mode = "Constant", id = 4, type_ = { Integer = "U8" }, span = { lo = 50, hi = 55 } }], output = [{ mode = "None", id = 5, type_ = { Integer = "U8" }, span = { lo = 60, hi = 62 } }], output_type = { Integer = "U8" }, block = { statements = [], id = 6, span = { lo = 63, hi = 65 } }, span = { lo = 30, hi = 65 } }, ]] [outputs.program_scopes.test.span] diff --git a/tests/expectations/parser/functions/infinite_recursion.out b/tests/expectations/parser/functions/infinite_recursion.out index 7f3875898d..f59db073a4 100644 --- a/tests/expectations/parser/functions/infinite_recursion.out +++ b/tests/expectations/parser/functions/infinite_recursion.out @@ -19,7 +19,7 @@ functions = [ ], [ "main", - { annotations = [], variant = "Function", identifier = '{"id":"9","name":"main","span":"{\"lo\":92,\"hi\":96}"}', output_type = "Boolean", id = 19, input = [{ identifier = '{"id":"10","name":"y","span":"{\"lo\":97,\"hi\":98}"}', mode = "None", type_ = "Boolean", id = 11, span = { lo = 97, hi = 98 } }], output = [{ mode = "None", type_ = "Boolean", id = 12, span = { lo = 109, hi = 113 } }], block = { id = 18, statements = [ + { annotations = [], variant = "Function", identifier = '{"id":"9","name":"main","span":"{\"lo\":92,\"hi\":96}"}', output_type = "Boolean", id = 19, input = [{ identifier = '{"id":"10","name":"y","span":"{\"lo\":97,\"hi\":98}"}', mode = "None", type_ = "Boolean", id = 11, span = { lo = 97, hi = 104 } }], output = [{ mode = "None", type_ = "Boolean", id = 12, span = { lo = 109, hi = 113 } }], block = { id = 18, statements = [ { Expression = { id = 15, expression = { Call = { arguments = [], program = "test", id = 14, function = { Identifier = '{"id":"13","name":"inf","span":"{\"lo\":124,\"hi\":127}"}' }, span = { lo = 124, hi = 129 } } }, span = { lo = 124, hi = 130 } } }, { Return = { id = 17, expression = { Identifier = '{"id":"16","name":"y","span":"{\"lo\":146,\"hi\":147}"}' }, span = { lo = 139, hi = 148 } } }, ], span = { lo = 114, hi = 154 } }, span = { lo = 83, hi = 154 } }, diff --git a/tests/expectations/parser/functions/inline_function.out b/tests/expectations/parser/functions/inline_function.out index bfcf3be574..55eeb9ffe3 100644 --- a/tests/expectations/parser/functions/inline_function.out +++ b/tests/expectations/parser/functions/inline_function.out @@ -15,8 +15,8 @@ mappings = [] functions = [[ "foo", { annotations = [], variant = "Inline", identifier = '{"id":"2","name":"foo","span":"{\"lo\":33,\"hi\":36}"}', id = 11, input = [ - { identifier = '{"id":"3","name":"x","span":"{\"lo\":37,\"hi\":38}"}', mode = "None", id = 4, type_ = { Integer = "U32" }, span = { lo = 37, hi = 38 } }, - { identifier = '{"id":"5","name":"y","span":"{\"lo\":45,\"hi\":46}"}', mode = "None", id = 6, type_ = { Integer = "I32" }, span = { lo = 45, hi = 46 } }, + { identifier = '{"id":"3","name":"x","span":"{\"lo\":37,\"hi\":38}"}', mode = "None", id = 4, type_ = { Integer = "U32" }, span = { lo = 37, hi = 43 } }, + { identifier = '{"id":"5","name":"y","span":"{\"lo\":45,\"hi\":46}"}', mode = "None", id = 6, type_ = { Integer = "I32" }, span = { lo = 45, hi = 51 } }, ], output = [{ mode = "None", id = 7, type_ = { Integer = "U32" }, span = { lo = 56, hi = 59 } }], output_type = { Integer = "U32" }, block = { id = 10, statements = [{ Return = { id = 9, expression = { Literal = { Integer = [ "U32", "0", diff --git a/tests/expectations/parser/functions/params.out b/tests/expectations/parser/functions/params.out index caf146ef80..35a937bab7 100644 --- a/tests/expectations/parser/functions/params.out +++ b/tests/expectations/parser/functions/params.out @@ -15,8 +15,8 @@ mappings = [] functions = [[ "x", { annotations = [], variant = "Function", identifier = '{"id":"2","name":"x","span":"{\"lo\":39,\"hi\":40}"}', id = 11, input = [ - { identifier = '{"id":"3","name":"x","span":"{\"lo\":41,\"hi\":42}"}', mode = "None", id = 4, type_ = { Integer = "U32" }, span = { lo = 41, hi = 42 } }, - { identifier = '{"id":"5","name":"y","span":"{\"lo\":49,\"hi\":50}"}', mode = "None", id = 6, type_ = { Integer = "I32" }, span = { lo = 49, hi = 50 } }, + { identifier = '{"id":"3","name":"x","span":"{\"lo\":41,\"hi\":42}"}', mode = "None", id = 4, type_ = { Integer = "U32" }, span = { lo = 41, hi = 47 } }, + { identifier = '{"id":"5","name":"y","span":"{\"lo\":49,\"hi\":50}"}', mode = "None", id = 6, type_ = { Integer = "I32" }, span = { lo = 49, hi = 55 } }, ], output = [{ mode = "None", id = 7, type_ = { Integer = "U8" }, span = { lo = 60, hi = 62 } }], output_type = { Integer = "U8" }, block = { id = 10, statements = [{ Return = { id = 9, expression = { Literal = { Integer = [ "U8", "0", diff --git a/tests/expectations/parser/functions/params_return.out b/tests/expectations/parser/functions/params_return.out index f4363bc3ac..be8d76a552 100644 --- a/tests/expectations/parser/functions/params_return.out +++ b/tests/expectations/parser/functions/params_return.out @@ -15,8 +15,8 @@ mappings = [] functions = [[ "x", { annotations = [], variant = "Function", identifier = '{"id":"2","name":"x","span":"{\"lo\":39,\"hi\":40}"}', id = 11, input = [ - { identifier = '{"id":"3","name":"x","span":"{\"lo\":41,\"hi\":42}"}', mode = "None", id = 4, type_ = { Integer = "U32" }, span = { lo = 41, hi = 42 } }, - { identifier = '{"id":"5","name":"y","span":"{\"lo\":49,\"hi\":50}"}', mode = "None", id = 6, type_ = { Integer = "I32" }, span = { lo = 49, hi = 50 } }, + { identifier = '{"id":"3","name":"x","span":"{\"lo\":41,\"hi\":42}"}', mode = "None", id = 4, type_ = { Integer = "U32" }, span = { lo = 41, hi = 47 } }, + { identifier = '{"id":"5","name":"y","span":"{\"lo\":49,\"hi\":50}"}', mode = "None", id = 6, type_ = { Integer = "I32" }, span = { lo = 49, hi = 55 } }, ], output = [{ mode = "None", id = 7, type_ = { Integer = "U32" }, span = { lo = 60, hi = 63 } }], output_type = { Integer = "U32" }, block = { id = 10, statements = [{ Return = { id = 9, expression = { Literal = { Integer = [ "U8", "0", diff --git a/tests/expectations/parser/functions/public_param.out b/tests/expectations/parser/functions/public_param.out index 5c4413e6a2..417f1570a7 100644 --- a/tests/expectations/parser/functions/public_param.out +++ b/tests/expectations/parser/functions/public_param.out @@ -16,8 +16,8 @@ functions = [ [ "x", { annotations = [], variant = "Function", identifier = '{"id":"2","name":"x","span":"{\"lo\":39,\"hi\":40}"}', id = 11, input = [ - { identifier = '{"id":"3","name":"x","span":"{\"lo\":41,\"hi\":42}"}', mode = "None", id = 4, type_ = { Integer = "U32" }, span = { lo = 41, hi = 42 } }, - { identifier = '{"id":"5","name":"y","span":"{\"lo\":56,\"hi\":57}"}', mode = "Public", id = 6, type_ = { Integer = "I32" }, span = { lo = 56, hi = 57 } }, + { identifier = '{"id":"3","name":"x","span":"{\"lo\":41,\"hi\":42}"}', mode = "None", id = 4, type_ = { Integer = "U32" }, span = { lo = 41, hi = 47 } }, + { identifier = '{"id":"5","name":"y","span":"{\"lo\":56,\"hi\":57}"}', mode = "Public", id = 6, type_ = { Integer = "I32" }, span = { lo = 56, hi = 62 } }, ], output = [{ mode = "None", id = 7, type_ = { Integer = "U8" }, span = { lo = 67, hi = 69 } }], output_type = { Integer = "U8" }, block = { id = 10, statements = [{ Return = { id = 9, expression = { Literal = { Integer = [ "U8", "0", @@ -28,8 +28,8 @@ functions = [ [ "x", { annotations = [], variant = "Function", identifier = '{"id":"12","name":"x","span":"{\"lo\":116,\"hi\":117}"}', id = 21, input = [ - { identifier = '{"id":"13","name":"x","span":"{\"lo\":125,\"hi\":126}"}', mode = "Public", id = 14, type_ = { Integer = "U32" }, span = { lo = 125, hi = 126 } }, - { identifier = '{"id":"15","name":"y","span":"{\"lo\":133,\"hi\":134}"}', mode = "None", id = 16, type_ = { Integer = "I32" }, span = { lo = 133, hi = 134 } }, + { identifier = '{"id":"13","name":"x","span":"{\"lo\":125,\"hi\":126}"}', mode = "Public", id = 14, type_ = { Integer = "U32" }, span = { lo = 125, hi = 131 } }, + { identifier = '{"id":"15","name":"y","span":"{\"lo\":133,\"hi\":134}"}', mode = "None", id = 16, type_ = { Integer = "I32" }, span = { lo = 133, hi = 139 } }, ], output = [{ mode = "None", id = 17, type_ = { Integer = "U8" }, span = { lo = 144, hi = 146 } }], output_type = { Integer = "U8" }, block = { id = 20, statements = [{ Return = { id = 19, expression = { Literal = { Integer = [ "U8", "0", diff --git a/tests/expectations/parser/functions/transition_function.out b/tests/expectations/parser/functions/transition_function.out index 93cfc1c88e..f89e8a9003 100644 --- a/tests/expectations/parser/functions/transition_function.out +++ b/tests/expectations/parser/functions/transition_function.out @@ -15,8 +15,8 @@ mappings = [] functions = [[ "foo", { annotations = [], variant = "Transition", identifier = '{"id":"2","name":"foo","span":"{\"lo\":37,\"hi\":40}"}', id = 11, input = [ - { identifier = '{"id":"3","name":"x","span":"{\"lo\":41,\"hi\":42}"}', mode = "None", id = 4, type_ = { Integer = "U32" }, span = { lo = 41, hi = 42 } }, - { identifier = '{"id":"5","name":"y","span":"{\"lo\":49,\"hi\":50}"}', mode = "None", id = 6, type_ = { Integer = "I32" }, span = { lo = 49, hi = 50 } }, + { identifier = '{"id":"3","name":"x","span":"{\"lo\":41,\"hi\":42}"}', mode = "None", id = 4, type_ = { Integer = "U32" }, span = { lo = 41, hi = 47 } }, + { identifier = '{"id":"5","name":"y","span":"{\"lo\":49,\"hi\":50}"}', mode = "None", id = 6, type_ = { Integer = "I32" }, span = { lo = 49, hi = 55 } }, ], output = [{ mode = "None", id = 7, type_ = { Integer = "U32" }, span = { lo = 60, hi = 63 } }], output_type = { Integer = "U32" }, block = { id = 10, statements = [{ Return = { id = 9, expression = { Literal = { Integer = [ "U32", "0", diff --git a/tests/expectations/parser/future/explicit_future_typing.out b/tests/expectations/parser/future/explicit_future_typing.out index a93226c0fa..5899def04c 100644 --- a/tests/expectations/parser/future/explicit_future_typing.out +++ b/tests/expectations/parser/future/explicit_future_typing.out @@ -79,16 +79,16 @@ functions = [ [ "finalize_main", { annotations = [], variant = "AsyncFunction", identifier = '{"id":"26","name":"finalize_main","span":"{\"lo\":426,\"hi\":439}"}', output = [], output_type = "Unit", id = 49, input = [ - { identifier = '{"id":"27","name":"a","span":"{\"lo\":440,\"hi\":441}"}', mode = "None", id = 28, type_ = { Integer = "U32" }, span = { lo = 440, hi = 441 } }, - { identifier = '{"id":"29","name":"b","span":"{\"lo\":448,\"hi\":449}"}', mode = "None", id = 30, type_ = { Integer = "U32" }, span = { lo = 448, hi = 449 } }, - { identifier = '{"id":"31","name":"f0","span":"{\"lo\":456,\"hi\":458}"}', mode = "None", id = 32, type_ = { Future = { inputs = [], is_explicit = true } }, span = { lo = 456, hi = 458 } }, + { identifier = '{"id":"27","name":"a","span":"{\"lo\":440,\"hi\":441}"}', mode = "None", id = 28, type_ = { Integer = "U32" }, span = { lo = 440, hi = 446 } }, + { identifier = '{"id":"29","name":"b","span":"{\"lo\":448,\"hi\":449}"}', mode = "None", id = 30, type_ = { Integer = "U32" }, span = { lo = 448, hi = 454 } }, + { identifier = '{"id":"31","name":"f0","span":"{\"lo\":456,\"hi\":458}"}', mode = "None", id = 32, type_ = { Future = { inputs = [], is_explicit = true } }, span = { lo = 456, hi = 471 } }, { identifier = '{"id":"33","name":"f1","span":"{\"lo\":474,\"hi\":476}"}', mode = "None", id = 34, type_ = { Future = { is_explicit = true, inputs = [ { Integer = "U32" }, { Future = { is_explicit = true, inputs = [ { Integer = "U32" }, { Integer = "U32" }, ] } }, -] } }, span = { lo = 474, hi = 476 } }, +] } }, span = { lo = 474, hi = 514 } }, ], block = { id = 48, statements = [ { Expression = { id = 39, expression = { Access = { AssociatedFunction = { variant = '{"id":"37","name":"Future","span":"{\"lo\":0,\"hi\":0}"}', name = '{"id":"36","name":"await","span":"{\"lo\":530,\"hi\":535}"}', id = 38, arguments = [{ Identifier = '{"id":"35","name":"f0","span":"{\"lo\":527,\"hi\":529}"}' }], span = { lo = 527, hi = 537 } } } }, span = { lo = 527, hi = 538 } } }, { Expression = { id = 44, expression = { Access = { AssociatedFunction = { variant = '{"id":"42","name":"Future","span":"{\"lo\":0,\"hi\":0}"}', name = '{"id":"41","name":"await","span":"{\"lo\":550,\"hi\":555}"}', id = 43, arguments = [{ Identifier = '{"id":"40","name":"f1","span":"{\"lo\":547,\"hi\":549}"}' }], span = { lo = 547, hi = 557 } } } }, span = { lo = 547, hi = 558 } } }, diff --git a/tests/expectations/parser/program/async_basic.out b/tests/expectations/parser/program/async_basic.out index ff3effce84..5c8307160a 100644 --- a/tests/expectations/parser/program/async_basic.out +++ b/tests/expectations/parser/program/async_basic.out @@ -39,8 +39,8 @@ functions = [ [ "finalize_main", { annotations = [], variant = "AsyncFunction", identifier = '{"id":"16","name":"finalize_main","span":"{\"lo\":186,\"hi\":199}"}', id = 30, input = [ - { identifier = '{"id":"17","name":"a","span":"{\"lo\":200,\"hi\":201}"}', mode = "None", id = 18, type_ = { Integer = "U32" }, span = { lo = 200, hi = 201 } }, - { identifier = '{"id":"19","name":"b","span":"{\"lo\":207,\"hi\":208}"}', mode = "None", id = 20, type_ = { Integer = "U32" }, span = { lo = 207, hi = 208 } }, + { identifier = '{"id":"17","name":"a","span":"{\"lo\":200,\"hi\":201}"}', mode = "None", id = 18, type_ = { Integer = "U32" }, span = { lo = 200, hi = 205 } }, + { identifier = '{"id":"19","name":"b","span":"{\"lo\":207,\"hi\":208}"}', mode = "None", id = 20, type_ = { Integer = "U32" }, span = { lo = 207, hi = 212 } }, ], output = [{ mode = "None", id = 21, type_ = { Future = { inputs = [], is_explicit = false } }, span = { lo = 217, hi = 223 } }], output_type = { Future = { inputs = [], is_explicit = false } }, block = { id = 29, statements = [{ Expression = { id = 28, expression = { Access = { AssociatedFunction = { variant = '{"id":"22","name":"Mapping","span":"{\"lo\":234,\"hi\":241}"}', name = '{"id":"23","name":"set","span":"{\"lo\":243,\"hi\":246}"}', id = 27, arguments = [ { Identifier = '{"id":"24","name":"Yo","span":"{\"lo\":247,\"hi\":249}"}' }, { Identifier = '{"id":"25","name":"a","span":"{\"lo\":251,\"hi\":252}"}' }, diff --git a/tests/expectations/parser/program/network_id.out b/tests/expectations/parser/program/network_id.out index b9ccf598c3..2baad6cbbf 100644 --- a/tests/expectations/parser/program/network_id.out +++ b/tests/expectations/parser/program/network_id.out @@ -14,7 +14,7 @@ structs = [] mappings = [] functions = [[ "main", - { annotations = [], variant = "Function", identifier = '{"id":"2","name":"main","span":"{\"lo\":34,\"hi\":38}"}', output = [], output_type = "Unit", id = 13, input = [{ identifier = '{"id":"3","name":"a","span":"{\"lo\":39,\"hi\":40}"}', mode = "None", type_ = "Address", id = 4, span = { lo = 39, hi = 40 } }], block = { id = 12, statements = [ + { annotations = [], variant = "Function", identifier = '{"id":"2","name":"main","span":"{\"lo\":34,\"hi\":38}"}', output = [], output_type = "Unit", id = 13, input = [{ identifier = '{"id":"3","name":"a","span":"{\"lo\":39,\"hi\":40}"}', mode = "None", type_ = "Address", id = 4, span = { lo = 39, hi = 49 } }], block = { id = 12, statements = [ { Assert = { id = 9, variant = { AssertEq = [ { Access = { Member = { name = '{"id":"6","name":"id","span":"{\"lo\":79,\"hi\":81}"}', id = 7, inner = { Identifier = '{"id":"5","name":"network","span":"{\"lo\":71,\"hi\":78}"}' }, span = { lo = 71, hi = 81 } } } }, { Literal = { Integer = [ diff --git a/tests/expectations/parser/program/special_address.out b/tests/expectations/parser/program/special_address.out index 8924e6940a..36f4f220d8 100644 --- a/tests/expectations/parser/program/special_address.out +++ b/tests/expectations/parser/program/special_address.out @@ -17,7 +17,7 @@ mappings = [[ ]] functions = [[ "main", - { annotations = [], variant = "Transition", identifier = '{"id":"4","name":"main","span":"{\"lo\":70,\"hi\":74}"}', output = [], output_type = "Unit", id = 24, input = [{ identifier = '{"id":"5","name":"a","span":"{\"lo\":75,\"hi\":76}"}', mode = "None", type_ = "Address", id = 6, span = { lo = 75, hi = 76 } }], block = { id = 23, statements = [ + { annotations = [], variant = "Transition", identifier = '{"id":"4","name":"main","span":"{\"lo\":70,\"hi\":74}"}', output = [], output_type = "Unit", id = 24, input = [{ identifier = '{"id":"5","name":"a","span":"{\"lo\":75,\"hi\":76}"}', mode = "None", type_ = "Address", id = 6, span = { lo = 75, hi = 85 } }], block = { id = 23, statements = [ { Assert = { id = 11, variant = { AssertEq = [ { Identifier = '{"id":"7","name":"a","span":"{\"lo\":107,\"hi\":108}"}' }, { Access = { Member = { name = '{"id":"9","name":"caller","span":"{\"lo\":115,\"hi\":121}"}', id = 10, inner = { Identifier = '{"id":"8","name":"self","span":"{\"lo\":110,\"hi\":114}"}' }, span = { lo = 110, hi = 121 } } } }, diff --git a/tests/expectations/parser/type_/signature.out b/tests/expectations/parser/type_/signature.out index e36afb3cb1..bda7d3c80d 100644 --- a/tests/expectations/parser/type_/signature.out +++ b/tests/expectations/parser/type_/signature.out @@ -16,9 +16,9 @@ functions = [ [ "baz", { annotations = [], variant = "Transition", identifier = '{"id":"2","name":"baz","span":"{\"lo\":37,\"hi\":40}"}', output = [], output_type = "Unit", id = 30, input = [ - { identifier = '{"id":"3","name":"s","span":"{\"lo\":41,\"hi\":42}"}', mode = "None", type_ = "Signature", id = 4, span = { lo = 41, hi = 42 } }, - { identifier = '{"id":"5","name":"a","span":"{\"lo\":55,\"hi\":56}"}', mode = "None", type_ = "Address", id = 6, span = { lo = 55, hi = 56 } }, - { identifier = '{"id":"7","name":"v","span":"{\"lo\":67,\"hi\":68}"}', mode = "None", id = 9, type_ = { Composite = { id = '{"id":"8","name":"value","span":"{\"lo\":70,\"hi\":75}"}', program = "test" } }, span = { lo = 67, hi = 68 } }, + { identifier = '{"id":"3","name":"s","span":"{\"lo\":41,\"hi\":42}"}', mode = "None", type_ = "Signature", id = 4, span = { lo = 41, hi = 53 } }, + { identifier = '{"id":"5","name":"a","span":"{\"lo\":55,\"hi\":56}"}', mode = "None", type_ = "Address", id = 6, span = { lo = 55, hi = 65 } }, + { identifier = '{"id":"7","name":"v","span":"{\"lo\":67,\"hi\":68}"}', mode = "None", id = 9, type_ = { Composite = { id = '{"id":"8","name":"value","span":"{\"lo\":70,\"hi\":75}"}', program = "test" } }, span = { lo = 67, hi = 75 } }, ], block = { id = 29, statements = [ { Definition = { declaration_type = "Let", type_ = "Boolean", id = 17, place = { Identifier = '{"id":"10","name":"a","span":"{\"lo\":91,\"hi\":92}"}' }, value = { Access = { AssociatedFunction = { variant = '{"id":"11","name":"signature","span":"{\"lo\":101,\"hi\":110}"}', name = '{"id":"12","name":"verify","span":"{\"lo\":112,\"hi\":118}"}', id = 16, arguments = [ { Identifier = '{"id":"13","name":"s","span":"{\"lo\":119,\"hi\":120}"}' }, @@ -38,7 +38,7 @@ functions = [ ], [ "bar", - { annotations = [], variant = "Transition", identifier = '{"id":"31","name":"bar","span":"{\"lo\":214,\"hi\":217}"}', id = 43, input = [{ identifier = '{"id":"32","name":"x","span":"{\"lo\":218,\"hi\":219}"}', mode = "None", id = 33, type_ = { Integer = "U8" }, span = { lo = 218, hi = 219 } }], output = [{ mode = "None", id = 34, type_ = { Integer = "U8" }, span = { lo = 228, hi = 230 } }], output_type = { Integer = "U8" }, block = { id = 42, statements = [ + { annotations = [], variant = "Transition", identifier = '{"id":"31","name":"bar","span":"{\"lo\":214,\"hi\":217}"}', id = 43, input = [{ identifier = '{"id":"32","name":"x","span":"{\"lo\":218,\"hi\":219}"}', mode = "None", id = 33, type_ = { Integer = "U8" }, span = { lo = 218, hi = 223 } }], output = [{ mode = "None", id = 34, type_ = { Integer = "U8" }, span = { lo = 228, hi = 230 } }], output_type = { Integer = "U8" }, block = { id = 42, statements = [ { Definition = { declaration_type = "Let", id = 39, place = { Identifier = '{"id":"35","name":"signature","span":"{\"lo\":245,\"hi\":254}"}' }, type_ = { Integer = "U8" }, value = { Binary = { op = "Add", id = 38, left = { Literal = { Integer = [ "U8", "1", @@ -51,9 +51,9 @@ functions = [ [ "bax", { annotations = [], variant = "Transition", identifier = '{"id":"44","name":"bax","span":"{\"lo\":317,\"hi\":320}"}', output = [], output_type = "Unit", id = 64, input = [ - { identifier = '{"id":"45","name":"s","span":"{\"lo\":321,\"hi\":322}"}', mode = "None", type_ = "Signature", id = 46, span = { lo = 321, hi = 322 } }, - { identifier = '{"id":"47","name":"a","span":"{\"lo\":335,\"hi\":336}"}', mode = "None", type_ = "Address", id = 48, span = { lo = 335, hi = 336 } }, - { identifier = '{"id":"49","name":"v","span":"{\"lo\":347,\"hi\":348}"}', mode = "None", id = 51, type_ = { Composite = { id = '{"id":"50","name":"value","span":"{\"lo\":350,\"hi\":355}"}', program = "test" } }, span = { lo = 347, hi = 348 } }, + { identifier = '{"id":"45","name":"s","span":"{\"lo\":321,\"hi\":322}"}', mode = "None", type_ = "Signature", id = 46, span = { lo = 321, hi = 333 } }, + { identifier = '{"id":"47","name":"a","span":"{\"lo\":335,\"hi\":336}"}', mode = "None", type_ = "Address", id = 48, span = { lo = 335, hi = 345 } }, + { identifier = '{"id":"49","name":"v","span":"{\"lo\":347,\"hi\":348}"}', mode = "None", id = 51, type_ = { Composite = { id = '{"id":"50","name":"value","span":"{\"lo\":350,\"hi\":355}"}', program = "test" } }, span = { lo = 347, hi = 355 } }, ], block = { id = 63, statements = [ { Definition = { declaration_type = "Let", type_ = "Boolean", id = 59, place = { Identifier = '{"id":"52","name":"a","span":"{\"lo\":370,\"hi\":371}"}' }, value = { Access = { AssociatedFunction = { variant = '{"id":"53","name":"signature","span":"{\"lo\":380,\"hi\":389}"}', name = '{"id":"54","name":"sign","span":"{\"lo\":391,\"hi\":395}"}', id = 58, arguments = [ { Identifier = '{"id":"55","name":"s","span":"{\"lo\":396,\"hi\":397}"}' }, diff --git a/tests/tests/compiler/futures/future_access_tuple_fail.leo b/tests/tests/compiler/futures/future_access_tuple_fail.leo new file mode 100644 index 0000000000..5560859d7e --- /dev/null +++ b/tests/tests/compiler/futures/future_access_tuple_fail.leo @@ -0,0 +1,37 @@ +/* +namespace = "Compile" +expectation = "Fail" +*/ +program credits.aleo { + record credits { + owner: address, + amount: u64, + } + + async transition transfer_private_to_public(input: credits, addr: address, amount:u64) -> (credits, Future) { + let f: Future = finalize(); + return (input, f); + } + + async function finalize() { + assert_eq(1u8, 1u8); + } +} + +// --- Next Program --- // + +import credits.aleo; + +program test_credits.aleo { + async transition send_credits(input: credits.aleo/credits, amount: u64) -> (credits.aleo/credits, Future) { + let start: (credits.aleo/credits, Future) = credits.aleo/transfer_private_to_public(input, self.address, amount); + let after: (u8, credits.aleo/credits) = (1u8, start.0); + let start_2: Future = start.1; + return (after.1, finish(start.1, start_2)); + } + + async function finish(f1: Future, f2: Future) { + f1.await(); + f2.await(); + } +} diff --git a/tests/tests/compiler/futures/future_in_tuple_check_fail.leo b/tests/tests/compiler/futures/future_in_tuple_check_fail.leo new file mode 100644 index 0000000000..21051be8c9 --- /dev/null +++ b/tests/tests/compiler/futures/future_in_tuple_check_fail.leo @@ -0,0 +1,35 @@ +/* +namespace = "Compile" +expectation = "Fail" +*/ +program credits.aleo { + record credits { + owner: address, + amount: u64, + } + + async transition transfer_private_to_public(input: credits, addr: address, amount:u64) -> (credits, Future) { + let f: Future = finalize(); + return (input, f); + } + + async function finalize() { + assert_eq(1u8, 1u8); + } +} + +// --- Next Program --- // + +import credits.aleo; + +program test_credits.aleo { + async transition send_credits(input: credits.aleo/credits, amount: u64) -> (credits.aleo/credits, Future) { + let result: (credits.aleo/credits, Future) = credits.aleo/transfer_private_to_public(input, self.address, amount); + let result2: (credits.aleo/credits, Future) = credits.aleo/transfer_private_to_public(input, self.address, amount); + return (result.0, finish(result.1)); + } + + async function finish(f: Future) { + f.await(); + } +} diff --git a/tests/tests/compiler/futures/future_parameter_fail.leo b/tests/tests/compiler/futures/future_parameter_fail.leo new file mode 100644 index 0000000000..7beb72fa31 --- /dev/null +++ b/tests/tests/compiler/futures/future_parameter_fail.leo @@ -0,0 +1,22 @@ +/* +namespace = "Compile" +expectation = "Fail" +*/ + +program test.aleo { + async transition first(x: Future) -> Future { + return finish(); + } + + transition second(x: Future) -> u8 { + return 1u8; + } + + function third(x: Future) -> u8 { + return 1u8; + } + + async function finish() { + assert_eq(1u8, 1u8); + } +} diff --git a/tests/tests/compiler/futures/misplaced_future_fail.leo b/tests/tests/compiler/futures/misplaced_future_fail.leo new file mode 100644 index 0000000000..c8e06ac59d --- /dev/null +++ b/tests/tests/compiler/futures/misplaced_future_fail.leo @@ -0,0 +1,43 @@ +/* +namespace = "Compile" +expectation = "Fail" +*/ + +program child.aleo { + async transition foo() -> Future { + return finalize_foo(0u32); + } + + async function finalize_foo(x: u32) { + assert_eq(1u32, 1u32); + } + + async transition boo() -> (u32, Future) { + return (1u32, finalize_boo(0u32)); + } + + async function finalize_boo(x: u32) { + assert_eq(1u32, 1u32); + } + } + +// --- Next Program --- // + +import child.aleo; + +program parent.aleo { + + async transition foo() -> Future { + let f0: Future = child.aleo/foo(); + + child.aleo/foo(); + + child.aleo/boo(); + + return finalize_foo(f0); + } + + async function finalize_foo(f0: Future) { + f0.await(); + } +}