Clippy + fmt

This commit is contained in:
Pranav Gaddamadugu 2023-11-22 17:34:20 -08:00
parent 1afa68a66e
commit afc953cd0b
28 changed files with 564 additions and 573 deletions

View File

@ -26,15 +26,16 @@ pub fn serialize<S: Serializer>(
imported_modules: &IndexMap<Vec<Symbol>, Program>, imported_modules: &IndexMap<Vec<Symbol>, Program>,
serializer: S, serializer: S,
) -> Result<S::Ok, S::Error> { ) -> Result<S::Ok, S::Error> {
let joined: IndexMap<String, Program> = with_session_globals(|s| { let joined: IndexMap<String, Program> =
imported_modules with_session_globals(|s| {
.into_iter() imported_modules
.map(|(package, program)| { .into_iter()
let package = package.iter().map(|x| x.as_str(s, |s| s.to_owned())).collect::<Vec<_>>(); .map(|(package, program)| {
(package.join("."), program.clone()) let package = package.iter().map(|x| x.as_str(s, |s| s.to_owned())).collect::<Vec<_>>();
}) (package.join("."), program.clone())
.collect() })
}); .collect()
});
joined.serialize(serializer) joined.serialize(serializer)
} }

View File

@ -66,12 +66,9 @@ pub trait ExpressionReconstructor {
fn reconstruct_associated_constant(&mut self, input: AssociatedConstant) -> (Expression, Self::AdditionalOutput) { fn reconstruct_associated_constant(&mut self, input: AssociatedConstant) -> (Expression, Self::AdditionalOutput) {
( (
Expression::Access(AccessExpression::AssociatedConstant(AssociatedConstant { Expression::Access(AccessExpression::AssociatedConstant(
ty: input.ty, AssociatedConstant { ty: input.ty, name: input.name, span: input.span, id: input.id }
name: input.name, )),
span: input.span,
id: input.id,
})),
Default::default(), Default::default(),
) )
} }

View File

@ -244,12 +244,9 @@ impl<'a> Compiler<'a> {
/// Runs the destructuring pass. /// Runs the destructuring pass.
pub fn destructuring_pass(&mut self) -> Result<()> { pub fn destructuring_pass(&mut self) -> Result<()> {
self.ast = Destructurer::do_pass(( self.ast = Destructurer::do_pass(
std::mem::take(&mut self.ast), (std::mem::take(&mut self.ast), &self.type_table, &self.node_builder, &self.assigner)
&self.type_table, )?;
&self.node_builder,
&self.assigner,
))?;
if self.compiler_options.output.destructured_ast { if self.compiler_options.output.destructured_ast {
self.write_ast_to_json("destructured_ast.json")?; self.write_ast_to_json("destructured_ast.json")?;

View File

@ -51,9 +51,9 @@ impl Namespace for CompileNamespace {
fn run_test(&self, test: Test) -> Result<Value, String> { fn run_test(&self, test: Test) -> Result<Value, String> {
let buf = BufferEmitter(Rc::default(), Rc::default()); let buf = BufferEmitter(Rc::default(), Rc::default());
let handler = Handler::new(Box::new(buf.clone())); let handler = Handler::new(Box::new(buf.clone()));
create_session_if_not_set_then(|_| { create_session_if_not_set_then(
run_test(test, &handler, &buf).map_err(|()| buf.0.take().to_string() + &buf.1.take().to_string()) |_| run_test(test, &handler, &buf).map_err(|()| buf.0.take().to_string() + &buf.1.take().to_string())
}) )
} }
} }

View File

@ -58,9 +58,9 @@ impl Namespace for ExecuteNamespace {
fn run_test(&self, test: Test) -> Result<Value, String> { fn run_test(&self, test: Test) -> Result<Value, String> {
let buf = BufferEmitter(Rc::default(), Rc::default()); let buf = BufferEmitter(Rc::default(), Rc::default());
let handler = Handler::new(Box::new(buf.clone())); let handler = Handler::new(Box::new(buf.clone()));
create_session_if_not_set_then(|_| { create_session_if_not_set_then(
run_test(test, &handler, &buf).map_err(|()| buf.0.take().to_string() + &buf.1.take().to_string()) |_| run_test(test, &handler, &buf).map_err(|()| buf.0.take().to_string() + &buf.1.take().to_string())
}) )
} }
} }
@ -125,13 +125,13 @@ fn run_test(test: Test, handler: &Handler, err_buf: &BufferEmitter) -> Result<Va
let bytecode = handler.extend_if_error(compile_and_process(&mut parsed))?; let bytecode = handler.extend_if_error(compile_and_process(&mut parsed))?;
// Extract the cases from the test config. // Extract the cases from the test config.
let all_cases = test let all_cases =
.config test.config
.extra .extra
.get("cases") .get("cases")
.expect("An `Execute` config must have a `cases` field.") .expect("An `Execute` config must have a `cases` field.")
.as_mapping() .as_mapping()
.unwrap(); .unwrap();
// Initialize a map for the expected results. // Initialize a map for the expected results.
let mut results = BTreeMap::new(); let mut results = BTreeMap::new();

View File

@ -237,12 +237,9 @@ impl ParserContext<'_> {
if self.eat(&Token::As) { if self.eat(&Token::As) {
let (type_, end_span) = self.parse_primitive_type()?; let (type_, end_span) = self.parse_primitive_type()?;
let span = expr.span() + end_span; let span = expr.span() + end_span;
expr = Expression::Cast(CastExpression { expr = Expression::Cast(
expression: Box::new(expr), CastExpression { expression: Box::new(expr), type_, span, id: self.node_builder.next_id() }
type_, );
span,
id: self.node_builder.next_id(),
});
} }
Ok(expr) Ok(expr)
@ -328,12 +325,9 @@ impl ParserContext<'_> {
if let (true, Some(op)) = (args.is_empty(), UnaryOperation::from_symbol(method.name)) { if let (true, Some(op)) = (args.is_empty(), UnaryOperation::from_symbol(method.name)) {
// Found an unary operator and the argument list is empty. // Found an unary operator and the argument list is empty.
Ok(Expression::Unary(UnaryExpression { Ok(Expression::Unary(
span, UnaryExpression { span, op, receiver: Box::new(receiver), id: self.node_builder.next_id() }
op, ))
receiver: Box::new(receiver),
id: self.node_builder.next_id(),
}))
} else if let (1, Some(op)) = (args.len(), BinaryOperation::from_symbol(method.name)) { } else if let (1, Some(op)) = (args.len(), BinaryOperation::from_symbol(method.name)) {
// Found a binary operator and the argument list contains a single argument. // Found a binary operator and the argument list contains a single argument.
Ok(Expression::Binary(BinaryExpression { Ok(Expression::Binary(BinaryExpression {
@ -443,12 +437,10 @@ impl ParserContext<'_> {
if self.check_int() { if self.check_int() {
// Eat a tuple member access. // Eat a tuple member access.
let (index, span) = self.eat_whole_number()?; let (index, span) = self.eat_whole_number()?;
expr = Expression::Access(AccessExpression::Tuple(TupleAccess { expr =
tuple: Box::new(expr), Expression::Access(AccessExpression::Tuple(
index, TupleAccess { tuple: Box::new(expr), index, span, id: self.node_builder.next_id() }
span, ))
id: self.node_builder.next_id(),
}))
} else if self.eat(&Token::Leo) { } else if self.eat(&Token::Leo) {
// Eat an external function call. // Eat an external function call.
self.eat(&Token::Div); // todo: Make `/` a more general token. self.eat(&Token::Div); // todo: Make `/` a more general token.
@ -627,14 +619,15 @@ impl ParserContext<'_> {
self.expect_identifier()? self.expect_identifier()?
}; };
let (expression, span) = if self.eat(&Token::Colon) { let (expression, span) =
// Parse individual struct variable declarations. if self.eat(&Token::Colon) {
let expression = self.parse_expression()?; // Parse individual struct variable declarations.
let span = identifier.span + expression.span(); let expression = self.parse_expression()?;
(Some(expression), span) let span = identifier.span + expression.span();
} else { (Some(expression), span)
(None, identifier.span) } else {
}; (None, identifier.span)
};
Ok(StructVariableInitializer { identifier, expression, id: self.node_builder.next_id(), span }) Ok(StructVariableInitializer { identifier, expression, id: self.node_builder.next_id(), span })
} }
@ -685,11 +678,9 @@ impl ParserContext<'_> {
// Literal followed by `group`, e.g., `42group`. // Literal followed by `group`, e.g., `42group`.
Some(Token::Group) => { Some(Token::Group) => {
assert_no_whitespace("group")?; assert_no_whitespace("group")?;
Expression::Literal(Literal::Group(Box::new(GroupLiteral::Single( Expression::Literal(Literal::Group(Box::new(
value, GroupLiteral::Single(value, full_span, self.node_builder.next_id())
full_span, )))
self.node_builder.next_id(),
))))
} }
// Literal followed by `scalar` e.g., `42scalar`. // Literal followed by `scalar` e.g., `42scalar`.
Some(Token::Scalar) => { Some(Token::Scalar) => {
@ -732,11 +723,9 @@ impl ParserContext<'_> {
Token::Block => { Token::Block => {
Expression::Identifier(Identifier { name: sym::block, span, id: self.node_builder.next_id() }) Expression::Identifier(Identifier { name: sym::block, span, id: self.node_builder.next_id() })
} }
t if crate::type_::TYPE_TOKENS.contains(&t) => Expression::Identifier(Identifier { t if crate::type_::TYPE_TOKENS.contains(&t) => Expression::Identifier(
name: t.keyword_to_symbol().unwrap(), Identifier { name: t.keyword_to_symbol().unwrap(), span, id: self.node_builder.next_id() }
span, ),
id: self.node_builder.next_id(),
}),
token => { token => {
return Err(ParserError::unexpected_str(token, "expression", span).into()); return Err(ParserError::unexpected_str(token, "expression", span).into());
} }

View File

@ -325,13 +325,9 @@ impl ParserContext<'_> {
} else { } else {
let type_ = self.parse_type()?.0; let type_ = self.parse_type()?.0;
Ok(functions::Input::Internal(FunctionInput { Ok(functions::Input::Internal(
identifier: name, FunctionInput { identifier: name, mode, type_, span: name.span, id: self.node_builder.next_id() }
mode, ))
type_,
span: name.span,
id: self.node_builder.next_id(),
}))
} }
} }
@ -420,56 +416,58 @@ impl ParserContext<'_> {
let (inputs, ..) = self.parse_paren_comma_list(|p| p.parse_input().map(Some))?; let (inputs, ..) = self.parse_paren_comma_list(|p| p.parse_input().map(Some))?;
// Parse return type. // Parse return type.
let output = match self.eat(&Token::Arrow) { let output =
false => vec![], match self.eat(&Token::Arrow) {
true => { false => vec![],
self.disallow_struct_construction = true; true => {
let output = match self.peek_is_left_par() { self.disallow_struct_construction = true;
true => self.parse_paren_comma_list(|p| p.parse_output().map(Some))?.0, let output = match self.peek_is_left_par() {
false => vec![self.parse_output()?], true => self.parse_paren_comma_list(|p| p.parse_output().map(Some))?.0,
}; false => vec![self.parse_output()?],
self.disallow_struct_construction = false; };
output self.disallow_struct_construction = false;
} output
}; }
};
// Parse the function body. // Parse the function body.
let block = self.parse_block()?; let block = self.parse_block()?;
// Parse the `finalize` block if it exists. // Parse the `finalize` block if it exists.
let finalize = match self.eat(&Token::Finalize) { let finalize =
false => None, match self.eat(&Token::Finalize) {
true => { false => None,
// Get starting span. true => {
let start = self.prev_token.span; // Get starting span.
let start = self.prev_token.span;
// Parse the identifier. // Parse the identifier.
let identifier = self.expect_identifier()?; let identifier = self.expect_identifier()?;
// Parse parameters. // Parse parameters.
let (input, ..) = self.parse_paren_comma_list(|p| p.parse_input().map(Some))?; let (input, ..) = self.parse_paren_comma_list(|p| p.parse_input().map(Some))?;
// Parse return type. // Parse return type.
let output = match self.eat(&Token::Arrow) { let output = match self.eat(&Token::Arrow) {
false => vec![], false => vec![],
true => { true => {
self.disallow_struct_construction = true; self.disallow_struct_construction = true;
let output = match self.peek_is_left_par() { let output = match self.peek_is_left_par() {
true => self.parse_paren_comma_list(|p| p.parse_output().map(Some))?.0, true => self.parse_paren_comma_list(|p| p.parse_output().map(Some))?.0,
false => vec![self.parse_output()?], false => vec![self.parse_output()?],
}; };
self.disallow_struct_construction = false; self.disallow_struct_construction = false;
output output
} }
}; };
// Parse the finalize body. // Parse the finalize body.
let block = self.parse_block()?; let block = self.parse_block()?;
let span = start + block.span; let span = start + block.span;
Some(Finalize::new(identifier, input, output, block, span, self.node_builder.next_id())) Some(Finalize::new(identifier, input, output, block, span, self.node_builder.next_id()))
} }
}; };
let span = start + block.span; let span = start + block.span;
Ok(( Ok((

View File

@ -158,11 +158,9 @@ impl ParserContext<'_> {
// Parse the expression as a statement. // Parse the expression as a statement.
let end = self.expect(&Token::Semicolon)?; let end = self.expect(&Token::Semicolon)?;
Ok(Statement::Expression(ExpressionStatement { Ok(Statement::Expression(
span: place.span() + end, ExpressionStatement { span: place.span() + end, expression: place, id: self.node_builder.next_id() }
expression: place, ))
id: self.node_builder.next_id(),
}))
} }
} }
@ -271,45 +269,43 @@ impl ParserContext<'_> {
let keyword = self.expect(&Token::Console)?; let keyword = self.expect(&Token::Console)?;
self.expect(&Token::Dot)?; self.expect(&Token::Dot)?;
let identifier = self.expect_identifier()?; let identifier = self.expect_identifier()?;
let (span, function) = match identifier.name { let (span, function) =
sym::assert => { match identifier.name {
self.expect(&Token::LeftParen)?; sym::assert => {
let expr = self.parse_expression()?; self.expect(&Token::LeftParen)?;
self.expect(&Token::RightParen)?; let expr = self.parse_expression()?;
(keyword + expr.span(), ConsoleFunction::Assert(expr)) self.expect(&Token::RightParen)?;
} (keyword + expr.span(), ConsoleFunction::Assert(expr))
sym::assert_eq => { }
self.expect(&Token::LeftParen)?; sym::assert_eq => {
let left = self.parse_expression()?; self.expect(&Token::LeftParen)?;
self.expect(&Token::Comma)?; let left = self.parse_expression()?;
let right = self.parse_expression()?; self.expect(&Token::Comma)?;
self.expect(&Token::RightParen)?; let right = self.parse_expression()?;
(left.span() + right.span(), ConsoleFunction::AssertEq(left, right)) self.expect(&Token::RightParen)?;
} (left.span() + right.span(), ConsoleFunction::AssertEq(left, right))
sym::assert_neq => { }
self.expect(&Token::LeftParen)?; sym::assert_neq => {
let left = self.parse_expression()?; self.expect(&Token::LeftParen)?;
self.expect(&Token::Comma)?; let left = self.parse_expression()?;
let right = self.parse_expression()?; self.expect(&Token::Comma)?;
self.expect(&Token::RightParen)?; let right = self.parse_expression()?;
(left.span() + right.span(), ConsoleFunction::AssertNeq(left, right)) self.expect(&Token::RightParen)?;
} (left.span() + right.span(), ConsoleFunction::AssertNeq(left, right))
symbol => { }
// Not sure what it is, assume it's `log`. symbol => {
self.emit_err(ParserError::unexpected_ident( // Not sure what it is, assume it's `log`.
symbol, self.emit_err(
&["assert", "assert_eq", "assert_neq"], ParserError::unexpected_ident(symbol, &["assert", "assert_eq", "assert_neq"], identifier.span)
identifier.span, );
)); (
( Default::default(),
Default::default(), ConsoleFunction::Assert(Expression::Err(
ConsoleFunction::Assert(Expression::Err(ErrExpression { ErrExpression { span: Default::default(), id: self.node_builder.next_id() }
span: Default::default(), )),
id: self.node_builder.next_id(), )
})), }
) };
}
};
self.expect(&Token::Semicolon)?; self.expect(&Token::Semicolon)?;
Ok(ConsoleStatement { span: keyword + span, function, id: self.node_builder.next_id() }) Ok(ConsoleStatement { span: keyword + span, function, id: self.node_builder.next_id() })

View File

@ -572,16 +572,18 @@ impl<'a> CodeGenerator<'a> {
let return_type = &self.symbol_table.lookup_fn_symbol(function_name).unwrap().output_type; let return_type = &self.symbol_table.lookup_fn_symbol(function_name).unwrap().output_type;
match return_type { match return_type {
Type::Unit => {} // Do nothing Type::Unit => {} // Do nothing
Type::Tuple(tuple) => match tuple.length() { Type::Tuple(tuple) => {
0 | 1 => unreachable!("Parsing guarantees that a tuple type has at least two elements"), match tuple.length() {
len => { 0 | 1 => unreachable!("Parsing guarantees that a tuple type has at least two elements"),
for _ in 0..len { len => {
let destination_register = format!("r{}", self.next_register); for _ in 0..len {
destinations.push(destination_register); let destination_register = format!("r{}", self.next_register);
self.next_register += 1; destinations.push(destination_register);
self.next_register += 1;
}
} }
} }
}, }
_ => { _ => {
let destination_register = format!("r{}", self.next_register); let destination_register = format!("r{}", self.next_register);
destinations.push(destination_register); destinations.push(destination_register);

View File

@ -55,18 +55,19 @@ impl<'a> CodeGenerator<'a> {
} }
fn visit_assert(&mut self, input: &'a AssertStatement) -> String { fn visit_assert(&mut self, input: &'a AssertStatement) -> String {
let mut generate_assert_instruction = |name: &str, left: &'a Expression, right: &'a Expression| { let mut generate_assert_instruction =
let (left_operand, left_instructions) = self.visit_expression(left); |name: &str, left: &'a Expression, right: &'a Expression| {
let (right_operand, right_instructions) = self.visit_expression(right); let (left_operand, left_instructions) = self.visit_expression(left);
let assert_instruction = format!(" {name} {left_operand} {right_operand};\n"); let (right_operand, right_instructions) = self.visit_expression(right);
let assert_instruction = format!(" {name} {left_operand} {right_operand};\n");
// Concatenate the instructions. // Concatenate the instructions.
let mut instructions = left_instructions; let mut instructions = left_instructions;
instructions.push_str(&right_instructions); instructions.push_str(&right_instructions);
instructions.push_str(&assert_instruction); instructions.push_str(&assert_instruction);
instructions instructions
}; };
match &input.variant { match &input.variant {
AssertVariant::Assert(expr) => { AssertVariant::Assert(expr) => {
let (operand, mut instructions) = self.visit_expression(expr); let (operand, mut instructions) = self.visit_expression(expr);
@ -81,68 +82,69 @@ impl<'a> CodeGenerator<'a> {
} }
fn visit_return(&mut self, input: &'a ReturnStatement) -> String { fn visit_return(&mut self, input: &'a ReturnStatement) -> String {
let mut outputs = match input.expression { let mut outputs =
// Skip empty return statements. match input.expression {
Expression::Unit(_) => String::new(), // Skip empty return statements.
_ => { Expression::Unit(_) => String::new(),
let (operand, mut expression_instructions) = self.visit_expression(&input.expression); _ => {
// Get the output type of the function. let (operand, mut expression_instructions) = self.visit_expression(&input.expression);
let output = if self.in_finalize { // Get the output type of the function.
// Note that the first unwrap is safe, since `current_function` is set in `visit_function`. let output = if self.in_finalize {
self.current_function.unwrap().finalize.as_ref().unwrap().output.iter() // Note that the first unwrap is safe, since `current_function` is set in `visit_function`.
} else { self.current_function.unwrap().finalize.as_ref().unwrap().output.iter()
// Note that this unwrap is safe, since `current_function` is set in `visit_function`. } else {
self.current_function.unwrap().output.iter() // Note that this unwrap is safe, since `current_function` is set in `visit_function`.
}; self.current_function.unwrap().output.iter()
// If the operand string is empty, initialize an empty vector. };
let operand_strings = match operand.is_empty() { // If the operand string is empty, initialize an empty vector.
true => vec![], let operand_strings = match operand.is_empty() {
false => operand.split(' ').collect_vec(), true => vec![],
}; false => operand.split(' ').collect_vec(),
let instructions = operand_strings };
.iter() let instructions = operand_strings
.zip_eq(output) .iter()
.map(|(operand, output)| { .zip_eq(output)
match output { .map(|(operand, output)| {
Output::Internal(output) => { match output {
let visibility = if self.is_transition_function { Output::Internal(output) => {
match self.in_finalize { let visibility = if self.is_transition_function {
// If in finalize block, the default visibility is public. match self.in_finalize {
true => match output.mode { // If in finalize block, the default visibility is public.
Mode::None => Mode::Public, true => match output.mode {
mode => mode, Mode::None => Mode::Public,
}, mode => mode,
// If not in finalize block, the default visibility is private. },
false => match output.mode { // If not in finalize block, the default visibility is private.
Mode::None => Mode::Private, false => match output.mode {
mode => mode, Mode::None => Mode::Private,
}, mode => mode,
} },
} else { }
// Only program functions have visibilities associated with their outputs. } else {
Mode::None // Only program functions have visibilities associated with their outputs.
}; Mode::None
format!( };
" output {} as {};\n", format!(
operand, " output {} as {};\n",
self.visit_type_with_visibility(&output.type_, visibility) operand,
) self.visit_type_with_visibility(&output.type_, visibility)
)
}
Output::External(output) => {
format!(
" output {} as {}.aleo/{}.record;\n",
operand, output.program_name, output.record,
)
}
} }
Output::External(output) => { })
format!( .join("");
" output {} as {}.aleo/{}.record;\n",
operand, output.program_name, output.record,
)
}
}
})
.join("");
expression_instructions.push_str(&instructions); expression_instructions.push_str(&instructions);
expression_instructions expression_instructions
} }
}; };
// Initialize storage for the instructions. // Initialize storage for the instructions.
let mut instructions = String::new(); let mut instructions = String::new();

View File

@ -55,10 +55,9 @@ impl SymbolTable {
variant: func.variant, variant: func.variant,
_span: func.span, _span: func.span,
input: func.input.clone(), input: func.input.clone(),
finalize: func.finalize.as_ref().map(|finalize| FinalizeData { finalize: func.finalize.as_ref().map(
input: finalize.input.clone(), |finalize| FinalizeData { input: finalize.input.clone(), output_type: finalize.output_type.clone() }
output_type: finalize.output_type.clone(), ),
}),
} }
} }
} }

View File

@ -87,12 +87,13 @@ impl StatementReconstructor for DeadCodeEliminator<'_> {
self.is_necessary = true; self.is_necessary = true;
// Visit the statement. // Visit the statement.
let statement = Statement::Assign(Box::new(AssignStatement { let statement =
place: input.place, Statement::Assign(Box::new(AssignStatement {
value: self.reconstruct_expression(input.value).0, place: input.place,
span: input.span, value: self.reconstruct_expression(input.value).0,
id: input.id, span: input.span,
})); id: input.id,
}));
// Unset the `is_necessary` flag. // Unset the `is_necessary` flag.
self.is_necessary = false; self.is_necessary = false;
@ -181,14 +182,15 @@ impl StatementReconstructor for DeadCodeEliminator<'_> {
self.is_necessary = true; self.is_necessary = true;
// Visit the statement. // Visit the statement.
let statement = Statement::Return(ReturnStatement { let statement =
expression: self.reconstruct_expression(input.expression).0, Statement::Return(ReturnStatement {
finalize_arguments: input.finalize_arguments.map(|arguments| { expression: self.reconstruct_expression(input.expression).0,
arguments.into_iter().map(|argument| self.reconstruct_expression(argument).0).collect() finalize_arguments: input.finalize_arguments.map(|arguments| {
}), arguments.into_iter().map(|argument| self.reconstruct_expression(argument).0).collect()
span: input.span, }),
id: input.id, span: input.span,
}); id: input.id,
});
// Unset the `is_necessary` flag. // Unset the `is_necessary` flag.
self.is_necessary = false; self.is_necessary = false;

View File

@ -137,29 +137,32 @@ impl StatementReconstructor for Destructurer<'_> {
), ),
// If the lhs is a tuple and the rhs is a tuple, create a new assign statement for each tuple element. // If the lhs is a tuple and the rhs is a tuple, create a new assign statement for each tuple element.
(Expression::Tuple(lhs_tuple), Expression::Tuple(rhs_tuple)) => { (Expression::Tuple(lhs_tuple), Expression::Tuple(rhs_tuple)) => {
let statements = lhs_tuple let statements =
.elements lhs_tuple
.into_iter() .elements
.zip_eq(rhs_tuple.elements) .into_iter()
.map(|(lhs, rhs)| { .zip_eq(rhs_tuple.elements)
// Get the type of the rhs. .map(|(lhs, rhs)| {
let type_ = match self.type_table.get(&lhs.id()) { // Get the type of the rhs.
Some(type_) => type_.clone(), let type_ = match self.type_table.get(&lhs.id()) {
None => { Some(type_) => type_.clone(),
unreachable!("Type checking guarantees that the type of the lhs is in the type table.") None => {
} unreachable!(
}; "Type checking guarantees that the type of the lhs is in the type table."
// Set the type of the lhs. )
self.type_table.insert(rhs.id(), type_); }
// Return the assign statement. };
Statement::Assign(Box::new(AssignStatement { // Set the type of the lhs.
place: lhs, self.type_table.insert(rhs.id(), type_);
value: rhs, // Return the assign statement.
span: Default::default(), Statement::Assign(Box::new(AssignStatement {
id: self.node_builder.next_id(), place: lhs,
})) value: rhs,
}) span: Default::default(),
.collect(); id: self.node_builder.next_id(),
}))
})
.collect();
(Statement::dummy(Default::default(), self.node_builder.next_id()), statements) (Statement::dummy(Default::default(), self.node_builder.next_id()), statements)
} }
// If the lhs is a tuple and the rhs is an identifier that is a tuple, create a new assign statement for each tuple element. // If the lhs is a tuple and the rhs is an identifier that is a tuple, create a new assign statement for each tuple element.

View File

@ -62,31 +62,32 @@ impl StatementReconstructor for Flattener<'_> {
let mut statements = Vec::new(); let mut statements = Vec::new();
// Flatten the arguments of the assert statement. // Flatten the arguments of the assert statement.
let assert = AssertStatement { let assert =
span: input.span, AssertStatement {
id: input.id, span: input.span,
variant: match input.variant { id: input.id,
AssertVariant::Assert(expression) => { variant: match input.variant {
let (expression, additional_statements) = self.reconstruct_expression(expression); AssertVariant::Assert(expression) => {
statements.extend(additional_statements); let (expression, additional_statements) = self.reconstruct_expression(expression);
AssertVariant::Assert(expression) statements.extend(additional_statements);
} AssertVariant::Assert(expression)
AssertVariant::AssertEq(left, right) => { }
let (left, additional_statements) = self.reconstruct_expression(left); AssertVariant::AssertEq(left, right) => {
statements.extend(additional_statements); let (left, additional_statements) = self.reconstruct_expression(left);
let (right, additional_statements) = self.reconstruct_expression(right); statements.extend(additional_statements);
statements.extend(additional_statements); let (right, additional_statements) = self.reconstruct_expression(right);
AssertVariant::AssertEq(left, right) statements.extend(additional_statements);
} AssertVariant::AssertEq(left, right)
AssertVariant::AssertNeq(left, right) => { }
let (left, additional_statements) = self.reconstruct_expression(left); AssertVariant::AssertNeq(left, right) => {
statements.extend(additional_statements); let (left, additional_statements) = self.reconstruct_expression(left);
let (right, additional_statements) = self.reconstruct_expression(right); statements.extend(additional_statements);
statements.extend(additional_statements); let (right, additional_statements) = self.reconstruct_expression(right);
AssertVariant::AssertNeq(left, right) statements.extend(additional_statements);
} AssertVariant::AssertNeq(left, right)
}, }
}; },
};
// Add the appropriate guards. // Add the appropriate guards.
match self.construct_guard() { match self.construct_guard() {

View File

@ -392,68 +392,71 @@ impl<'a> Flattener<'a> {
// Initialize a vector to accumulate any statements generated. // Initialize a vector to accumulate any statements generated.
let mut statements = Vec::new(); let mut statements = Vec::new();
// For each struct member, construct a new ternary expression. // For each struct member, construct a new ternary expression.
let members = struct_ let members =
.members struct_
.iter() .members
.map(|Member { identifier, type_, .. }| { .iter()
// Create an assignment statement for the first access expression. .map(|Member { identifier, type_, .. }| {
let (first, stmt) = // Create an assignment statement for the first access expression.
self.unique_simple_assign_statement(Expression::Access(AccessExpression::Member(MemberAccess { let (first, stmt) = self.unique_simple_assign_statement(Expression::Access(
inner: Box::new(Expression::Identifier(*first)), AccessExpression::Member(MemberAccess {
name: *identifier, inner: Box::new(Expression::Identifier(*first)),
name: *identifier,
span: Default::default(),
id: {
// Create a new node ID for the access expression.
let id = self.node_builder.next_id();
// Set the type of the node ID.
self.type_table.insert(id, type_.clone());
id
},
}),
));
statements.push(stmt);
// Create an assignment statement for the second access expression.
let (second, stmt) = self.unique_simple_assign_statement(Expression::Access(
AccessExpression::Member(MemberAccess {
inner: Box::new(Expression::Identifier(*second)),
name: *identifier,
span: Default::default(),
id: {
// Create a new node ID for the access expression.
let id = self.node_builder.next_id();
// Set the type of the node ID.
self.type_table.insert(id, type_.clone());
id
},
}),
));
statements.push(stmt);
// Recursively reconstruct the ternary expression.
let (expression, stmts) = self.reconstruct_ternary(TernaryExpression {
condition: Box::new(condition.clone()),
// Access the member of the first expression.
if_true: Box::new(Expression::Identifier(first)),
// Access the member of the second expression.
if_false: Box::new(Expression::Identifier(second)),
span: Default::default(), span: Default::default(),
id: { id: {
// Create a new node ID for the access expression. // Create a new node ID for the ternary expression.
let id = self.node_builder.next_id(); let id = self.node_builder.next_id();
// Set the type of the node ID. // Set the type of the node ID.
self.type_table.insert(id, type_.clone()); self.type_table.insert(id, type_.clone());
id id
}, },
}))); });
statements.push(stmt);
// Create an assignment statement for the second access expression. // Accumulate any statements generated.
let (second, stmt) = statements.extend(stmts);
self.unique_simple_assign_statement(Expression::Access(AccessExpression::Member(MemberAccess {
inner: Box::new(Expression::Identifier(*second)), StructVariableInitializer {
name: *identifier, identifier: *identifier,
expression: Some(expression),
span: Default::default(), span: Default::default(),
id: { id: self.node_builder.next_id(),
// Create a new node ID for the access expression. }
let id = self.node_builder.next_id(); })
// Set the type of the node ID. .collect();
self.type_table.insert(id, type_.clone());
id
},
})));
statements.push(stmt);
// Recursively reconstruct the ternary expression.
let (expression, stmts) = self.reconstruct_ternary(TernaryExpression {
condition: Box::new(condition.clone()),
// Access the member of the first expression.
if_true: Box::new(Expression::Identifier(first)),
// Access the member of the second expression.
if_false: Box::new(Expression::Identifier(second)),
span: Default::default(),
id: {
// Create a new node ID for the ternary expression.
let id = self.node_builder.next_id();
// Set the type of the node ID.
self.type_table.insert(id, type_.clone());
id
},
});
// Accumulate any statements generated.
statements.extend(stmts);
StructVariableInitializer {
identifier: *identifier,
expression: Some(expression),
span: Default::default(),
id: self.node_builder.next_id(),
}
})
.collect();
let (expr, stmts) = self.reconstruct_struct_init(StructExpression { let (expr, stmts) = self.reconstruct_struct_init(StructExpression {
name: struct_.identifier, name: struct_.identifier,
@ -489,65 +492,66 @@ impl<'a> Flattener<'a> {
// Initialize a vector to accumulate any statements generated. // Initialize a vector to accumulate any statements generated.
let mut statements = Vec::new(); let mut statements = Vec::new();
// For each tuple element, construct a new ternary expression. // For each tuple element, construct a new ternary expression.
let elements = tuple_type let elements =
.elements() tuple_type
.iter() .elements()
.enumerate() .iter()
.map(|(i, type_)| { .enumerate()
// Create an assignment statement for the first access expression. .map(|(i, type_)| {
let (first, stmt) = // Create an assignment statement for the first access expression.
self.unique_simple_assign_statement(Expression::Access(AccessExpression::Tuple(TupleAccess { let (first, stmt) =
tuple: Box::new(Expression::Identifier(*first)), self.unique_simple_assign_statement(Expression::Access(AccessExpression::Tuple(TupleAccess {
index: NonNegativeNumber::from(i), tuple: Box::new(Expression::Identifier(*first)),
index: NonNegativeNumber::from(i),
span: Default::default(),
id: {
// Create a new node ID for the access expression.
let id = self.node_builder.next_id();
// Set the type of the node ID.
self.type_table.insert(id, type_.clone());
id
},
})));
statements.push(stmt);
// Create an assignment statement for the second access expression.
let (second, stmt) =
self.unique_simple_assign_statement(Expression::Access(AccessExpression::Tuple(TupleAccess {
tuple: Box::new(Expression::Identifier(*second)),
index: NonNegativeNumber::from(i),
span: Default::default(),
id: {
// Create a new node ID for the access expression.
let id = self.node_builder.next_id();
// Set the type of the node ID.
self.type_table.insert(id, type_.clone());
id
},
})));
statements.push(stmt);
// Recursively reconstruct the ternary expression.
let (expression, stmts) = self.reconstruct_ternary(TernaryExpression {
condition: Box::new(condition.clone()),
// Access the member of the first expression.
if_true: Box::new(Expression::Identifier(first)),
// Access the member of the second expression.
if_false: Box::new(Expression::Identifier(second)),
span: Default::default(), span: Default::default(),
id: { id: {
// Create a new node ID for the access expression. // Create a new node ID for the ternary expression.
let id = self.node_builder.next_id(); let id = self.node_builder.next_id();
// Set the type of the node ID. // Set the type of the node ID.
self.type_table.insert(id, type_.clone()); self.type_table.insert(id, type_.clone());
id id
}, },
}))); });
statements.push(stmt);
// Create an assignment statement for the second access expression.
let (second, stmt) =
self.unique_simple_assign_statement(Expression::Access(AccessExpression::Tuple(TupleAccess {
tuple: Box::new(Expression::Identifier(*second)),
index: NonNegativeNumber::from(i),
span: Default::default(),
id: {
// Create a new node ID for the access expression.
let id = self.node_builder.next_id();
// Set the type of the node ID.
self.type_table.insert(id, type_.clone());
id
},
})));
statements.push(stmt);
// Recursively reconstruct the ternary expression. // Accumulate any statements generated.
let (expression, stmts) = self.reconstruct_ternary(TernaryExpression { statements.extend(stmts);
condition: Box::new(condition.clone()),
// Access the member of the first expression.
if_true: Box::new(Expression::Identifier(first)),
// Access the member of the second expression.
if_false: Box::new(Expression::Identifier(second)),
span: Default::default(),
id: {
// Create a new node ID for the ternary expression.
let id = self.node_builder.next_id();
// Set the type of the node ID.
self.type_table.insert(id, type_.clone());
id
},
});
// Accumulate any statements generated. expression
statements.extend(stmts); })
.collect();
expression
})
.collect();
// Construct the tuple expression. // Construct the tuple expression.
let tuple = TupleExpression { let tuple = TupleExpression {

View File

@ -192,41 +192,42 @@ impl<'a> Unroller<'a> {
self.type_table.insert(id, input.type_.clone()); self.type_table.insert(id, input.type_.clone());
// Reconstruct `iteration_count` as a `Literal`. // Reconstruct `iteration_count` as a `Literal`.
let value = match input.type_ { let value =
Type::Integer(IntegerType::I8) => { match input.type_ {
Literal::Integer(IntegerType::I8, iteration_count.to_string(), Default::default(), id) Type::Integer(IntegerType::I8) => {
} Literal::Integer(IntegerType::I8, iteration_count.to_string(), Default::default(), id)
Type::Integer(IntegerType::I16) => { }
Literal::Integer(IntegerType::I16, iteration_count.to_string(), Default::default(), id) Type::Integer(IntegerType::I16) => {
} Literal::Integer(IntegerType::I16, iteration_count.to_string(), Default::default(), id)
Type::Integer(IntegerType::I32) => { }
Literal::Integer(IntegerType::I32, iteration_count.to_string(), Default::default(), id) Type::Integer(IntegerType::I32) => {
} Literal::Integer(IntegerType::I32, iteration_count.to_string(), Default::default(), id)
Type::Integer(IntegerType::I64) => { }
Literal::Integer(IntegerType::I64, iteration_count.to_string(), Default::default(), id) Type::Integer(IntegerType::I64) => {
} Literal::Integer(IntegerType::I64, iteration_count.to_string(), Default::default(), id)
Type::Integer(IntegerType::I128) => { }
Literal::Integer(IntegerType::I128, iteration_count.to_string(), Default::default(), id) Type::Integer(IntegerType::I128) => {
} Literal::Integer(IntegerType::I128, iteration_count.to_string(), Default::default(), id)
Type::Integer(IntegerType::U8) => { }
Literal::Integer(IntegerType::U8, iteration_count.to_string(), Default::default(), id) Type::Integer(IntegerType::U8) => {
} Literal::Integer(IntegerType::U8, iteration_count.to_string(), Default::default(), id)
Type::Integer(IntegerType::U16) => { }
Literal::Integer(IntegerType::U16, iteration_count.to_string(), Default::default(), id) Type::Integer(IntegerType::U16) => {
} Literal::Integer(IntegerType::U16, iteration_count.to_string(), Default::default(), id)
Type::Integer(IntegerType::U32) => { }
Literal::Integer(IntegerType::U32, iteration_count.to_string(), Default::default(), id) Type::Integer(IntegerType::U32) => {
} Literal::Integer(IntegerType::U32, iteration_count.to_string(), Default::default(), id)
Type::Integer(IntegerType::U64) => { }
Literal::Integer(IntegerType::U64, iteration_count.to_string(), Default::default(), id) Type::Integer(IntegerType::U64) => {
} Literal::Integer(IntegerType::U64, iteration_count.to_string(), Default::default(), id)
Type::Integer(IntegerType::U128) => { }
Literal::Integer(IntegerType::U128, iteration_count.to_string(), Default::default(), id) Type::Integer(IntegerType::U128) => {
} Literal::Integer(IntegerType::U128, iteration_count.to_string(), Default::default(), id)
_ => unreachable!( }
"The iteration variable must be an integer type. This should be enforced by type checking." _ => unreachable!(
), "The iteration variable must be an integer type. This should be enforced by type checking."
}; ),
};
// Add the loop variable as a constant for the current scope // Add the loop variable as a constant for the current scope
self.constant_propagation_table self.constant_propagation_table

View File

@ -207,12 +207,13 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
let (expression, mut statements) = self.consume_expression(*input.expression); let (expression, mut statements) = self.consume_expression(*input.expression);
// Construct and accumulate a unique assignment statement storing the result of the cast expression. // Construct and accumulate a unique assignment statement storing the result of the cast expression.
let (place, statement) = self.unique_simple_assign_statement(Expression::Cast(CastExpression { let (place, statement) =
expression: Box::new(expression), self.unique_simple_assign_statement(Expression::Cast(CastExpression {
type_: input.type_, expression: Box::new(expression),
span: input.span, type_: input.type_,
id: input.id, span: input.span,
})); id: input.id,
}));
statements.push(statement); statements.push(statement);
(Expression::Identifier(place), statements) (Expression::Identifier(place), statements)
@ -280,12 +281,13 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
} }
// Construct and accumulate a new assignment statement for the struct expression. // Construct and accumulate a new assignment statement for the struct expression.
let (place, statement) = self.unique_simple_assign_statement(Expression::Struct(StructExpression { let (place, statement) =
name: input.name, self.unique_simple_assign_statement(Expression::Struct(StructExpression {
span: input.span, name: input.name,
members: reordered_members, span: input.span,
id: input.id, members: reordered_members,
})); id: input.id,
}));
statements.push(statement); statements.push(statement);
(Expression::Identifier(place), statements) (Expression::Identifier(place), statements)
@ -375,12 +377,9 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
let (receiver, mut statements) = self.consume_expression(*input.receiver); let (receiver, mut statements) = self.consume_expression(*input.receiver);
// Construct and accumulate a new assignment statement for the unary expression. // Construct and accumulate a new assignment statement for the unary expression.
let (place, statement) = self.unique_simple_assign_statement(Expression::Unary(UnaryExpression { let (place, statement) = self.unique_simple_assign_statement(Expression::Unary(
op: input.op, UnaryExpression { op: input.op, receiver: Box::new(receiver), span: input.span, id: input.id }
receiver: Box::new(receiver), ));
span: input.span,
id: input.id,
}));
statements.push(statement); statements.push(statement);
(Expression::Identifier(place), statements) (Expression::Identifier(place), statements)

View File

@ -198,13 +198,14 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
self.type_table.insert(id, type_); self.type_table.insert(id, type_);
// Construct a ternary expression for the phi function. // Construct a ternary expression for the phi function.
let (value, stmts) = self.consume_ternary(TernaryExpression { let (value, stmts) =
condition: Box::new(condition.clone()), self.consume_ternary(TernaryExpression {
if_true, condition: Box::new(condition.clone()),
if_false, if_true,
span: Default::default(), if_false,
id, span: Default::default(),
}); id,
});
statements.extend(stmts); statements.extend(stmts);
@ -290,22 +291,17 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
} }
// Construct the lhs of the assignment. // Construct the lhs of the assignment.
let place = Expression::Tuple(TupleExpression { let place = Expression::Tuple(
elements, TupleExpression { elements, span: Default::default(), id: self.node_builder.next_id() }
span: Default::default(), );
id: self.node_builder.next_id(),
});
// Update the type of the lhs. // Update the type of the lhs.
self.type_table.insert(place.id(), Type::Tuple(tuple_type_)); self.type_table.insert(place.id(), Type::Tuple(tuple_type_));
// Create the assignment statement. // Create the assignment statement.
let assignment = Statement::Assign(Box::new(AssignStatement { let assignment = Statement::Assign(
place, Box::new(AssignStatement { place, value, span: definition.span, id: definition.id })
value, );
span: definition.span,
id: definition.id,
}));
statements.push(assignment); statements.push(assignment);
} }
@ -401,12 +397,9 @@ impl StatementConsumer for StaticSingleAssigner<'_> {
}); });
// Add the simplified return statement to the list of produced statements. // Add the simplified return statement to the list of produced statements.
statements.push(Statement::Return(ReturnStatement { statements.push(Statement::Return(
expression, ReturnStatement { expression, finalize_arguments: finalize_args, span: input.span, id: input.id }
finalize_arguments: finalize_args, ));
span: input.span,
id: input.id,
}));
statements statements
} }

View File

@ -235,10 +235,9 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
self.emit_err(TypeCheckerError::type_should_be(type_, "struct", access.inner.span())); self.emit_err(TypeCheckerError::type_should_be(type_, "struct", access.inner.span()));
} }
None => { None => {
self.emit_err(TypeCheckerError::could_not_determine_type( self.emit_err(
&access.inner, TypeCheckerError::could_not_determine_type(&access.inner, access.inner.span())
access.inner.span(), );
));
} }
} }
} }
@ -288,11 +287,9 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
} }
// The array cannot have more than `MAX_ARRAY_ELEMENTS` elements. // The array cannot have more than `MAX_ARRAY_ELEMENTS` elements.
num_elements => { num_elements => {
self.emit_err(TypeCheckerError::array_too_large( self.emit_err(
num_elements, TypeCheckerError::array_too_large(num_elements, Testnet3::MAX_ARRAY_ELEMENTS, input.span())
Testnet3::MAX_ARRAY_ELEMENTS, );
input.span(),
));
None None
} }
}; };

View File

@ -121,18 +121,19 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> {
// For records, enforce presence of the `owner: Address` member. // For records, enforce presence of the `owner: Address` member.
if input.is_record { if input.is_record {
let check_has_field = let check_has_field = |need, expected_ty: Type| match input
|need, expected_ty: Type| match input.members.iter().find_map(|Member { identifier, type_, .. }| { .members
(identifier.name == need).then_some((identifier, type_)) .iter()
}) { .find_map(|Member { identifier, type_, .. }| (identifier.name == need).then_some((identifier, type_)))
Some((_, actual_ty)) if expected_ty.eq_flat(actual_ty) => {} // All good, found + right type! {
Some((field, _)) => { Some((_, actual_ty)) if expected_ty.eq_flat(actual_ty) => {} // All good, found + right type!
self.emit_err(TypeCheckerError::record_var_wrong_type(field, expected_ty, input.span())); Some((field, _)) => {
} self.emit_err(TypeCheckerError::record_var_wrong_type(field, expected_ty, input.span()));
None => { }
self.emit_err(TypeCheckerError::required_record_variable(need, expected_ty, input.span())); None => {
} self.emit_err(TypeCheckerError::required_record_variable(need, expected_ty, input.span()));
}; }
};
check_has_field(sym::owner, Type::Address); check_has_field(sym::owner, Type::Address);
} }

