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'.
This commit is contained in:
KtorZ 2024-01-20 10:36:07 +01:00
parent bf96c3afd2
commit 54a1b50138
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
4 changed files with 45 additions and 26 deletions

View File

@ -173,10 +173,10 @@ pub enum ErrorKind {
hint: Option<String>,
},
#[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()),
),

View File

@ -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)]

View File

@ -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,
}

View File

@ -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: