Better trace parsing + default behaviour.
Somehow, we allow traces with no continuation after and currently default to a Todo. That todo is completely invisible from a user standpoint and return a generic `a`. So it is pretty easy for someone to think their program is okay, compiles, and have no issues, while simply crashing at runtime because of an invisible todo. Hence, I've changed that to default to `Void` instead, which is more sensible as a default for an empty trace. Also, I've made the parser fail with one puts a colon for label, but doesn't add any value to display. Fixes #1113. Signed-off-by: KtorZ <matthias.benkort@gmail.com>
This commit is contained in:
parent
222d244bcf
commit
9b8137c056
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
ast::TraceKind,
|
||||
ast::{well_known, TraceKind},
|
||||
expr::UntypedExpr,
|
||||
parser::{
|
||||
error::{ParseError, Pattern},
|
||||
|
@ -32,7 +32,8 @@ pub fn parser<'a>(
|
|||
choice((just(Token::Colon), just(Token::Comma)))
|
||||
.then(
|
||||
choice((string::hybrid(), expression.clone()))
|
||||
.separated_by(just(Token::Comma)),
|
||||
.separated_by(just(Token::Comma))
|
||||
.at_least(1),
|
||||
)
|
||||
.validate(|(token, arguments), span, emit| {
|
||||
if token != Token::Colon {
|
||||
|
@ -53,7 +54,10 @@ pub fn parser<'a>(
|
|||
|((label, arguments), continuation), span| UntypedExpr::Trace {
|
||||
kind: TraceKind::Trace,
|
||||
location: span,
|
||||
then: Box::new(continuation.unwrap_or_else(|| UntypedExpr::todo(None, span))),
|
||||
then: Box::new(continuation.unwrap_or_else(|| UntypedExpr::Var {
|
||||
location: span,
|
||||
name: well_known::VOID.to_string(),
|
||||
})),
|
||||
label: Box::new(label),
|
||||
arguments,
|
||||
},
|
||||
|
@ -193,4 +197,15 @@ mod tests {
|
|||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trace_dangling_colons() {
|
||||
assert_expr!(
|
||||
r#"
|
||||
let debug = fn() {
|
||||
trace "foo":
|
||||
}
|
||||
"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/parser/expr/fail_todo_trace.rs
|
||||
description: "Invalid code (parse error):\n\nlet debug = fn() {\n trace \"foo\":\n}\n"
|
||||
---
|
||||
[
|
||||
ParseError {
|
||||
kind: Unexpected(
|
||||
Token(
|
||||
RightBrace,
|
||||
),
|
||||
),
|
||||
span: 34..35,
|
||||
while_parsing: None,
|
||||
expected: {
|
||||
Token(
|
||||
If,
|
||||
),
|
||||
Token(
|
||||
Expect,
|
||||
),
|
||||
Token(
|
||||
Minus,
|
||||
),
|
||||
Token(
|
||||
When,
|
||||
),
|
||||
Token(
|
||||
And,
|
||||
),
|
||||
Token(
|
||||
Or,
|
||||
),
|
||||
Token(
|
||||
LeftParen,
|
||||
),
|
||||
Token(
|
||||
Todo,
|
||||
),
|
||||
Token(
|
||||
LeftSquare,
|
||||
),
|
||||
Token(
|
||||
NewLineMinus,
|
||||
),
|
||||
Token(
|
||||
Bang,
|
||||
),
|
||||
Token(
|
||||
Fail,
|
||||
),
|
||||
Token(
|
||||
NewLineLeftParen,
|
||||
),
|
||||
Token(
|
||||
LeftBrace,
|
||||
),
|
||||
Token(
|
||||
Trace,
|
||||
),
|
||||
Token(
|
||||
Let,
|
||||
),
|
||||
Token(
|
||||
Hash,
|
||||
),
|
||||
Token(
|
||||
Fn,
|
||||
),
|
||||
},
|
||||
label: None,
|
||||
},
|
||||
]
|
|
@ -5,17 +5,9 @@ description: "Code:\n\ntrace some_var\n"
|
|||
Trace {
|
||||
kind: Trace,
|
||||
location: 0..14,
|
||||
then: Trace {
|
||||
kind: Todo,
|
||||
then: Var {
|
||||
location: 0..14,
|
||||
then: ErrorTerm {
|
||||
location: 0..14,
|
||||
},
|
||||
label: String {
|
||||
location: 0..14,
|
||||
value: "aiken::todo",
|
||||
},
|
||||
arguments: [],
|
||||
name: "Void",
|
||||
},
|
||||
label: Var {
|
||||
location: 6..14,
|
||||
|
|
|
@ -5,17 +5,9 @@ description: "Code:\n\ntrace foo: \"bar\"\n"
|
|||
Trace {
|
||||
kind: Trace,
|
||||
location: 0..16,
|
||||
then: Trace {
|
||||
kind: Todo,
|
||||
then: Var {
|
||||
location: 0..16,
|
||||
then: ErrorTerm {
|
||||
location: 0..16,
|
||||
},
|
||||
label: String {
|
||||
location: 0..16,
|
||||
value: "aiken::todo",
|
||||
},
|
||||
arguments: [],
|
||||
name: "Void",
|
||||
},
|
||||
label: Var {
|
||||
location: 6..9,
|
||||
|
|
|
@ -5,17 +5,9 @@ description: "Code:\n\ntrace \"foo\": @\"bar\", baz\n"
|
|||
Trace {
|
||||
kind: Trace,
|
||||
location: 0..24,
|
||||
then: Trace {
|
||||
kind: Todo,
|
||||
then: Var {
|
||||
location: 0..24,
|
||||
then: ErrorTerm {
|
||||
location: 0..24,
|
||||
},
|
||||
label: String {
|
||||
location: 0..24,
|
||||
value: "aiken::todo",
|
||||
},
|
||||
arguments: [],
|
||||
name: "Void",
|
||||
},
|
||||
label: String {
|
||||
location: 6..11,
|
||||
|
|
|
@ -3332,6 +3332,22 @@ fn dangling_let_in_block() {
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_trace_return() {
|
||||
let source_code = r#"
|
||||
fn debug() {
|
||||
trace @"patate": Void
|
||||
}
|
||||
|
||||
test foo() {
|
||||
debug()
|
||||
True
|
||||
}
|
||||
"#;
|
||||
|
||||
assert!(matches!(check_validator(parse(source_code)), Ok(..)))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dangling_trace_let_standalone() {
|
||||
let source_code = r#"
|
||||
|
|
Loading…
Reference in New Issue