View File

@ -68,21 +68,24 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
} }
}; };
let var_type = if let Some(var) = self.symbol_table.borrow_mut().lookup_variable(var_name.name) { let var_type =
match &var.declaration { if let Some(var) = self.symbol_table.borrow_mut().lookup_variable(var_name.name) {
VariableType::Const => self.emit_err(TypeCheckerError::cannot_assign_to_const_var(var_name, var.span)), match &var.declaration {
VariableType::Input(Mode::Constant) => { VariableType::Const => {
self.emit_err(TypeCheckerError::cannot_assign_to_const_input(var_name, var.span)) self.emit_err(TypeCheckerError::cannot_assign_to_const_var(var_name, var.span))
}
VariableType::Input(Mode::Constant) => {
self.emit_err(TypeCheckerError::cannot_assign_to_const_input(var_name, var.span))
}
_ => {}
} }
_ => {}
}
Some(var.type_.clone()) Some(var.type_.clone())
} else { } else {
self.emit_err(TypeCheckerError::unknown_sym("variable", var_name.name, var_name.span)); self.emit_err(TypeCheckerError::unknown_sym("variable", var_name.name, var_name.span));
None None
}; };
if var_type.is_some() { if var_type.is_some() {
self.visit_expression(&input.value, &var_type); self.visit_expression(&input.value, &var_type);
@ -175,16 +178,18 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
// Enforce that Constant variables have literal expressions on right-hand side // Enforce that Constant variables have literal expressions on right-hand side
match &input.value { match &input.value {
Expression::Literal(_) => (), Expression::Literal(_) => (),
Expression::Tuple(tuple_expression) => match tuple_expression.elements.len() { Expression::Tuple(tuple_expression) => {
0 | 1 => unreachable!("Parsing guarantees that tuple types have at least two elements."), match tuple_expression.elements.len() {
_ => { 0 | 1 => unreachable!("Parsing guarantees that tuple types have at least two elements."),
if tuple_expression.elements.iter().any(|expr| !matches!(expr, Expression::Literal(_))) { _ => {
self.emit_err(TypeCheckerError::const_declaration_must_be_literal_or_tuple_of_literals( if tuple_expression.elements.iter().any(|expr| !matches!(expr, Expression::Literal(_))) {
input.span, self.emit_err(TypeCheckerError::const_declaration_must_be_literal_or_tuple_of_literals(
)) input.span,
))
}
} }
} }
}, }
_ => self.emit_err(TypeCheckerError::const_declaration_must_be_literal_or_tuple_of_literals(input.span())), _ => self.emit_err(TypeCheckerError::const_declaration_must_be_literal_or_tuple_of_literals(input.span())),
} }

View File

@ -387,11 +387,9 @@ impl<'a> TypeChecker<'a> {
) -> Option<Type> { ) -> Option<Type> {
// Check that the number of arguments is correct. // Check that the number of arguments is correct.
if arguments.len() != core_function.num_args() { if arguments.len() != core_function.num_args() {
self.emit_err(TypeCheckerError::incorrect_num_args_to_call( self.emit_err(
core_function.num_args(), TypeCheckerError::incorrect_num_args_to_call(core_function.num_args(), arguments.len(), function_span)
arguments.len(), );
function_span,
));
return None; return None;
} }
@ -982,10 +980,9 @@ impl<'a> TypeChecker<'a> {
CoreFunction::MappingContains => { CoreFunction::MappingContains => {
// Check that the operation is invoked in a `finalize` block. // Check that the operation is invoked in a `finalize` block.
if !self.is_finalize { if !self.is_finalize {
self.handler.emit_err(TypeCheckerError::invalid_operation_outside_finalize( self.handler.emit_err(
"Mapping::contains", TypeCheckerError::invalid_operation_outside_finalize("Mapping::contains", function_span)
function_span, )
))
} }
// Check that the first argument is a mapping. // Check that the first argument is a mapping.
if let Some(mapping_type) = self.assert_mapping_type(&arguments[0].0, arguments[0].1) { if let Some(mapping_type) = self.assert_mapping_type(&arguments[0].0, arguments[0].1) {

View File

@ -99,10 +99,11 @@ impl SourceMap {
/// Returns a displayable representation of the `span` as a string. /// Returns a displayable representation of the `span` as a string.
pub fn span_to_string(&self, span: Span) -> String { pub fn span_to_string(&self, span: Span) -> String {
let loc = match self.span_to_location(span) { let loc =
None => return "no-location".to_string(), match self.span_to_location(span) {
Some(l) => l, None => return "no-location".to_string(),
}; Some(l) => l,
};
if loc.line_start == loc.line_stop { if loc.line_start == loc.line_stop {
format!("{}:{}-{}", loc.line_start, loc.col_start, loc.col_stop) format!("{}:{}-{}", loc.line_start, loc.col_start, loc.col_stop)
@ -339,10 +340,11 @@ fn normalize_newlines(src: &mut String) {
let mut gap_len = 0; let mut gap_len = 0;
let mut tail = buf.as_mut_slice(); let mut tail = buf.as_mut_slice();
loop { loop {
let idx = match find_crlf(&tail[gap_len..]) { let idx =
None => tail.len(), match find_crlf(&tail[gap_len..]) {
Some(idx) => idx + gap_len, None => tail.len(),
}; Some(idx) => idx + gap_len,
};
tail.copy_within(gap_len..idx, 0); tail.copy_within(gap_len..idx, 0);
tail = &mut tail[idx - gap_len..]; tail = &mut tail[idx - gap_len..];
if tail.len() == gap_len { if tail.len() == gap_len {

View File

@ -205,10 +205,11 @@ fn main() -> Result<()> {
// Parse ABNF to get list of all definitions. // Parse ABNF to get list of all definitions.
// Rust ABNF does not provide support for `%s` (case sensitive strings, part of // Rust ABNF does not provide support for `%s` (case sensitive strings, part of
// the standard); so we need to remove all occurrences before parsing. // the standard); so we need to remove all occurrences before parsing.
let parsed = abnf::rulelist(&str::replace(&grammar, "%s", "")).map_err(|e| { let parsed =
eprintln!("{}", &e); abnf::rulelist(&str::replace(&grammar, "%s", "")).map_err(|e| {
anyhow::anyhow!(e) eprintln!("{}", &e);
})?; anyhow::anyhow!(e)
})?;
// Init parser and run it. That's it. // Init parser and run it. That's it.
let mut parser = Processor::new(&grammar, parsed); let mut parser = Processor::new(&grammar, parsed);

View File

@ -54,13 +54,14 @@ impl Command for Execute {
fn apply(self, context: Context, input: Self::Input) -> Result<Self::Output> { fn apply(self, context: Context, input: Self::Input) -> Result<Self::Output> {
// If input values are provided, then run the program with those inputs. // If input values are provided, then run the program with those inputs.
// Otherwise, use the input file. // Otherwise, use the input file.
let mut inputs = match self.inputs.is_empty() { let mut inputs =
true => match input { match self.inputs.is_empty() {
(Some(input_ast), circuits) => input_ast.program_inputs(&self.name, circuits), true => match input {
_ => Vec::new(), (Some(input_ast), circuits) => input_ast.program_inputs(&self.name, circuits),
}, _ => Vec::new(),
false => self.inputs, },
}; false => self.inputs,
};
// Compose the `execute` command. // Compose the `execute` command.
let mut arguments = vec![SNARKVM_COMMAND.to_string(), self.name]; let mut arguments = vec![SNARKVM_COMMAND.to_string(), self.name];

View File

@ -46,13 +46,14 @@ impl Command for Run {
fn apply(self, context: Context, input: Self::Input) -> Result<Self::Output> { fn apply(self, context: Context, input: Self::Input) -> Result<Self::Output> {
// If input values are provided, then run the program with those inputs. // If input values are provided, then run the program with those inputs.
// Otherwise, use the input file. // Otherwise, use the input file.
let mut inputs = match self.inputs.is_empty() { let mut inputs =
true => match input { match self.inputs.is_empty() {
(Some(input_ast), circuits) => input_ast.program_inputs(&self.name, circuits), true => match input {
_ => Vec::new(), (Some(input_ast), circuits) => input_ast.program_inputs(&self.name, circuits),
}, _ => Vec::new(),
false => self.inputs, },
}; false => self.inputs,
};
// Compose the `run` command. // Compose the `run` command.
let mut arguments = vec![SNARKVM_COMMAND.to_string(), self.name]; let mut arguments = vec![SNARKVM_COMMAND.to_string(), self.name];

View File

@ -56,8 +56,8 @@ impl InputFile {
pub fn read_from<'a>(&self, path: &'a Path) -> Result<(String, Cow<'a, Path>)> { pub fn read_from<'a>(&self, path: &'a Path) -> Result<(String, Cow<'a, Path>)> {
let path = self.setup_file_path(path); let path = self.setup_file_path(path);
let input = fs::read_to_string(&path) let input =
.map_err(|_| PackageError::failed_to_read_input_file(path.clone().into_owned()))?; fs::read_to_string(&path).map_err(|_| PackageError::failed_to_read_input_file(path.clone().into_owned()))?;
Ok((input, path)) Ok((input, path))
} }

View File

@ -93,12 +93,13 @@ impl TestCases {
let mut path_prefix = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let mut path_prefix = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path_prefix.push("../../tests"); path_prefix.push("../../tests");
let mut new = Self { let mut new =
tests: Vec::new(), Self {
path_prefix, tests: Vec::new(),
expectation_category: expectation_category.to_string(), path_prefix,
fail_categories: Vec::new(), expectation_category: expectation_category.to_string(),
}; fail_categories: Vec::new(),
};
let tests = new.load_tests(additional_check); let tests = new.load_tests(additional_check);
(new, tests) (new, tests)
} }
@ -188,10 +189,11 @@ pub fn run_tests<T: Runner>(runner: &T, expectation_category: &str) {
let mut outputs = vec![]; let mut outputs = vec![];
cases.process_tests(configs, |cases, (path, content, test_name, config)| { cases.process_tests(configs, |cases, (path, content, test_name, config)| {
let namespace = match runner.resolve_namespace(&config.namespace) { let namespace =
Some(ns) => ns, match runner.resolve_namespace(&config.namespace) {
None => return, Some(ns) => ns,
}; None => return,
};
let (expectation_path, expectations) = cases.load_expectations(path); let (expectation_path, expectations) = cases.load_expectations(path);