From 54a1b501387ad81d26d6673aafb46ec7878734f8 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Sat, 20 Jan 2024 10:36:07 +0100 Subject: [PATCH] Make behavior between curly- and paren-delimited blocks consistent. Note that the formatter rewrite parens-block sequences as curly-block sequences anyway. Albeit weird looking syntax, they are valid nonetheless. I also clarified a bit the hints and description of the 'illegal::return' error as it would mistakenly say 'function' instead of 'block'. --- crates/aiken-lang/src/parser/error.rs | 4 +- crates/aiken-lang/src/parser/expr/block.rs | 22 +++++----- .../snapshots/expect_let_in_let_parens.snap | 41 ++++++++++++++----- crates/aiken-lang/src/tipo/error.rs | 4 +- 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/crates/aiken-lang/src/parser/error.rs b/crates/aiken-lang/src/parser/error.rs index 9308ca42..0212e042 100644 --- a/crates/aiken-lang/src/parser/error.rs +++ b/crates/aiken-lang/src/parser/error.rs @@ -173,10 +173,10 @@ pub enum ErrorKind { hint: Option, }, - #[error("I discovered an unfinished assignment.")] + #[error("I spotted an unfinished assignment.")] #[diagnostic( help( - "{} and {} bindings must be followed by a valid expression.", + "{} and {} bindings must be followed by a valid, complete, expression.", "let".if_supports_color(Stdout, |s| s.yellow()), "expect".if_supports_color(Stdout, |s| s.yellow()), ), diff --git a/crates/aiken-lang/src/parser/expr/block.rs b/crates/aiken-lang/src/parser/expr/block.rs index 370536f8..ac1db7c8 100644 --- a/crates/aiken-lang/src/parser/expr/block.rs +++ b/crates/aiken-lang/src/parser/expr/block.rs @@ -11,22 +11,22 @@ pub fn parser( choice(( sequence .clone() - .delimited_by(just(Token::LeftBrace), just(Token::RightBrace)) - .map_with_span(|e, span| { - if matches!(e, UntypedExpr::Assignment { .. }) { - UntypedExpr::Sequence { - location: span, - expressions: vec![e], - } - } else { - e - } - }), + .delimited_by(just(Token::LeftBrace), just(Token::RightBrace)), sequence.clone().delimited_by( choice((just(Token::LeftParen), just(Token::NewLineLeftParen))), just(Token::RightParen), ), )) + .map_with_span(|e, span| { + if matches!(e, UntypedExpr::Assignment { .. }) { + UntypedExpr::Sequence { + location: span, + expressions: vec![e], + } + } else { + e + } + }) } #[cfg(test)] diff --git a/crates/aiken-lang/src/parser/expr/snapshots/expect_let_in_let_parens.snap b/crates/aiken-lang/src/parser/expr/snapshots/expect_let_in_let_parens.snap index 250c033a..7ca8ace8 100644 --- a/crates/aiken-lang/src/parser/expr/snapshots/expect_let_in_let_parens.snap +++ b/crates/aiken-lang/src/parser/expr/snapshots/expect_let_in_let_parens.snap @@ -1,15 +1,34 @@ --- source: crates/aiken-lang/src/parser/expr/assignment.rs -description: "Invalid code (parse error):\n\nlet a = ( let b = 42 )" +description: "Code:\n\nlet a = ( let b = 42 )" --- -[ - ParseError { - kind: UnfinishedAssignmentRightHandSide, - span: 0..22, - while_parsing: None, - expected: {}, - label: Some( - "invalid assignment right-hand side", - ), +Assignment { + location: 0..22, + value: Sequence { + location: 8..22, + expressions: [ + Assignment { + location: 10..20, + value: UInt { + location: 18..20, + value: "42", + base: Decimal { + numeric_underscore: false, + }, + }, + pattern: Var { + location: 14..15, + name: "b", + }, + kind: Let, + annotation: None, + }, + ], }, -] + pattern: Var { + location: 4..5, + name: "a", + }, + kind: Let, + annotation: None, +} diff --git a/crates/aiken-lang/src/tipo/error.rs b/crates/aiken-lang/src/tipo/error.rs index 8afd2a73..283efc5e 100644 --- a/crates/aiken-lang/src/tipo/error.rs +++ b/crates/aiken-lang/src/tipo/error.rs @@ -407,10 +407,10 @@ Perhaps, try the following: as, expect, check, const, else, fn, if, is, let, opaque, pub, test, todo, trace, type, use, when"#))] KeywordInModuleName { name: String, keyword: String }, - #[error("I discovered a function which is ending with an assignment.\n")] + #[error("I discovered a block which is ending with an assignment.\n")] #[diagnostic(url("https://aiken-lang.org/language-tour/functions#named-functions"))] #[diagnostic(code("illegal::return"))] - #[diagnostic(help(r#"In Aiken, functions must return an explicit result in the form of an expression. While assignments are technically speaking expressions, they aren't allowed to be the last expression of a function because they convey a different meaning and this could be error-prone. + #[diagnostic(help(r#"In Aiken, code blocks (such as function bodies) must return an explicit result in the form of an expression. While assignments are technically speaking expressions, they aren't allowed to be the last expression of a function because they convey a different meaning and this could be error-prone. If you really meant to return that last expression, try to replace it with the following: