feat(backpassing): implements multi patterns
The main trick here was transforming Assignment to contain `Vec<UntypedPattern, Option<Annotation>>` in a field called patterns. This then meant that I could remove the `pattern` and `annotation` field from `Assignment`. The parser handles `=` and `<-` just fine because in the future `=` with multi patterns will mean some kind of optimization on tuples. But, since we don't have that optimization yet, when someone uses multi patterns with an `=` there will be an error returned from the type checker right where `infer_seq` looks for `backpassing`. From there the rest of the work was in `Project::backpassing` where I only needed to rework some things to work with a list of patterns instead of just one.
This commit is contained in:
@@ -1383,6 +1383,74 @@ fn backpassing_expect_type_mismatch() {
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn backpassing_multi_args() {
|
||||
let source_code = r#"
|
||||
fn fold(list: List<a>, init: b, then: fn(a, b) -> b) -> b {
|
||||
when list is {
|
||||
[] -> init
|
||||
[x, ..rest] -> fold(rest, then(x, init), then)
|
||||
}
|
||||
}
|
||||
|
||||
fn backpassing() -> Int {
|
||||
let elem, acc <- fold([1, 2, 3], 0)
|
||||
|
||||
elem + acc
|
||||
}
|
||||
"#;
|
||||
|
||||
assert!(check(parse(source_code)).is_ok())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn backpassing_multi_args_expect() {
|
||||
let source_code = r#"
|
||||
pub type Bar {
|
||||
Foo(Int)
|
||||
Wow(Int)
|
||||
}
|
||||
|
||||
fn fold(list: List<a>, init: b, then: fn(a, b) -> b) -> b {
|
||||
when list is {
|
||||
[] -> init
|
||||
[x, ..rest] -> fold(rest, then(x, init), then)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn backpassing() -> Bar {
|
||||
expect Foo(elem), Wow(acc) <- fold([Foo(1), Foo(2), Foo(3)], Wow(0))
|
||||
|
||||
Wow(elem + acc)
|
||||
}
|
||||
"#;
|
||||
|
||||
assert!(matches!(check(parse(source_code)), Ok((warnings, _)) if warnings.is_empty()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn backpassing_multi_args_using_equals() {
|
||||
let source_code = r#"
|
||||
fn fold(list: List<a>, init: b, then: fn(a, b) -> b) -> b {
|
||||
when list is {
|
||||
[] -> init
|
||||
[x, ..rest] -> fold(rest, then(x, init), then)
|
||||
}
|
||||
}
|
||||
|
||||
fn backpassing() -> Int {
|
||||
let elem, acc = fold([1, 2, 3], 0, fn(elem, acc) { elem + acc })
|
||||
|
||||
elem + acc
|
||||
}
|
||||
"#;
|
||||
|
||||
assert!(matches!(
|
||||
check(parse(source_code)),
|
||||
Err((_, Error::UnexpectedMultiPatternAssignment { .. }))
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trace_if_false_ko() {
|
||||
let source_code = r#"
|
||||
|
||||
Reference in New Issue
Block a user