roc/compiler/test_gen/src/gen_result.rs
Ayaz Hafiz 163c6b39d6
Unify type alias "real variables"
Turns out that we can't always assume that a successful unification of
type alias type variables means that those aliases had the same real
type from the start. Because type variables may contain unbound type
variables and grow during their unification (for example,
`[InvalidNumStr]a ~ [ListWasEmpty]b` unify to give `[InvalidNumStr,
ListWasEmpty]`), the real type may grow as well.

For this reason, continue to explicitly unify alias real types for now.
We can get away with not having to do so when the type variable
unification causes no changes to the unification tree at all, but we
don't have a great way to detect that right now (maybe snapshots?)

Closes #2583
2022-04-05 11:21:52 -04:00

270 lines
4.7 KiB
Rust

#![cfg(feature = "gen-llvm")]
#[cfg(feature = "gen-llvm")]
use crate::helpers::llvm::assert_evals_to;
// #[cfg(feature = "gen-dev")]
// use crate::helpers::dev::assert_evals_to;
// #[cfg(feature = "gen-wasm")]
// use crate::helpers::wasm::assert_evals_to;
use indoc::indoc;
#[allow(unused_imports)]
use roc_std::{RocResult, RocStr};
#[test]
#[cfg(any(feature = "gen-llvm"))]
fn with_default() {
assert_evals_to!(
indoc!(
r#"
result : Result I64 {}
result = Ok 2
Result.withDefault result 0
"#
),
2,
i64
);
assert_evals_to!(
indoc!(
r#"
result : Result I64 {}
result = Err {}
Result.withDefault result 0
"#
),
0,
i64
);
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
fn result_map() {
assert_evals_to!(
indoc!(
r#"
result : Result I64 {}
result = Ok 2
result
|> Result.map (\x -> x + 1)
|> Result.withDefault 0
"#
),
3,
i64
);
assert_evals_to!(
indoc!(
r#"
result : Result I64 {}
result = Err {}
result
|> Result.map (\x -> x + 1)
|> Result.withDefault 0
"#
),
0,
i64
);
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
fn result_map_err() {
assert_evals_to!(
indoc!(
r#"
result : Result {} I64
result = Err 2
when Result.mapErr result (\x -> x + 1) is
Err n -> n
Ok _ -> 0
"#
),
3,
i64
);
assert_evals_to!(
indoc!(
r#"
result : Result {} I64
result = Ok {}
when Result.mapErr result (\x -> x + 1) is
Err n -> n
Ok _ -> 0
"#
),
0,
i64
);
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
fn err_type_var() {
assert_evals_to!(
indoc!(
r#"
Result.map (Ok 3) (\x -> x + 1)
|> Result.withDefault -1
"#
),
4,
i64
);
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
fn err_type_var_annotation() {
assert_evals_to!(
indoc!(
r#"
ok : Result I64 *
ok = Ok 3
Result.map ok (\x -> x + 1)
|> Result.withDefault -1
"#
),
4,
i64
);
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
fn err_empty_tag_union() {
assert_evals_to!(
indoc!(
r#"
ok : Result I64 []
ok = Ok 3
Result.map ok (\x -> x + 1)
|> Result.withDefault -1
"#
),
4,
i64
);
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
fn is_ok() {
assert_evals_to!(
indoc!(
r#"
result : Result I64 {}
result = Ok 2
Result.isOk result
"#
),
true,
bool
);
assert_evals_to!(
indoc!(
r#"
result : Result I64 {}
result = Err {}
Result.isOk result
"#
),
false,
bool
);
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
fn is_err() {
assert_evals_to!(
indoc!(
r#"
result : Result I64 {}
result = Ok 2
Result.isErr result
"#
),
false,
bool
);
assert_evals_to!(
indoc!(
r#"
result : Result I64 {}
result = Err {}
Result.isErr result
"#
),
true,
bool
);
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
fn roc_result_ok() {
assert_evals_to!(
indoc!(
r#"
result : Result I64 {}
result = Ok 42
result
"#
),
RocResult::ok(42),
RocResult<i64, ()>
);
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
fn roc_result_err() {
assert_evals_to!(
indoc!(
r#"
result : Result I64 Str
result = Err "foo"
result
"#
),
RocResult::err(RocStr::from("foo")),
RocResult<i64, RocStr>
);
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
fn issue_2583_specialize_errors_behind_unified_branches() {
assert_evals_to!(
r#"
if True then List.first [15] else Str.toI64 ""
"#,
RocResult::ok(15i64),
RocResult<i64, bool>
)
}