feat: handle pipe fn infer TODOs
This improves error messages for `a |> b(x)`. We need to do a special check when looping over the args and unifying. This information is within a function that does not belong to pipe typer so I used a closure to forward along a way to add metadata to the error when the first argument in the loop has a unification error. Simply adding the metadata at the pipe typer level is not good enough because then we may annotate regular unification errors from the args.
This commit is contained in:
@@ -3,7 +3,7 @@ use crate::{
|
||||
builtins,
|
||||
expr::TypedExpr,
|
||||
parser,
|
||||
tipo::error::{Error, Warning},
|
||||
tipo::error::{Error, UnifyErrorSituation, Warning},
|
||||
IdGenerator,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
@@ -1006,6 +1006,104 @@ fn trace_if_false_ko() {
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pipe_with_wrong_type() {
|
||||
let source_code = r#"
|
||||
test foo() {
|
||||
True |> bar
|
||||
}
|
||||
|
||||
fn bar(n: Int) {
|
||||
n - 1
|
||||
}
|
||||
"#;
|
||||
|
||||
assert!(matches!(
|
||||
check(parse(source_code)),
|
||||
Err((
|
||||
_,
|
||||
Error::CouldNotUnify {
|
||||
situation: Some(UnifyErrorSituation::PipeTypeMismatch),
|
||||
..
|
||||
}
|
||||
))
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pipe_with_wrong_type_and_args() {
|
||||
let source_code = r#"
|
||||
test foo() {
|
||||
True |> bar(False)
|
||||
}
|
||||
|
||||
fn bar(n: Int, l: Bool) {
|
||||
n - 1
|
||||
}
|
||||
"#;
|
||||
|
||||
assert!(matches!(
|
||||
check(parse(source_code)),
|
||||
Err((
|
||||
_,
|
||||
Error::CouldNotUnify {
|
||||
situation: Some(UnifyErrorSituation::PipeTypeMismatch),
|
||||
..
|
||||
}
|
||||
))
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pipe_with_right_type_and_wrong_args() {
|
||||
let source_code = r#"
|
||||
test foo() {
|
||||
1 |> bar(1)
|
||||
}
|
||||
|
||||
fn bar(n: Int, l: Bool) {
|
||||
n - 1
|
||||
}
|
||||
"#;
|
||||
|
||||
assert!(matches!(
|
||||
check(parse(source_code)),
|
||||
Err((
|
||||
_,
|
||||
Error::CouldNotUnify {
|
||||
situation: None,
|
||||
..
|
||||
}
|
||||
))
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pipe_with_wrong_type_and_full_args() {
|
||||
let source_code = r#"
|
||||
test foo() {
|
||||
True |> bar(False)
|
||||
}
|
||||
|
||||
fn bar(l: Bool) -> fn(Int) -> Int {
|
||||
fn(n: Int) {
|
||||
n - 1
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
assert!(matches!(
|
||||
dbg!(check(parse(source_code))),
|
||||
Err((
|
||||
_,
|
||||
Error::CouldNotUnify {
|
||||
situation: Some(UnifyErrorSituation::PipeTypeMismatch),
|
||||
..
|
||||
}
|
||||
))
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn utf8_hex_literal_warning() {
|
||||
let source_code = r#"
|
||||
|
||||
Reference in New Issue
Block a user