Skip to content

Commit

Permalink
feat: improve parser recovery of constructor field with '::' instead …
Browse files Browse the repository at this point in the history
…of ':'
  • Loading branch information
asterite committed Dec 4, 2024
1 parent f81244c commit 6dfcede
Showing 1 changed file with 30 additions and 2 deletions.
32 changes: 30 additions & 2 deletions compiler/noirc_frontend/src/parser/parser/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,8 @@ impl<'a> Parser<'a> {
Some(if self.eat_colon() {
let expression = self.parse_expression_or_error();
(ident, expression)
} else if self.at(Token::Assign) {
// If we find '=' instead of ':', assume the user meant ':`, error and continue
} else if self.at(Token::DoubleColon) || self.at(Token::Assign) {
// If we find '=' or '::' instead of ':', assume the user meant ':`, error and continue
self.expected_token(Token::Colon);
self.bump();
let expression = self.parse_expression_or_error();
Expand Down Expand Up @@ -1369,6 +1369,34 @@ mod tests {
assert_eq!(expr.to_string(), "y");
}

#[test]
fn parses_constructor_recovers_if_double_colon_instead_of_colon() {
let src = "
Foo { x: 1, y:: z }
^^
";
let (src, span) = get_source_with_error_span(src);
let mut parser = Parser::for_str(&src);
let expr = parser.parse_expression_or_error();

let error = get_single_error(&parser.errors, span);
assert_eq!(error.to_string(), "Expected a ':' but found '::'");

let ExpressionKind::Constructor(mut constructor) = expr.kind else {
panic!("Expected constructor");
};
assert_eq!(constructor.typ.to_string(), "Foo");
assert_eq!(constructor.fields.len(), 2);

let (name, expr) = constructor.fields.remove(0);
assert_eq!(name.to_string(), "x");
assert_eq!(expr.to_string(), "1");

let (name, expr) = constructor.fields.remove(0);
assert_eq!(name.to_string(), "y");
assert_eq!(expr.to_string(), "z");
}

#[test]
fn parses_parses_if_true() {
let src = "if true { 1 }";
Expand Down

0 comments on commit 6dfcede

Please sign in to comment.