diff --git a/compiler/parser/src/parser/file.rs b/compiler/parser/src/parser/file.rs index 16c5267e6c..c010aa6052 100644 --- a/compiler/parser/src/parser/file.rs +++ b/compiler/parser/src/parser/file.rs @@ -60,6 +60,7 @@ impl ParserContext<'_> { let (id, function) = self.parse_function()?; functions.insert(id, function); } + Token::Circuit => return Err(ParserError::circuit_is_deprecated(self.token.span).into()), _ => return Err(Self::unexpected_item(&self.token).into()), } } @@ -173,9 +174,9 @@ impl ParserContext<'_> { /// Returns a [`Member`] AST node if the next tokens represent a struct member variable. fn parse_member_variable_declaration(&mut self) -> Result { - let (name, type_) = self.parse_typed_ident()?; + let (identifier, type_) = self.parse_typed_ident()?; - Ok(Member::StructVariable(name, type_)) + Ok(Member { identifier, type_ }) } /// Parses a struct or record definition, e.g., `struct Foo { ... }` or `record Foo { ... }`. diff --git a/compiler/parser/src/tokenizer/lexer.rs b/compiler/parser/src/tokenizer/lexer.rs index cc76a98880..7e60dbccc5 100644 --- a/compiler/parser/src/tokenizer/lexer.rs +++ b/compiler/parser/src/tokenizer/lexer.rs @@ -396,6 +396,7 @@ impl Token { "address" => Token::Address, "async" => Token::Async, "bool" => Token::Bool, + "circuit" => Token::Circuit, "console" => Token::Console, "const" => Token::Const, "constant" => Token::Constant, diff --git a/compiler/parser/src/tokenizer/token.rs b/compiler/parser/src/tokenizer/token.rs index d460944618..274ab78acd 100644 --- a/compiler/parser/src/tokenizer/token.rs +++ b/compiler/parser/src/tokenizer/token.rs @@ -324,6 +324,7 @@ impl fmt::Display for Token { Record => write!(f, "record"), Async => write!(f, "async"), + Circuit => write!(f, "circuit"), Console => write!(f, "console"), Const => write!(f, "const"), Constant => write!(f, "constant"), diff --git a/compiler/passes/src/code_generation/visit_program.rs b/compiler/passes/src/code_generation/visit_program.rs index 3dbddc31c2..fe58df300d 100644 --- a/compiler/passes/src/code_generation/visit_program.rs +++ b/compiler/passes/src/code_generation/visit_program.rs @@ -16,7 +16,7 @@ use crate::CodeGenerator; -use leo_ast::{functions, Function, Identifier, Mapping, Member, Mode, Program, Struct, Type}; +use leo_ast::{functions, Function, Identifier, Mapping, Mode, Program, Struct, Type}; use indexmap::IndexMap; use itertools::Itertools; @@ -131,11 +131,7 @@ impl<'a> CodeGenerator<'a> { // Construct and append the record variables. for var in struct_.members.iter() { - let (name, type_) = match var { - Member::StructVariable(name, type_) => (name, type_), - }; - - writeln!(output_string, " {} as {};", name, type_,).expect("failed to write to string"); + writeln!(output_string, " {} as {};", var.identifier, var.type_,).expect("failed to write to string"); } output_string @@ -150,14 +146,10 @@ impl<'a> CodeGenerator<'a> { // Construct and append the record variables. for var in record.members.iter() { - let (name, type_) = match var { - Member::StructVariable(name, type_) => (name, type_), - }; - writeln!( output_string, " {} as {}.private;", // todo: CAUTION private record variables only. - name, type_, + var.identifier, var.type_, ) .expect("failed to write to string"); } diff --git a/compiler/passes/src/flattening/flatten_expression.rs b/compiler/passes/src/flattening/flatten_expression.rs index 0526583c58..df287aba6d 100644 --- a/compiler/passes/src/flattening/flatten_expression.rs +++ b/compiler/passes/src/flattening/flatten_expression.rs @@ -108,18 +108,18 @@ impl ExpressionReconstructor for Flattener<'_> { let members = first_member_struct .members .iter() - .map(|Member::StructVariable(id, _)| { + .map(|Member { identifier, .. }| { // Construct a new ternary expression for the struct member. let (expression, stmts) = self.reconstruct_ternary(TernaryExpression { condition: input.condition.clone(), if_true: Box::new(Expression::Access(AccessExpression::Member(MemberAccess { inner: Box::new(Expression::Access(AccessExpression::Member(first.clone()))), - name: *id, + name: *identifier, span: Default::default(), }))), if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess { inner: Box::new(Expression::Access(AccessExpression::Member(second.clone()))), - name: *id, + name: *identifier, span: Default::default(), }))), span: Default::default(), @@ -133,7 +133,7 @@ impl ExpressionReconstructor for Flattener<'_> { statements.push(statement); StructVariableInitializer { - identifier: *id, + identifier, expression: Some(Expression::Identifier(identifier)), } }) @@ -204,18 +204,18 @@ impl ExpressionReconstructor for Flattener<'_> { let members = first_struct .members .iter() - .map(|Member::StructVariable(id, _)| { + .map(|Member { identifier, .. }| { // Construct a new ternary expression for the struct member. let (expression, stmts) = self.reconstruct_ternary(TernaryExpression { condition: input.condition.clone(), if_true: Box::new(Expression::Access(AccessExpression::Member(MemberAccess { inner: Box::new(Expression::Identifier(first)), - name: *id, + name: *identifier, span: Default::default(), }))), if_false: Box::new(Expression::Access(AccessExpression::Member(MemberAccess { inner: Box::new(Expression::Identifier(second)), - name: *id, + name: *identifier, span: Default::default(), }))), span: Default::default(), @@ -229,7 +229,7 @@ impl ExpressionReconstructor for Flattener<'_> { statements.push(statement); StructVariableInitializer { - identifier: *id, + identifier, expression: Some(Expression::Identifier(identifier)), } }) diff --git a/compiler/passes/src/flattening/flattener.rs b/compiler/passes/src/flattening/flattener.rs index 5938ca540e..9229cbf40e 100644 --- a/compiler/passes/src/flattening/flattener.rs +++ b/compiler/passes/src/flattening/flattener.rs @@ -126,12 +126,12 @@ impl<'a> Flattener<'a> { // The inner expression of an access expression is either an identifier or another access expression. let name = self.lookup_struct_symbol(&access.inner).unwrap(); let struct_ = self.symbol_table.lookup_struct(name).unwrap(); - let Member::StructVariable(_, member_type) = struct_ + let Member { type_, .. } = struct_ .members .iter() .find(|member| member.name() == access.name.name) .unwrap(); - match member_type { + match type_ { Type::Identifier(identifier) => Some(identifier.name), _ => None, } diff --git a/compiler/passes/src/type_checking/check_expressions.rs b/compiler/passes/src/type_checking/check_expressions.rs index 6f1ac333de..7096260099 100644 --- a/compiler/passes/src/type_checking/check_expressions.rs +++ b/compiler/passes/src/type_checking/check_expressions.rs @@ -143,7 +143,7 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> { // Check that `access.name` is a member of the struct. match struct_.members.iter().find(|member| member.name() == access.name.name) { // Case where `access.name` is a member of the struct. - Some(Member::StructVariable(_, type_)) => return Some(type_.clone()), + Some(Member { type_, .. }) => return Some(type_.clone()), // Case where `access.name` is not a member of the struct. None => { self.emit_err(TypeCheckerError::invalid_struct_variable( @@ -482,16 +482,20 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> { } // Check struct member types. - struct_.members.iter().for_each(|Member::StructVariable(name, ty)| { + struct_.members.iter().for_each(|Member { identifier, type_ }| { // Lookup struct variable name. - if let Some(actual) = input.members.iter().find(|member| member.identifier.name == name.name) { + if let Some(actual) = input + .members + .iter() + .find(|member| member.identifier.name == identifier.name) + { if let Some(expr) = &actual.expression { - self.visit_expression(expr, &Some(ty.clone())); + self.visit_expression(expr, &Some(type_.clone())); } } else { self.emit_err(TypeCheckerError::missing_struct_member( struct_.identifier, - name, + identifier, input.span(), )); }; diff --git a/compiler/passes/src/type_checking/check_program.rs b/compiler/passes/src/type_checking/check_program.rs index e23c2bb95b..31b7b6b612 100644 --- a/compiler/passes/src/type_checking/check_program.rs +++ b/compiler/passes/src/type_checking/check_program.rs @@ -29,11 +29,11 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> { fn visit_struct(&mut self, input: &'a Struct) { // Check for conflicting struct/record member names. let mut used = HashSet::new(); - if !input.members.iter().all(|Member::StructVariable(ident, type_)| { + if !input.members.iter().all(|Member { identifier, type_ }| { // TODO: Better spans. // Check that the member types are valid. self.assert_type_is_valid(input.span, type_); - used.insert(ident.name) + used.insert(identifier.name) }) { self.emit_err(if input.is_record { TypeCheckerError::duplicate_record_variable(input.name(), input.span()) @@ -47,7 +47,7 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> { let check_has_field = |need, expected_ty: Type| match input .members .iter() - .find_map(|Member::StructVariable(v, t)| (v.name == need).then_some((v, t))) + .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, _)) => { @@ -69,11 +69,11 @@ impl<'a> ProgramVisitor<'a> for TypeChecker<'a> { check_has_field(sym::gates, Type::Integer(IntegerType::U64)); } - for Member::StructVariable(v, type_) in input.members.iter() { + for Member { identifier, type_ } in input.members.iter() { // Ensure there are no tuple typed members. - self.assert_not_tuple(v.span, type_); + self.assert_not_tuple(identifier.span, type_); // Ensure that there are no record members. - self.assert_member_is_not_record(v.span, input.identifier.name, type_); + self.assert_member_is_not_record(identifier.span, input.identifier.name, type_); } } diff --git a/errors/src/errors/parser/parser_errors.rs b/errors/src/errors/parser/parser_errors.rs index eb10ced98b..e1d2091b6b 100644 --- a/errors/src/errors/parser/parser_errors.rs +++ b/errors/src/errors/parser/parser_errors.rs @@ -251,4 +251,11 @@ create_messages!( msg: "A finalize statement must be preceded by the `async` keyword.", help: Some("Add the `async` keyword before the `finalize` keyword.".to_string()), } + + @formatted + circuit_is_deprecated { + args: (), + msg: "The keyword `circuit` is deprecated.", + help: Some("Use `struct` instead.".to_string()), + } );