Fix adjacent sequence collapse in parser
Without this fix, the parser wrongly turns the following: ``` { let a = Void a } let _ = True True ``` into the following: ``` let a = Void a let _ = True True ``` Which in this particular example looks benign. But now takes something more _real-world_: ``` { let scope, output <- for_each_2(scopes, other_outputs) Void } let _ = True True ``` This would lead to the the entire sequence that follows the backpassed continuation to be added to the continuation; here ultimately causing a type unification error (since for_each_2 is expected to yield Void, not Bool). This is utterly confusing.. and dangerous. Signed-off-by: KtorZ <matthias.benkort@gmail.com>
This commit is contained in:
parent
f786e80924
commit
54d41f73ea
|
@ -16,6 +16,7 @@
|
|||
### Fixed
|
||||
|
||||
- **aiken-lang**: Formatter was removing comments from function type annotation args @rvcas
|
||||
- **aiken-lang**: Parser wrongly merged two adjacent sequences together, effectively fusioning scopes. @KtorZ
|
||||
|
||||
## v1.1.13 - 2025-02-26
|
||||
|
||||
|
|
|
@ -1406,23 +1406,10 @@ impl UntypedExpr {
|
|||
};
|
||||
|
||||
match (self.clone(), next.clone()) {
|
||||
(
|
||||
Self::Sequence {
|
||||
expressions: mut current_expressions,
|
||||
..
|
||||
},
|
||||
Self::Sequence {
|
||||
expressions: mut next_expressions,
|
||||
..
|
||||
},
|
||||
) => {
|
||||
current_expressions.append(&mut next_expressions);
|
||||
|
||||
Self::Sequence {
|
||||
location,
|
||||
expressions: current_expressions,
|
||||
}
|
||||
}
|
||||
(left @ Self::Sequence { .. }, right @ Self::Sequence { .. }) => Self::Sequence {
|
||||
location,
|
||||
expressions: vec![left, right],
|
||||
},
|
||||
(
|
||||
_,
|
||||
Self::Sequence {
|
||||
|
|
|
@ -31,7 +31,7 @@ pub fn parser(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::assert_expr;
|
||||
use crate::{assert_definition, assert_expr};
|
||||
|
||||
#[test]
|
||||
fn block_let() {
|
||||
|
@ -54,4 +54,35 @@ mod tests {
|
|||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sequence_then_expr() {
|
||||
assert_definition!(
|
||||
r#"
|
||||
test foo() {
|
||||
{
|
||||
let a = Void
|
||||
a
|
||||
}
|
||||
True
|
||||
}
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sequence_then_sequence() {
|
||||
assert_definition!(
|
||||
r#"
|
||||
test foo() {
|
||||
{
|
||||
let a = Void
|
||||
a
|
||||
}
|
||||
let _ = True
|
||||
True
|
||||
}
|
||||
"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/parser/expr/block.rs
|
||||
description: "Code:\n\ntest foo() {\n {\n let a = Void\n a\n }\n True\n}\n"
|
||||
---
|
||||
Test(
|
||||
Function {
|
||||
arguments: [],
|
||||
body: Sequence {
|
||||
location: 38..50,
|
||||
expressions: [
|
||||
Sequence {
|
||||
location: 21..39,
|
||||
expressions: [
|
||||
Assignment {
|
||||
location: 21..33,
|
||||
value: Var {
|
||||
location: 29..33,
|
||||
name: "Void",
|
||||
},
|
||||
patterns: [
|
||||
AssignmentPattern {
|
||||
pattern: Var {
|
||||
location: 25..26,
|
||||
name: "a",
|
||||
},
|
||||
annotation: None,
|
||||
location: 25..26,
|
||||
},
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
},
|
||||
Var {
|
||||
location: 38..39,
|
||||
name: "a",
|
||||
},
|
||||
],
|
||||
},
|
||||
Var {
|
||||
location: 46..50,
|
||||
name: "True",
|
||||
},
|
||||
],
|
||||
},
|
||||
doc: None,
|
||||
location: 0..10,
|
||||
name: "foo",
|
||||
public: false,
|
||||
return_annotation: None,
|
||||
return_type: (),
|
||||
end_position: 51,
|
||||
on_test_failure: FailImmediately,
|
||||
},
|
||||
)
|
|
@ -0,0 +1,80 @@
|
|||
---
|
||||
source: crates/aiken-lang/src/parser/expr/block.rs
|
||||
description: "Code:\n\ntest foo() {\n {\n let a = Void\n a\n }\n let _ = True\n True\n}\n"
|
||||
---
|
||||
Test(
|
||||
Function {
|
||||
arguments: [],
|
||||
body: Sequence {
|
||||
location: 38..65,
|
||||
expressions: [
|
||||
Sequence {
|
||||
location: 21..39,
|
||||
expressions: [
|
||||
Assignment {
|
||||
location: 21..33,
|
||||
value: Var {
|
||||
location: 29..33,
|
||||
name: "Void",
|
||||
},
|
||||
patterns: [
|
||||
AssignmentPattern {
|
||||
pattern: Var {
|
||||
location: 25..26,
|
||||
name: "a",
|
||||
},
|
||||
annotation: None,
|
||||
location: 25..26,
|
||||
},
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
},
|
||||
Var {
|
||||
location: 38..39,
|
||||
name: "a",
|
||||
},
|
||||
],
|
||||
},
|
||||
Sequence {
|
||||
location: 46..65,
|
||||
expressions: [
|
||||
Assignment {
|
||||
location: 46..58,
|
||||
value: Var {
|
||||
location: 54..58,
|
||||
name: "True",
|
||||
},
|
||||
patterns: [
|
||||
AssignmentPattern {
|
||||
pattern: Discard {
|
||||
name: "_",
|
||||
location: 50..51,
|
||||
},
|
||||
annotation: None,
|
||||
location: 50..51,
|
||||
},
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
},
|
||||
Var {
|
||||
location: 61..65,
|
||||
name: "True",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
doc: None,
|
||||
location: 0..10,
|
||||
name: "foo",
|
||||
public: false,
|
||||
return_annotation: None,
|
||||
return_type: (),
|
||||
end_position: 66,
|
||||
on_test_failure: FailImmediately,
|
||||
},
|
||||
)
|
Loading…
Reference in New Issue