Merge branch 'main' into patch-4

This commit is contained in:
Anton-4 2024-01-05 18:21:05 +01:00 committed by GitHub
commit 578dbf1469
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 5292 additions and 4298 deletions

2
.gitignore vendored
View file

@ -67,6 +67,8 @@ result
# It also ensures the compiler can always pull in 1 version of things and doesn't get restricted by sub lockfiles. # It also ensures the compiler can always pull in 1 version of things and doesn't get restricted by sub lockfiles.
/**/Cargo.lock /**/Cargo.lock
!/Cargo.lock !/Cargo.lock
!/examples/static-site-gen/platform/Cargo.lock
# static-site-gen exception is because of https://github.com/tkaitchuck/aHash/issues/195
# snapshot tests temp file # snapshot tests temp file
*.pending-snap *.pending-snap

129
Cargo.lock generated
View file

@ -19,13 +19,14 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.3" version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"once_cell", "once_cell",
"version_check", "version_check",
"zerocopy",
] ]
[[package]] [[package]]
@ -61,6 +62,12 @@ dependencies = [
"alloc-no-stdlib", "alloc-no-stdlib",
] ]
[[package]]
name = "allocator-api2"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
[[package]] [[package]]
name = "android-tzdata" name = "android-tzdata"
version = "0.1.1" version = "0.1.1"
@ -202,7 +209,7 @@ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"miniz_oxide", "miniz_oxide",
"object 0.32.1", "object",
"rustc-demangle", "rustc-demangle",
] ]
@ -700,7 +707,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"hashbrown 0.14.1", "hashbrown 0.14.3",
"lock_api", "lock_api",
"once_cell", "once_cell",
"parking_lot_core", "parking_lot_core",
@ -715,6 +722,17 @@ dependencies = [
"powerfmt", "powerfmt",
] ]
[[package]]
name = "derive_more"
version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "diff" name = "diff"
version = "0.1.13" version = "0.1.13"
@ -820,6 +838,12 @@ dependencies = [
"regex", "regex",
] ]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.5" version = "0.3.5"
@ -1034,7 +1058,7 @@ dependencies = [
"futures-sink", "futures-sink",
"futures-util", "futures-util",
"http", "http",
"indexmap", "indexmap 1.9.3",
"slab", "slab",
"tokio", "tokio",
"tokio-util", "tokio-util",
@ -1055,20 +1079,14 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.13.2" version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
dependencies = [ dependencies = [
"ahash", "ahash",
"bumpalo", "allocator-api2",
] ]
[[package]]
name = "hashbrown"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.4.1" version = "0.4.1"
@ -1251,6 +1269,16 @@ dependencies = [
"hashbrown 0.12.3", "hashbrown 0.12.3",
] ]
[[package]]
name = "indexmap"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [
"equivalent",
"hashbrown 0.14.3",
]
[[package]] [[package]]
name = "indoc" name = "indoc"
version = "1.0.9" version = "1.0.9"
@ -1629,24 +1657,16 @@ dependencies = [
[[package]] [[package]]
name = "object" name = "object"
version = "0.30.4" version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"flate2", "flate2",
"hashbrown 0.13.2", "hashbrown 0.14.3",
"indexmap", "indexmap 2.1.0",
"memchr",
]
[[package]]
name = "object"
version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
dependencies = [
"memchr", "memchr",
"ruzstd",
] ]
[[package]] [[package]]
@ -2145,9 +2165,9 @@ dependencies = [
[[package]] [[package]]
name = "reqwest" name = "reqwest"
version = "0.11.22" version = "0.11.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41"
dependencies = [ dependencies = [
"base64 0.21.4", "base64 0.21.4",
"bytes", "bytes",
@ -2389,7 +2409,7 @@ dependencies = [
"bitvec", "bitvec",
"bumpalo", "bumpalo",
"fnv", "fnv",
"hashbrown 0.13.2", "hashbrown 0.14.3",
"im", "im",
"im-rc", "im-rc",
"smallvec", "smallvec",
@ -2519,7 +2539,7 @@ version = "0.0.1"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"capstone", "capstone",
"object 0.30.4", "object",
"packed_struct", "packed_struct",
"roc_builtins", "roc_builtins",
"roc_can", "roc_can",
@ -2584,7 +2604,7 @@ dependencies = [
"cli_utils", "cli_utils",
"dircpy", "dircpy",
"fnv", "fnv",
"indexmap", "indexmap 2.1.0",
"indoc", "indoc",
"libc", "libc",
"libloading", "libloading",
@ -2675,7 +2695,7 @@ dependencies = [
"libc", "libc",
"mach_object", "mach_object",
"memmap2", "memmap2",
"object 0.30.4", "object",
"roc_collections", "roc_collections",
"roc_error_macros", "roc_error_macros",
"roc_load", "roc_load",
@ -2778,7 +2798,7 @@ dependencies = [
"arrayvec 0.7.4", "arrayvec 0.7.4",
"bitvec", "bitvec",
"bumpalo", "bumpalo",
"hashbrown 0.13.2", "hashbrown 0.14.3",
"parking_lot", "parking_lot",
"roc_builtins", "roc_builtins",
"roc_can", "roc_can",
@ -3275,6 +3295,17 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "ruzstd"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58c4eb8a81997cf040a091d1f7e1938aeab6749d3a0dfa73af43cdc32393483d"
dependencies = [
"byteorder",
"derive_more",
"twox-hash",
]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.15" version = "1.0.15"
@ -4128,6 +4159,16 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
[[package]]
name = "twox-hash"
version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
"cfg-if",
"static_assertions",
]
[[package]] [[package]]
name = "typed-arena" name = "typed-arena"
version = "2.0.2" version = "2.0.2"
@ -4676,3 +4717,23 @@ name = "yansi"
version = "0.5.1" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
[[package]]
name = "zerocopy"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
]

View file

@ -101,11 +101,11 @@ fnv = "1.0.7"
fs_extra = "1.3.0" fs_extra = "1.3.0"
futures = "0.3.26" futures = "0.3.26"
glyph_brush = "0.7.7" glyph_brush = "0.7.7"
hashbrown = { version = "0.13.2", features = ["bumpalo"] } hashbrown = { version = "0.14.3" }
iced-x86 = { version = "1.18.0", default-features = false, features = ["std", "decoder", "op_code_info", "instr_info"] } iced-x86 = { version = "1.18.0", default-features = false, features = ["std", "decoder", "op_code_info", "instr_info"] }
im = "15.1.0" im = "15.1.0"
im-rc = "15.1.0" im-rc = "15.1.0"
indexmap = "1.9.2" indexmap = "2.1.0"
indoc = "1.0.9" indoc = "1.0.9"
insta = "1.28.0" insta = "1.28.0"
js-sys = "0.3.61" js-sys = "0.3.61"
@ -120,7 +120,7 @@ maplit = "1.0.2"
memmap2 = "0.5.10" memmap2 = "0.5.10"
mimalloc = { version = "0.1.34", default-features = false } mimalloc = { version = "0.1.34", default-features = false }
nonempty = "0.8.1" nonempty = "0.8.1"
object = { version = "0.30.3", features = ["read", "write"] } object = { version = "0.32.2", features = ["read", "write"] }
packed_struct = "0.10.1" packed_struct = "0.10.1"
page_size = "0.5.0" page_size = "0.5.0"
palette = "0.6.1" palette = "0.6.1"
@ -139,7 +139,7 @@ quote = "1.0.23"
rand = "0.8.5" rand = "0.8.5"
regex = "1.7.1" regex = "1.7.1"
remove_dir_all = "0.8.1" remove_dir_all = "0.8.1"
reqwest = { version = "0.11.20", default-features = false, features = ["blocking", "rustls-tls"] } # default-features=false removes libopenssl as a dependency on Linux, which might not be available! reqwest = { version = "0.11.23", default-features = false, features = ["blocking", "rustls-tls"] } # default-features=false removes libopenssl as a dependency on Linux, which might not be available!
rlimit = "0.9.1" rlimit = "0.9.1"
rustyline = { git = "https://github.com/roc-lang/rustyline", rev = "e74333c" } rustyline = { git = "https://github.com/roc-lang/rustyline", rev = "e74333c" }
rustyline-derive = { git = "https://github.com/roc-lang/rustyline", rev = "e74333c" } rustyline-derive = { git = "https://github.com/roc-lang/rustyline", rev = "e74333c" }

View file

@ -280,12 +280,12 @@ mod test_can {
#[test] #[test]
fn correct_annotated_body() { fn correct_annotated_body() {
let src = indoc!( let src = indoc!(
r#" r"
f : Num.Int * -> Num.Int * f : Num.Int * -> Num.Int *
f = \ a -> a f = \ a -> a
f f
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -296,12 +296,12 @@ mod test_can {
#[test] #[test]
fn correct_annotated_body_with_comments() { fn correct_annotated_body_with_comments() {
let src = indoc!( let src = indoc!(
r#" r"
f : Num.Int * -> Num.Int * # comment f : Num.Int * -> Num.Int * # comment
f = \ a -> a f = \ a -> a
f f
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -312,12 +312,12 @@ mod test_can {
#[test] #[test]
fn name_mismatch_annotated_body() { fn name_mismatch_annotated_body() {
let src = indoc!( let src = indoc!(
r#" r"
f : Num.Int * -> Num.Int * f : Num.Int * -> Num.Int *
g = \ a -> a g = \ a -> a
g g
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -340,12 +340,12 @@ mod test_can {
#[test] #[test]
fn name_mismatch_annotated_body_with_comment() { fn name_mismatch_annotated_body_with_comment() {
let src = indoc!( let src = indoc!(
r#" r"
f : Num.Int * -> Num.Int * # comment f : Num.Int * -> Num.Int * # comment
g = \ a -> a g = \ a -> a
g g
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -368,13 +368,13 @@ mod test_can {
#[test] #[test]
fn separated_annotated_body() { fn separated_annotated_body() {
let src = indoc!( let src = indoc!(
r#" r"
f : Num.Int * -> Num.Int * f : Num.Int * -> Num.Int *
f = \ a -> a f = \ a -> a
f 42 f 42
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -389,13 +389,13 @@ mod test_can {
#[test] #[test]
fn separated_annotated_body_with_comment() { fn separated_annotated_body_with_comment() {
let src = indoc!( let src = indoc!(
r#" r"
f : Num.Int * -> Num.Int * f : Num.Int * -> Num.Int *
# comment # comment
f = \ a -> a f = \ a -> a
f 42 f 42
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -410,13 +410,13 @@ mod test_can {
#[test] #[test]
fn shadowed_annotation() { fn shadowed_annotation() {
let src = indoc!( let src = indoc!(
r#" r"
f : Num.Int * -> Num.Int * f : Num.Int * -> Num.Int *
f : Num.Int * -> Num.Int * f : Num.Int * -> Num.Int *
f f
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -432,7 +432,7 @@ mod test_can {
#[test] #[test]
fn correct_nested_unannotated_body() { fn correct_nested_unannotated_body() {
let src = indoc!( let src = indoc!(
r#" r"
f : Num.Int * f : Num.Int *
f = f =
g = 42 g = 42
@ -440,7 +440,7 @@ mod test_can {
g + 1 g + 1
f f
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -451,7 +451,7 @@ mod test_can {
#[test] #[test]
fn correct_nested_annotated_body() { fn correct_nested_annotated_body() {
let src = indoc!( let src = indoc!(
r#" r"
f : Num.Int * f : Num.Int *
f = f =
g : Num.Int * g : Num.Int *
@ -460,7 +460,7 @@ mod test_can {
g + 1 g + 1
f f
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -471,7 +471,7 @@ mod test_can {
#[test] #[test]
fn correct_nested_body_annotated_multiple_lines() { fn correct_nested_body_annotated_multiple_lines() {
let src = indoc!( let src = indoc!(
r#" r"
f : Num.Int * f : Num.Int *
f = f =
g : Num.Int * g : Num.Int *
@ -482,7 +482,7 @@ mod test_can {
g + h + z g + h + z
f f
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -493,7 +493,7 @@ mod test_can {
#[test] #[test]
fn correct_nested_body_unannotated_multiple_lines() { fn correct_nested_body_unannotated_multiple_lines() {
let src = indoc!( let src = indoc!(
r#" r"
f : Num.Int * f : Num.Int *
f = f =
g = 42 g = 42
@ -503,7 +503,7 @@ mod test_can {
g + h + z g + h + z
f f
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -513,7 +513,7 @@ mod test_can {
#[test] #[test]
fn correct_double_nested_body() { fn correct_double_nested_body() {
let src = indoc!( let src = indoc!(
r#" r"
f : Num.Int * f : Num.Int *
f = f =
g = g =
@ -523,7 +523,7 @@ mod test_can {
f f
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -534,13 +534,13 @@ mod test_can {
#[test] #[test]
fn annotation_followed_with_unrelated_affectation() { fn annotation_followed_with_unrelated_affectation() {
let src = indoc!( let src = indoc!(
r#" r"
F : Str F : Str
x = 1 x = 1
x x
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -554,7 +554,7 @@ mod test_can {
#[test] #[test]
fn two_annotations_followed_with_unrelated_affectation() { fn two_annotations_followed_with_unrelated_affectation() {
let src = indoc!( let src = indoc!(
r#" r"
G : Str G : Str
F : {} F : {}
@ -562,7 +562,7 @@ mod test_can {
x = 1 x = 1
x x
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -581,11 +581,11 @@ mod test_can {
// // it only exists in the closure's arguments. // // it only exists in the closure's arguments.
// let arena = Bump::new(); // let arena = Bump::new();
// let src = indoc!( // let src = indoc!(
// r#" // r"
// func = \arg -> arg // func = \arg -> arg
// func 2 // func 2
// "# // "
// ); // );
// let (_actual, output, problems, _var_store, _vars, _constraint) = // let (_actual, output, problems, _var_store, _vars, _constraint) =
// can_expr_with(&arena, test_home(), src); // can_expr_with(&arena, test_home(), src);
@ -608,13 +608,13 @@ mod test_can {
// fn call_by_pointer_for_fn_args() { // fn call_by_pointer_for_fn_args() {
// // This function will get passed in as a pointer. // // This function will get passed in as a pointer.
// let src = indoc!( // let src = indoc!(
// r#" // r"
// apply = \f, x -> f x // apply = \f, x -> f x
// identity = \a -> a // identity = \a -> a
// apply identity 5 // apply identity 5
// "# // "
// ); // );
// let arena = Bump::new(); // let arena = Bump::new();
// let (_actual, output, problems, _var_store, _vars, _constraint) = // let (_actual, output, problems, _var_store, _vars, _constraint) =
@ -637,9 +637,9 @@ mod test_can {
#[test] #[test]
fn incorrect_optional_value() { fn incorrect_optional_value() {
let src = indoc!( let src = indoc!(
r#" r"
{ x ? 42 } { x ? 42 }
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { let CanExprOut {
@ -911,7 +911,7 @@ mod test_can {
#[test] #[test]
fn recognize_tail_calls() { fn recognize_tail_calls() {
let src = indoc!( let src = indoc!(
r#" r"
g = \x -> g = \x ->
when x is when x is
0 -> 0 0 -> 0
@ -936,7 +936,7 @@ mod test_can {
{ x: p, y: h } { x: p, y: h }
) )
) )
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { let CanExprOut {
@ -963,7 +963,7 @@ mod test_can {
// #[test] // #[test]
// fn reproduce_incorrect_unused_defs() { // fn reproduce_incorrect_unused_defs() {
// let src = indoc!( // let src = indoc!(
// r#" // r"
// g = \x -> // g = \x ->
// when x is // when x is
// 0 -> 0 // 0 -> 0
@ -983,7 +983,7 @@ mod test_can {
// # variables must be (indirectly) referenced in the body for analysis to work // # variables must be (indirectly) referenced in the body for analysis to work
// # { x: p, y: h } // # { x: p, y: h }
// g // g
// "# // "
// ); // );
// let arena = Bump::new(); // let arena = Bump::new();
// let CanExprOut { // let CanExprOut {
@ -1012,14 +1012,14 @@ mod test_can {
#[test] #[test]
fn when_tail_call() { fn when_tail_call() {
let src = indoc!( let src = indoc!(
r#" r"
g = \x -> g = \x ->
when x is when x is
0 -> 0 0 -> 0
_ -> g (x + 1) _ -> g (x + 1)
g 0 g 0
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { let CanExprOut {
@ -1034,11 +1034,11 @@ mod test_can {
#[test] #[test]
fn immediate_tail_call() { fn immediate_tail_call() {
let src = indoc!( let src = indoc!(
r#" r"
f = \x -> f x f = \x -> f x
f 0 f 0
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { let CanExprOut {
@ -1055,13 +1055,13 @@ mod test_can {
#[test] #[test]
fn when_condition_is_no_tail_call() { fn when_condition_is_no_tail_call() {
let src = indoc!( let src = indoc!(
r#" r"
q = \x -> q = \x ->
when q x is when q x is
_ -> 0 _ -> 0
q 0 q 0
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { let CanExprOut {
@ -1076,7 +1076,7 @@ mod test_can {
#[test] #[test]
fn good_mutual_recursion() { fn good_mutual_recursion() {
let src = indoc!( let src = indoc!(
r#" r"
q = \x -> q = \x ->
when x is when x is
0 -> 0 0 -> 0
@ -1088,7 +1088,7 @@ mod test_can {
_ -> q (x - 1) _ -> q (x - 1)
q p q p
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { let CanExprOut {
@ -1107,11 +1107,11 @@ mod test_can {
#[test] #[test]
fn valid_self_recursion() { fn valid_self_recursion() {
let src = indoc!( let src = indoc!(
r#" r"
boom = \_ -> boom {} boom = \_ -> boom {}
boom boom
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { let CanExprOut {
@ -1128,13 +1128,13 @@ mod test_can {
#[test] #[test]
fn invalid_mutual_recursion() { fn invalid_mutual_recursion() {
let src = indoc!( let src = indoc!(
r#" r"
x = y x = y
y = z y = z
z = x z = x
x x
"# "
); );
let home = test_home(); let home = test_home();
let arena = Bump::new(); let arena = Bump::new();
@ -1176,11 +1176,11 @@ mod test_can {
#[test] #[test]
fn dict() { fn dict() {
let src = indoc!( let src = indoc!(
r#" r"
x = Dict.empty {} x = Dict.empty {}
Dict.len x Dict.len x
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -1191,7 +1191,7 @@ mod test_can {
#[test] #[test]
fn unused_def_regression() { fn unused_def_regression() {
let src = indoc!( let src = indoc!(
r#" r"
Booly : [Yes, No, Maybe] Booly : [Yes, No, Maybe]
y : Booly y : Booly
@ -1205,7 +1205,7 @@ mod test_can {
x = [y] x = [y]
x x
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -1216,14 +1216,14 @@ mod test_can {
#[test] #[test]
fn optional_field_not_unused() { fn optional_field_not_unused() {
let src = indoc!( let src = indoc!(
r#" r"
fallbackZ = 3 fallbackZ = 3
fn = \{ x, y, z ? fallbackZ } -> fn = \{ x, y, z ? fallbackZ } ->
{ x, y, z } { x, y, z }
fn { x: 0, y: 1 } fn { x: 0, y: 1 }
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -1234,12 +1234,12 @@ mod test_can {
#[test] #[test]
fn issue_2534() { fn issue_2534() {
let src = indoc!( let src = indoc!(
r#" r"
x = { a: 1 } x = { a: 1 }
{ {
x & a: 2 x & a: 2
} }
"# "
); );
let arena = Bump::new(); let arena = Bump::new();
let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src); let CanExprOut { problems, .. } = can_expr_with(&arena, test_home(), src);
@ -1252,13 +1252,13 @@ mod test_can {
// // "local" should be used, because the closure used it. // // "local" should be used, because the closure used it.
// // However, "unused" should be unused. // // However, "unused" should be unused.
// let (_, output, problems, _) = can_expr(indoc!( // let (_, output, problems, _) = can_expr(indoc!(
// r#" // r"
// local = 5 // local = 5
// unused = 6 // unused = 6
// func = \arg -> arg + local // func = \arg -> arg + local
// 3 + func 2 // 3 + func 2
// "# // "
// )); // ));
// assert_eq!( // assert_eq!(
@ -1283,13 +1283,13 @@ mod test_can {
//fn unused_closure() { //fn unused_closure() {
// // "unused" should be unused because it's in func, which is unused. // // "unused" should be unused because it's in func, which is unused.
// let (_, output, problems, _) = can_expr(indoc!( // let (_, output, problems, _) = can_expr(indoc!(
// r#" // r"
// local = 5 // local = 5
// unused = 6 // unused = 6
// func = \arg -> arg + unused // func = \arg -> arg + unused
// local // local
// "# // "
// )); // ));
// assert_eq!( // assert_eq!(
@ -1316,9 +1316,9 @@ mod test_can {
// #[test] // #[test]
// fn basic_unrecognized_constant() { // fn basic_unrecognized_constant() {
// let (expr, output, problems, _) = can_expr(indoc!( // let (expr, output, problems, _) = can_expr(indoc!(
// r#" // r"
// x // x
// "# // "
// )); // ));
// assert_eq!( // assert_eq!(
@ -1342,12 +1342,12 @@ mod test_can {
//#[test] //#[test]
//fn complex_unrecognized_constant() { //fn complex_unrecognized_constant() {
// let (_, output, problems, _) = can_expr(indoc!( // let (_, output, problems, _) = can_expr(indoc!(
// r#" // r"
// a = 5 // a = 5
// b = 6 // b = 6
// a + b * z // a + b * z
// "# // "
// )); // ));
// assert_eq!( // assert_eq!(
@ -1375,13 +1375,13 @@ mod test_can {
// // This should report that both a and b are unused, since the return expr never references them. // // This should report that both a and b are unused, since the return expr never references them.
// // It should not report them as circular, since we haven't solved the halting problem here. // // It should not report them as circular, since we haven't solved the halting problem here.
// let (_, output, problems, _) = can_expr(indoc!( // let (_, output, problems, _) = can_expr(indoc!(
// r#" // r"
// a = \arg -> if arg > 0 then b 7 else 0 // a = \arg -> if arg > 0 then b 7 else 0
// b = \arg -> if arg > 0 then a (arg - 1) else 0 // b = \arg -> if arg > 0 then a (arg - 1) else 0
// c = 5 // c = 5
// c // c
// "# // "
// )); // ));
// assert_eq!(problems, vec![unused("a"), unused("b")]); // assert_eq!(problems, vec![unused("a"), unused("b")]);
@ -1400,7 +1400,7 @@ mod test_can {
//#[test] //#[test]
//fn can_fibonacci() { //fn can_fibonacci() {
// let (_, output, problems, _) = can_expr(indoc!( // let (_, output, problems, _) = can_expr(indoc!(
// r#" // r"
// fibonacci = \num -> // fibonacci = \num ->
// if num < 2 then // if num < 2 then
// num // num
@ -1408,7 +1408,7 @@ mod test_can {
// fibonacci (num - 1) + fibonacci (num - 2) // fibonacci (num - 1) + fibonacci (num - 2)
// fibonacci 9 // fibonacci 9
// "# // "
// )); // ));
// assert_eq!(problems, vec![]); // assert_eq!(problems, vec![]);
@ -1430,7 +1430,7 @@ mod test_can {
// // is considered a tail call, even though it only // // is considered a tail call, even though it only
// // calls itself from one branch! // // calls itself from one branch!
// let (_, output, problems, _) = can_expr(indoc!( // let (_, output, problems, _) = can_expr(indoc!(
// r#" // r"
// factorial = \num -> // factorial = \num ->
// factorialHelp num 0 // factorialHelp num 0
@ -1441,7 +1441,7 @@ mod test_can {
// factorialHelp (num - 1) (total * num) // factorialHelp (num - 1) (total * num)
// factorial 9 // factorial 9
// "# // "
// )); // ));
// assert_eq!(problems, vec![]); // assert_eq!(problems, vec![]);
@ -1462,12 +1462,12 @@ mod test_can {
// // This should report that neither a nor b are unused, // // This should report that neither a nor b are unused,
// // since if you never call a function but do return it, that's okay! // // since if you never call a function but do return it, that's okay!
// let (_, output, problems, _) = can_expr(indoc!( // let (_, output, problems, _) = can_expr(indoc!(
// r#" // r"
// a = \_ -> 42 // a = \_ -> 42
// b = a // b = a
// b // b
// "# // "
// )); // ));
// assert_eq!(problems, Vec::new()); // assert_eq!(problems, Vec::new());
@ -1488,14 +1488,14 @@ mod test_can {
//#[test] //#[test]
//fn reorder_assignments() { //fn reorder_assignments() {
// let (expr, output, problems, _) = can_expr(indoc!( // let (expr, output, problems, _) = can_expr(indoc!(
// r#" // r"
// increment = \arg -> arg + 1 // increment = \arg -> arg + 1
// z = (increment 2) + y // z = (increment 2) + y
// y = x + 1 // y = x + 1
// x = 9 // x = 9
// z * 3 // z * 3
// "# // "
// )); // ));
// assert_eq!(problems, vec![]); // assert_eq!(problems, vec![]);
@ -1526,7 +1526,7 @@ mod test_can {
//#[test] //#[test]
//fn reorder_closed_over_assignments() { //fn reorder_closed_over_assignments() {
// let (expr, output, problems, _) = can_expr(indoc!( // let (expr, output, problems, _) = can_expr(indoc!(
// r#" // r"
// z = func1 x // z = func1 x
// x = 9 // x = 9
// y = func2 3 // y = func2 3
@ -1534,7 +1534,7 @@ mod test_can {
// func2 = \arg -> arg + x // func2 = \arg -> arg + x
// z // z
// "# // "
// )); // ));
// assert_eq!(problems, vec![]); // assert_eq!(problems, vec![]);
@ -1628,14 +1628,14 @@ mod test_can {
//#[test] //#[test]
//fn circular_assignment() { //fn circular_assignment() {
// let (_, _, problems, _) = can_expr(indoc!( // let (_, _, problems, _) = can_expr(indoc!(
// r#" // r"
// c = d + 3 // c = d + 3
// b = 2 + c // b = 2 + c
// d = a + 7 // d = a + 7
// a = b + 1 // a = b + 1
// 2 + d // 2 + d
// "# // "
// )); // ));
// assert_eq!( // assert_eq!(
@ -1655,9 +1655,9 @@ mod test_can {
// // There was a bug where this reported UnusedArgument("val") // // There was a bug where this reported UnusedArgument("val")
// // since it was used only in the returned function only. // // since it was used only in the returned function only.
// let (_, _, problems, _) = can_expr(indoc!( // let (_, _, problems, _) = can_expr(indoc!(
// r#" // r"
// \val -> \_ -> val // \val -> \_ -> val
// "# // "
// )); // ));
// assert_eq!(problems, vec![]); // assert_eq!(problems, vec![]);
@ -1831,7 +1831,7 @@ mod test_can {
// "abcd\\(efg)hij" // "abcd\\(efg)hij"
// "# // "#
// ), // ),
// Str(r#"abcd\(efg)hij"#.into()), // Str(r"abcd\(efg)hij".into()),
// ); // );
// } // }
@ -1848,7 +1848,7 @@ mod test_can {
// #[test] // #[test]
// fn string_with_special_escapes() { // fn string_with_special_escapes() {
// expect_parsed_str(r#"x\x"#, r#""x\\x""#); // expect_parsed_str(r"x\x", r#""x\\x""#);
// expect_parsed_str(r#"x"x"#, r#""x\"x""#); // expect_parsed_str(r#"x"x"#, r#""x\"x""#);
// expect_parsed_str("x\tx", r#""x\tx""#); // expect_parsed_str("x\tx", r#""x\tx""#);
// expect_parsed_str("x\rx", r#""x\rx""#); // expect_parsed_str("x\rx", r#""x\rx""#);

View file

@ -30,9 +30,6 @@ pub type SendMap<K, V> = im::hashmap::HashMap<K, V, BuildHasher>;
pub type SendSet<K> = im::hashset::HashSet<K, BuildHasher>; pub type SendSet<K> = im::hashset::HashSet<K, BuildHasher>;
// pub type BumpMap<'a, K, V> = hashbrown::HashMap<K, V, BuildHasher, hashbrown::BumpWrapper<'a>>;
// pub type BumpSet<'a, K> = hashbrown::HashSet<K, BuildHasher, hashbrown::BumpWrapper<'a>>;
pub type BumpMap<K, V> = hashbrown::HashMap<K, V, BuildHasher>; pub type BumpMap<K, V> = hashbrown::HashMap<K, V, BuildHasher>;
pub type BumpSet<K> = hashbrown::HashSet<K, BuildHasher>; pub type BumpSet<K> = hashbrown::HashSet<K, BuildHasher>;
@ -46,32 +43,20 @@ pub trait BumpMapDefault<'a> {
impl<'a, K, V> BumpMapDefault<'a> for BumpMap<K, V> { impl<'a, K, V> BumpMapDefault<'a> for BumpMap<K, V> {
fn new_in(_arena: &'a bumpalo::Bump) -> Self { fn new_in(_arena: &'a bumpalo::Bump) -> Self {
// hashbrown::HashMap::with_hasher_in(default_hasher(), hashbrown::BumpWrapper(arena))
hashbrown::HashMap::with_hasher(default_hasher()) hashbrown::HashMap::with_hasher(default_hasher())
} }
fn with_capacity_in(capacity: usize, _arena: &'a bumpalo::Bump) -> Self { fn with_capacity_in(capacity: usize, _arena: &'a bumpalo::Bump) -> Self {
// hashbrown::HashMap::with_capacity_and_hasher_in(
// capacity,
// default_hasher(),
// hashbrown::BumpWrapper(arena),
// )
hashbrown::HashMap::with_capacity_and_hasher(capacity, default_hasher()) hashbrown::HashMap::with_capacity_and_hasher(capacity, default_hasher())
} }
} }
impl<'a, K> BumpMapDefault<'a> for BumpSet<K> { impl<'a, K> BumpMapDefault<'a> for BumpSet<K> {
fn new_in(_arena: &'a bumpalo::Bump) -> Self { fn new_in(_arena: &'a bumpalo::Bump) -> Self {
// hashbrown::HashSet::with_hasher_in(default_hasher(), hashbrown::BumpWrapper(arena))
hashbrown::HashSet::with_hasher(default_hasher()) hashbrown::HashSet::with_hasher(default_hasher())
} }
fn with_capacity_in(capacity: usize, _arena: &'a bumpalo::Bump) -> Self { fn with_capacity_in(capacity: usize, _arena: &'a bumpalo::Bump) -> Self {
// hashbrown::HashSet::with_capacity_and_hasher_in(
// capacity,
// default_hasher(),
// hashbrown::BumpWrapper(arena),
// )
hashbrown::HashSet::with_capacity_and_hasher(capacity, default_hasher()) hashbrown::HashSet::with_capacity_and_hasher(capacity, default_hasher())
} }
} }

View file

@ -1424,9 +1424,38 @@ impl<
} }
fn build_num_mul(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) { fn build_num_mul(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &InLayout<'a>) {
// for the time being, `num_mul` is implemented as wrapping multiplication. In roc, the normal match self.layout_interner.get_repr(*layout) {
// `mul` should panic on overflow, but we just don't do that yet LayoutRepr::Builtin(Builtin::Int(int_width)) => self.build_fn_call(
self.build_num_mul_wrap(dst, src1, src2, layout) dst,
bitcode::NUM_MUL_OR_PANIC_INT[int_width].to_string(),
&[*src1, *src2],
&[*layout, *layout],
layout,
),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src1_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src1);
let src2_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src2);
ASM::mul_freg64_freg64_freg64(&mut self.buf, dst_reg, src1_reg, src2_reg);
}
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
let src1_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src1);
let src2_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src2);
ASM::mul_freg32_freg32_freg32(&mut self.buf, dst_reg, src1_reg, src2_reg);
}
LayoutRepr::DEC => self.build_fn_call(
dst,
bitcode::DEC_MUL_OR_PANIC.to_string(),
&[*src1, *src2],
&[Layout::DEC, Layout::DEC],
&Layout::DEC,
),
other => unreachable!("NumMul for layout {other:?}"),
}
} }
fn build_num_mul_wrap( fn build_num_mul_wrap(

View file

@ -523,12 +523,12 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Syste
use X86_64GeneralReg::*; use X86_64GeneralReg::*;
type ASM = X86_64Assembler; type ASM = X86_64Assembler;
// move the first argument to roc_panic (a *RocStr) into r8 // move the first argument to roc_panic (a *const RocStr) into r8
ASM::add_reg64_reg64_imm32(buf, R8, RSP, 8); ASM::mov_reg64_reg64(buf, R8, RDI);
// move the crash tag into the second return register. We add 1 to it because the 0 value // move the crash tag into the second return register. We add 1 to it because the 0 value
// is already used for "no crash occurred" // is already used for "no crash occurred"
ASM::add_reg64_reg64_imm32(buf, RDX, RDI, 1); ASM::add_reg64_reg64_imm32(buf, RDX, RSI, 1);
// the setlongjmp_buffer // the setlongjmp_buffer
ASM::data_pointer(buf, relocs, String::from("setlongjmp_buffer"), RDI); ASM::data_pointer(buf, relocs, String::from("setlongjmp_buffer"), RDI);

View file

@ -668,14 +668,22 @@ trait Backend<'a> {
&Literal::Int((crash_tag as u128).to_ne_bytes()), &Literal::Int((crash_tag as u128).to_ne_bytes()),
); );
// this function gets a RocStr, but the roc_panic defined by a platform expects a `*RocStr`.
// we store the value in a global variable and then use a pointer to this global
let panic_msg_ptr = self.debug_symbol("panic_msg_ptr");
let ignored = self.debug_symbol("ignored");
self.build_data_pointer(&panic_msg_ptr, "panic_msg".to_string());
self.load_literal_symbols(&[msg]);
self.build_ptr_store(ignored, panic_msg_ptr, msg, Layout::STR);
// Now that the arguments are needed, load them if they are literals. // Now that the arguments are needed, load them if they are literals.
let arguments = &[msg, error_message]; let arguments = &[panic_msg_ptr, error_message];
self.load_literal_symbols(arguments); self.load_literal_symbols(arguments);
self.build_fn_call( self.build_fn_call(
&Symbol::DEV_TMP2, &Symbol::DEV_TMP2,
String::from("roc_panic"), String::from("roc_panic"),
arguments, arguments,
&[Layout::STR, Layout::U32], &[Layout::U64, Layout::U32],
&Layout::UNIT, &Layout::UNIT,
); );

View file

@ -159,6 +159,30 @@ fn define_setlongjmp_buffer(output: &mut Object) -> SymbolId {
symbol_id symbol_id
} }
// needed to implement Crash when setjmp/longjmp is used
fn define_panic_msg(output: &mut Object) -> SymbolId {
let bss_section = output.section_id(StandardSection::Data);
// 3 words for a RocStr
const SIZE: usize = 3 * core::mem::size_of::<u64>();
let symbol = Symbol {
name: b"panic_msg".to_vec(),
value: 0,
size: SIZE as u64,
kind: SymbolKind::Data,
scope: SymbolScope::Linkage,
weak: false,
section: SymbolSection::Section(bss_section),
flags: SymbolFlags::None,
};
let symbol_id = output.add_symbol(symbol);
output.add_symbol_data(symbol_id, bss_section, &[0x00; SIZE], 8);
symbol_id
}
fn generate_setjmp<'a, B: Backend<'a>>(backend: &mut B, output: &mut Object) { fn generate_setjmp<'a, B: Backend<'a>>(backend: &mut B, output: &mut Object) {
let text_section = output.section_id(StandardSection::Text); let text_section = output.section_id(StandardSection::Text);
let proc_symbol = Symbol { let proc_symbol = Symbol {
@ -422,6 +446,7 @@ fn build_object<'a, B: Backend<'a>>(
*/ */
if backend.env().mode.generate_roc_panic() { if backend.env().mode.generate_roc_panic() {
define_panic_msg(&mut output);
define_setlongjmp_buffer(&mut output); define_setlongjmp_buffer(&mut output);
generate_roc_panic(&mut backend, &mut output); generate_roc_panic(&mut backend, &mut output);

File diff suppressed because it is too large Load diff

View file

@ -325,7 +325,7 @@ fn import_transitive_alias() {
( (
"RBTree", "RBTree",
indoc!( indoc!(
r#" r"
interface RBTree exposes [RedBlackTree, empty] imports [] interface RBTree exposes [RedBlackTree, empty] imports []
# The color of a node. Leaves are considered Black. # The color of a node. Leaves are considered Black.
@ -337,18 +337,18 @@ fn import_transitive_alias() {
empty : RedBlackTree k v empty : RedBlackTree k v
empty = empty =
Empty Empty
"# "
), ),
), ),
( (
"Other", "Other",
indoc!( indoc!(
r#" r"
interface Other exposes [empty] imports [RBTree] interface Other exposes [empty] imports [RBTree]
empty : RBTree.RedBlackTree I64 I64 empty : RBTree.RedBlackTree I64 I64
empty = RBTree.empty empty = RBTree.empty
"# "
), ),
), ),
]; ];
@ -628,11 +628,11 @@ fn parse_problem() {
let modules = vec![( let modules = vec![(
"Main", "Main",
indoc!( indoc!(
r#" r"
interface Main exposes [main] imports [] interface Main exposes [main] imports []
main = [ main = [
"# "
), ),
)]; )];
@ -820,23 +820,23 @@ fn opaque_wrapped_unwrapped_outside_defining_module() {
( (
"Age", "Age",
indoc!( indoc!(
r#" r"
interface Age exposes [Age] imports [] interface Age exposes [Age] imports []
Age := U32 Age := U32
"# "
), ),
), ),
( (
"Main", "Main",
indoc!( indoc!(
r#" r"
interface Main exposes [twenty, readAge] imports [Age.{ Age }] interface Main exposes [twenty, readAge] imports [Age.{ Age }]
twenty = @Age 20 twenty = @Age 20
readAge = \@Age n -> n readAge = \@Age n -> n
"# "
), ),
), ),
]; ];
@ -846,7 +846,7 @@ fn opaque_wrapped_unwrapped_outside_defining_module() {
assert_eq!( assert_eq!(
err, err,
indoc!( indoc!(
r#" r"
OPAQUE TYPE DECLARED OUTSIDE SCOPE ...rapped_outside_defining_module/Main OPAQUE TYPE DECLARED OUTSIDE SCOPE ...rapped_outside_defining_module/Main
The unwrapped opaque type Age referenced here: The unwrapped opaque type Age referenced here:
@ -883,7 +883,7 @@ fn opaque_wrapped_unwrapped_outside_defining_module() {
^^^^^^^^^^^ ^^^^^^^^^^^
Since Age isn't used, you don't need to import it. Since Age isn't used, you don't need to import it.
"# "
), ),
"\n{}", "\n{}",
err err
@ -993,11 +993,11 @@ fn module_doesnt_match_file_path() {
let modules = vec![( let modules = vec![(
"Age", "Age",
indoc!( indoc!(
r#" r"
interface NotAge exposes [Age] imports [] interface NotAge exposes [Age] imports []
Age := U32 Age := U32
"# "
), ),
)]; )];
@ -1005,7 +1005,7 @@ fn module_doesnt_match_file_path() {
assert_eq!( assert_eq!(
err, err,
indoc!( indoc!(
r#" r"
WEIRD MODULE NAME tmp/module_doesnt_match_file_path/Age WEIRD MODULE NAME tmp/module_doesnt_match_file_path/Age
This module name does not correspond with the file path it is defined This module name does not correspond with the file path it is defined
@ -1016,7 +1016,7 @@ fn module_doesnt_match_file_path() {
Module names must correspond with the file paths they are defined in. Module names must correspond with the file paths they are defined in.
For example, I expect to see BigNum defined in BigNum.roc, or Math.Sin For example, I expect to see BigNum defined in BigNum.roc, or Math.Sin
defined in Math/Sin.roc."# defined in Math/Sin.roc."
), ),
"\n{}", "\n{}",
err err
@ -1028,9 +1028,9 @@ fn module_cyclic_import_itself() {
let modules = vec![( let modules = vec![(
"Age", "Age",
indoc!( indoc!(
r#" r"
interface Age exposes [] imports [Age] interface Age exposes [] imports [Age]
"# "
), ),
)]; )];
@ -1038,7 +1038,7 @@ fn module_cyclic_import_itself() {
assert_eq!( assert_eq!(
err, err,
indoc!( indoc!(
r#" r"
IMPORT CYCLE tmp/module_cyclic_import_itself/Age IMPORT CYCLE tmp/module_cyclic_import_itself/Age
I can't compile Age because it depends on itself through the following I can't compile Age because it depends on itself through the following
@ -1052,7 +1052,7 @@ fn module_cyclic_import_itself() {
Cyclic dependencies are not allowed in Roc! Can you restructure a Cyclic dependencies are not allowed in Roc! Can you restructure a
module in this import chain so that it doesn't have to depend on module in this import chain so that it doesn't have to depend on
itself?"# itself?"
), ),
"\n{}", "\n{}",
err err
@ -1065,17 +1065,17 @@ fn module_cyclic_import_transitive() {
( (
"Age", "Age",
indoc!( indoc!(
r#" r"
interface Age exposes [] imports [Person] interface Age exposes [] imports [Person]
"# "
), ),
), ),
( (
"Person", "Person",
indoc!( indoc!(
r#" r"
interface Person exposes [] imports [Age] interface Person exposes [] imports [Age]
"# "
), ),
), ),
]; ];
@ -1084,7 +1084,7 @@ fn module_cyclic_import_transitive() {
assert_eq!( assert_eq!(
err, err,
indoc!( indoc!(
r#" r"
IMPORT CYCLE tmp/module_cyclic_import_transitive/Age.roc IMPORT CYCLE tmp/module_cyclic_import_transitive/Age.roc
I can't compile Age because it depends on itself through the following I can't compile Age because it depends on itself through the following
@ -1100,7 +1100,7 @@ fn module_cyclic_import_transitive() {
Cyclic dependencies are not allowed in Roc! Can you restructure a Cyclic dependencies are not allowed in Roc! Can you restructure a
module in this import chain so that it doesn't have to depend on module in this import chain so that it doesn't have to depend on
itself?"# itself?"
), ),
"\n{}", "\n{}",
err err
@ -1113,17 +1113,17 @@ fn nested_module_has_incorrect_name() {
( (
"Dep/Foo.roc", "Dep/Foo.roc",
indoc!( indoc!(
r#" r"
interface Foo exposes [] imports [] interface Foo exposes [] imports []
"# "
), ),
), ),
( (
"I.roc", "I.roc",
indoc!( indoc!(
r#" r"
interface I exposes [] imports [Dep.Foo] interface I exposes [] imports [Dep.Foo]
"# "
), ),
), ),
]; ];
@ -1132,7 +1132,7 @@ fn nested_module_has_incorrect_name() {
assert_eq!( assert_eq!(
err, err,
indoc!( indoc!(
r#" r"
INCORRECT MODULE NAME tmp/nested_module_has_incorrect_name/Dep/Foo.roc INCORRECT MODULE NAME tmp/nested_module_has_incorrect_name/Dep/Foo.roc
This module has a different name than I expected: This module has a different name than I expected:
@ -1142,7 +1142,7 @@ fn nested_module_has_incorrect_name() {
Based on the nesting and use of this module, I expect it to have name Based on the nesting and use of this module, I expect it to have name
Dep.Foo"# Dep.Foo"
), ),
"\n{}", "\n{}",
err err

View file

@ -272,11 +272,11 @@ mod test_parse {
let arena = Bump::new(); let arena = Bump::new();
let src = indoc!( let src = indoc!(
r#" r"
foo = \list -> foo = \list ->
isTest = \_ -> 5 isTest = \_ -> 5
List.map list isTest List.map list isTest
"# "
); );
let actual = module_defs() let actual = module_defs()
.parse(&arena, State::new(src.as_bytes()), 0) .parse(&arena, State::new(src.as_bytes()), 0)
@ -295,12 +295,12 @@ mod test_parse {
// highlights a problem with the else branch demanding a newline after its expression // highlights a problem with the else branch demanding a newline after its expression
let src = indoc!( let src = indoc!(
r#" r"
main = main =
v = \y -> if x then y else z v = \y -> if x then y else z
1 1
"# "
); );
let state = State::new(src.as_bytes()); let state = State::new(src.as_bytes());

File diff suppressed because it is too large Load diff

View file

@ -542,7 +542,7 @@ mod encode_immediate {
_ -> "<bad>" _ -> "<bad>"
"# "#
), $num, stringify!($typ)), ), $num, stringify!($typ)),
RocStr::from(format!(r#"{}"#, $num).as_str()), RocStr::from(format!(r"{}", $num).as_str()),
RocStr RocStr
) )
} }
@ -1011,7 +1011,7 @@ fn decode_derive_decoder_for_opaque() {
_ -> "FAIL" _ -> "FAIL"
"# "#
), ),
RocStr::from(r#"Hello, World!"#), RocStr::from(r"Hello, World!"),
RocStr RocStr
) )
} }
@ -1458,7 +1458,7 @@ mod hash {
use indoc::indoc; use indoc::indoc;
const TEST_HASHER: &str = indoc!( const TEST_HASHER: &str = indoc!(
r#" r"
THasher := List U8 implements [Hasher { THasher := List U8 implements [Hasher {
addBytes: tAddBytes, addBytes: tAddBytes,
addU8: tAddU8, addU8: tAddU8,
@ -1507,7 +1507,7 @@ mod hash {
tComplete = \@THasher _ -> Num.maxU64 tComplete = \@THasher _ -> Num.maxU64
tRead = \@THasher bytes -> bytes tRead = \@THasher bytes -> bytes
"# "
); );
fn build_test(input: &str) -> String { fn build_test(input: &str) -> String {
@ -1668,7 +1668,7 @@ mod hash {
#[test] #[test]
fn list_u8() { fn list_u8() {
assert_evals_to!( assert_evals_to!(
&build_test(r#"[15u8, 23u8, 37u8]"#), &build_test(r"[15u8, 23u8, 37u8]"),
RocList::from_slice(&[15, 23, 37]), RocList::from_slice(&[15, 23, 37]),
RocList<u8> RocList<u8>
) )
@ -1700,7 +1700,7 @@ mod hash {
#[test] #[test]
fn empty_record() { fn empty_record() {
assert_evals_to!( assert_evals_to!(
&build_test(r#"{}"#), &build_test(r"{}"),
RocList::from_slice(&[] as &[u8]), RocList::from_slice(&[] as &[u8]),
RocList<u8> RocList<u8>
) )
@ -1728,7 +1728,7 @@ mod hash {
fn record_of_list_of_records() { fn record_of_list_of_records() {
assert_evals_to!( assert_evals_to!(
&build_test( &build_test(
r#"{ a: [ { b: 15u8 }, { b: 23u8 } ], b: [ { c: 45u8 }, { c: 73u8 } ] }"# r"{ a: [ { b: 15u8 }, { b: 23u8 } ], b: [ { c: 45u8 }, { c: 73u8 } ] }"
), ),
RocList::from_slice(&[15, 23, 45, 73]), RocList::from_slice(&[15, 23, 45, 73]),
RocList<u8> RocList<u8>
@ -1757,7 +1757,7 @@ mod hash {
fn tuple_of_list_of_tuples() { fn tuple_of_list_of_tuples() {
assert_evals_to!( assert_evals_to!(
&build_test( &build_test(
r#"( [ ( 15u8, 32u8 ), ( 23u8, 41u8 ) ], [ (45u8, 63u8), (58u8, 73u8) ] )"# r"( [ ( 15u8, 32u8 ), ( 23u8, 41u8 ) ], [ (45u8, 63u8), (58u8, 73u8) ] )"
), ),
RocList::from_slice(&[15, 32, 23, 41, 45, 63, 58, 73]), RocList::from_slice(&[15, 32, 23, 41, 45, 63, 58, 73]),
RocList<u8> RocList<u8>
@ -2152,7 +2152,7 @@ fn issue_4772_weakened_monomorphic_destructure() {
with_larger_debug_stack(|| { with_larger_debug_stack(|| {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r###" r#"
app "test" app "test"
imports [TotallyNotJson] imports [TotallyNotJson]
provides [main] to "./platform" provides [main] to "./platform"
@ -2173,7 +2173,7 @@ fn issue_4772_weakened_monomorphic_destructure() {
main = main =
getNumber |> Result.map .val |> Result.withDefault 0 getNumber |> Result.map .val |> Result.withDefault 0
"### "#
), ),
1234i64, 1234i64,
i64 i64
@ -2302,7 +2302,7 @@ mod inspect {
main = Inspect.toStr (@Op {}) main = Inspect.toStr (@Op {})
"# "#
), ),
RocStr::from(r#"<opaque>"#), RocStr::from(r"<opaque>"),
RocStr RocStr
); );
} }
@ -2322,7 +2322,7 @@ mod inspect {
main = late (@Op {}) main = late (@Op {})
"# "#
), ),
RocStr::from(r#"<opaque>"#), RocStr::from(r"<opaque>"),
RocStr RocStr
); );
} }

View file

@ -19,11 +19,11 @@ use roc_std::{RocList, RocResult, RocStr};
fn def_closure_in_parens() { fn def_closure_in_parens() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
id = (\x -> x) id = (\x -> x)
id 42u32 id 42u32
"# "
), ),
42, 42,
u32 u32
@ -35,11 +35,11 @@ fn def_closure_in_parens() {
fn def_closure_in_multiple_parens() { fn def_closure_in_multiple_parens() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
id = (((\x -> x))) id = (((\x -> x)))
id 42u32 id 42u32
"# "
), ),
42, 42,
u32 u32

View file

@ -20,9 +20,9 @@ use roc_std::{RocList, RocStr};
fn dict_empty_len() { fn dict_empty_len() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Dict.len (Dict.empty {}) Dict.len (Dict.empty {})
"# "
), ),
0, 0,
usize usize
@ -34,11 +34,11 @@ fn dict_empty_len() {
fn dict_insert_empty() { fn dict_insert_empty() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Dict.empty {} Dict.empty {}
|> Dict.insert 42 32 |> Dict.insert 42 32
|> Dict.len |> Dict.len
"# "
), ),
1, 1,
usize usize
@ -50,12 +50,12 @@ fn dict_insert_empty() {
fn dict_empty_contains() { fn dict_empty_contains() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
empty : Dict.Dict I64 F64 empty : Dict.Dict I64 F64
empty = Dict.empty {} empty = Dict.empty {}
Dict.contains empty 42 Dict.contains empty 42
"# "
), ),
false, false,
bool bool
@ -67,12 +67,12 @@ fn dict_empty_contains() {
fn dict_nonempty_contains() { fn dict_nonempty_contains() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
empty : Dict.Dict I64 F64 empty : Dict.Dict I64 F64
empty = Dict.insert (Dict.empty {}) 42 1.23 empty = Dict.insert (Dict.empty {}) 42 1.23
Dict.contains empty 42 Dict.contains empty 42
"# "
), ),
true, true,
bool bool
@ -85,14 +85,14 @@ fn dict_nonempty_contains() {
fn dict_empty_remove() { fn dict_empty_remove() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
empty : Dict.Dict I64 F64 empty : Dict.Dict I64 F64
empty = Dict.empty {} empty = Dict.empty {}
empty empty
|> Dict.remove 42 |> Dict.remove 42
|> Dict.len |> Dict.len
"# "
), ),
0, 0,
i64 i64
@ -104,7 +104,7 @@ fn dict_empty_remove() {
fn dict_nonempty_remove() { fn dict_nonempty_remove() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
empty : Dict.Dict I64 F64 empty : Dict.Dict I64 F64
empty = Dict.insert (Dict.empty {}) 42 1.23 empty = Dict.insert (Dict.empty {}) 42 1.23
@ -112,7 +112,7 @@ fn dict_nonempty_remove() {
|> Dict.remove 42 |> Dict.remove 42
|> Dict.len |> Dict.len
|> Num.toI64 |> Num.toI64
"# "
), ),
0, 0,
i64 i64
@ -124,7 +124,7 @@ fn dict_nonempty_remove() {
fn dict_nonempty_get() { fn dict_nonempty_get() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
empty : Dict.Dict I64 F64 empty : Dict.Dict I64 F64
empty = Dict.insert (Dict.empty {}) 42 1.23 empty = Dict.insert (Dict.empty {}) 42 1.23
@ -137,7 +137,7 @@ fn dict_nonempty_get() {
|> Dict.insert 42 1.23f64 |> Dict.insert 42 1.23f64
|> Dict.get 42 |> Dict.get 42
|> withDefault 0 |> withDefault 0
"# "
), ),
1.23, 1.23,
f64 f64
@ -145,7 +145,7 @@ fn dict_nonempty_get() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
withDefault = \x, def -> withDefault = \x, def ->
when x is when x is
Ok v -> v Ok v -> v
@ -155,7 +155,7 @@ fn dict_nonempty_get() {
|> Dict.insert 42 1.23f64 |> Dict.insert 42 1.23f64
|> Dict.get 43 |> Dict.get 43
|> withDefault 0 |> withDefault 0
"# "
), ),
0.0, 0.0,
f64 f64
@ -167,7 +167,7 @@ fn dict_nonempty_get() {
fn keys() { fn keys() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
myDict : Dict.Dict I64 I64 myDict : Dict.Dict I64 I64
myDict = myDict =
Dict.empty {} Dict.empty {}
@ -177,7 +177,7 @@ fn keys() {
Dict.keys myDict Dict.keys myDict
"# "
), ),
RocList::from_slice(&[0, 1, 2]), RocList::from_slice(&[0, 1, 2]),
RocList<i64> RocList<i64>
@ -189,7 +189,7 @@ fn keys() {
fn values() { fn values() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
myDict : Dict.Dict I64 I64 myDict : Dict.Dict I64 I64
myDict = myDict =
Dict.empty {} Dict.empty {}
@ -199,7 +199,7 @@ fn values() {
Dict.values myDict Dict.values myDict
"# "
), ),
RocList::from_slice(&[100, 200, 300]), RocList::from_slice(&[100, 200, 300]),
RocList<i64> RocList<i64>
@ -211,14 +211,14 @@ fn values() {
fn from_list_with_fold_simple() { fn from_list_with_fold_simple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
myDict : Dict.Dict I64 I64 myDict : Dict.Dict I64 I64
myDict = myDict =
[1,2,3] [1,2,3]
|> List.walk (Dict.empty {}) (\accum, value -> Dict.insert accum value value) |> List.walk (Dict.empty {}) (\accum, value -> Dict.insert accum value value)
Dict.values myDict Dict.values myDict
"# "
), ),
RocList::from_slice(&[1, 2, 3]), RocList::from_slice(&[1, 2, 3]),
RocList<i64> RocList<i64>
@ -230,7 +230,7 @@ fn from_list_with_fold_simple() {
fn from_list_with_fold_reallocates() { fn from_list_with_fold_reallocates() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
range : I64, I64, List I64-> List I64 range : I64, I64, List I64-> List I64
range = \low, high, accum -> range = \low, high, accum ->
if low < high then if low < high then
@ -245,7 +245,7 @@ fn from_list_with_fold_reallocates() {
|> List.walk (Dict.empty {}) (\accum, value -> Dict.insert accum value value) |> List.walk (Dict.empty {}) (\accum, value -> Dict.insert accum value value)
Dict.values myDict Dict.values myDict
"# "
), ),
RocList::from_slice(&[ RocList::from_slice(&[
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
@ -329,7 +329,7 @@ fn big_str_values() {
fn unit_values() { fn unit_values() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
myDict : Dict.Dict I64 {} myDict : Dict.Dict I64 {}
myDict = myDict =
Dict.empty {} Dict.empty {}
@ -339,7 +339,7 @@ fn unit_values() {
|> Dict.insert 3 {} |> Dict.insert 3 {}
Num.toI64 (Dict.len myDict) Num.toI64 (Dict.len myDict)
"# "
), ),
4, 4,
i64 i64
@ -351,13 +351,13 @@ fn unit_values() {
fn single() { fn single() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
myDict : Dict.Dict I64 {} myDict : Dict.Dict I64 {}
myDict = myDict =
Dict.single 12345 {} Dict.single 12345 {}
Num.toI64 (Dict.len myDict) Num.toI64 (Dict.len myDict)
"# "
), ),
1, 1,
i64 i64
@ -369,14 +369,14 @@ fn single() {
fn insert_all() { fn insert_all() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
myDict : Dict I64 {} myDict : Dict I64 {}
myDict = myDict =
Dict.insertAll (Dict.single 0 {}) (Dict.single 1 {}) Dict.insertAll (Dict.single 0 {}) (Dict.single 1 {})
Dict.len myDict Dict.len myDict
|> Num.toI64 |> Num.toI64
"# "
), ),
2, 2,
i64 i64
@ -388,14 +388,14 @@ fn insert_all() {
fn insert_all_prefer_second() { fn insert_all_prefer_second() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
myDict : Dict.Dict I64 I64 myDict : Dict.Dict I64 I64
myDict = myDict =
(Dict.single 0 100) (Dict.single 0 100)
|> Dict.insertAll (Dict.single 0 200) |> Dict.insertAll (Dict.single 0 200)
Dict.values myDict Dict.values myDict
"# "
), ),
RocList::from_slice(&[200]), RocList::from_slice(&[200]),
RocList<i64> RocList<i64>
@ -407,7 +407,7 @@ fn insert_all_prefer_second() {
fn keep_shared() { fn keep_shared() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
dict1 : Dict.Dict I64 {} dict1 : Dict.Dict I64 {}
dict1 = dict1 =
Dict.empty {} Dict.empty {}
@ -427,7 +427,7 @@ fn keep_shared() {
Dict.keepShared dict1 dict2 Dict.keepShared dict1 dict2
|> Dict.len |> Dict.len
|> Num.toI64 |> Num.toI64
"# "
), ),
2, 2,
i64 i64
@ -439,7 +439,7 @@ fn keep_shared() {
fn keep_shared_value_must_match() { fn keep_shared_value_must_match() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
dict1 : Dict.Dict I64 I64 dict1 : Dict.Dict I64 I64
dict1 = dict1 =
Dict.empty {} Dict.empty {}
@ -458,7 +458,7 @@ fn keep_shared_value_must_match() {
Dict.keepShared dict1 dict2 Dict.keepShared dict1 dict2
|> Dict.values |> Dict.values
"# "
), ),
RocList::from_slice(&[2]), RocList::from_slice(&[2]),
RocList<i64> RocList<i64>
@ -470,7 +470,7 @@ fn keep_shared_value_must_match() {
fn remove_all() { fn remove_all() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
dict1 : Dict.Dict I64 {} dict1 : Dict.Dict I64 {}
dict1 = dict1 =
Dict.empty {} Dict.empty {}
@ -490,7 +490,7 @@ fn remove_all() {
Dict.removeAll dict1 dict2 Dict.removeAll dict1 dict2
|> Dict.len |> Dict.len
|> Num.toI64 |> Num.toI64
"# "
), ),
3, 3,
i64 i64
@ -502,7 +502,7 @@ fn remove_all() {
fn remove_all_prefer_first() { fn remove_all_prefer_first() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
dict1 : Dict.Dict I64 I64 dict1 : Dict.Dict I64 I64
dict1 = dict1 =
Dict.empty {} Dict.empty {}
@ -521,7 +521,7 @@ fn remove_all_prefer_first() {
Dict.removeAll dict1 dict2 Dict.removeAll dict1 dict2
|> Dict.values |> Dict.values
"# "
), ),
RocList::from_slice(&[1, 5, 3]), RocList::from_slice(&[1, 5, 3]),
RocList<i64> RocList<i64>
@ -533,7 +533,7 @@ fn remove_all_prefer_first() {
fn walk_sum_keys() { fn walk_sum_keys() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
dict1 : Dict.Dict I64 I64 dict1 : Dict.Dict I64 I64
dict1 = dict1 =
Dict.empty {} Dict.empty {}
@ -544,7 +544,7 @@ fn walk_sum_keys() {
|> Dict.insert 5 5 |> Dict.insert 5 5
Dict.walk dict1 0 \k, _, a -> k + a Dict.walk dict1 0 \k, _, a -> k + a
"# "
), ),
15, 15,
i64 i64

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -28,11 +28,11 @@ fn basic_float() {
fn branch_first_float() { fn branch_first_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when 1.23f64 is when 1.23f64 is
1.23 -> 12 1.23 -> 12
_ -> 34 _ -> 34
"# "
), ),
12, 12,
i64 i64
@ -44,11 +44,11 @@ fn branch_first_float() {
fn branch_second_float() { fn branch_second_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when 2.34 is when 2.34 is
1.23 -> 63 1.23 -> 63
_ -> 48 _ -> 48
"# "
), ),
48, 48,
i64 i64
@ -60,12 +60,12 @@ fn branch_second_float() {
fn branch_third_float() { fn branch_third_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when 10.0 is when 10.0 is
1.0 -> 63 1.0 -> 63
2.0 -> 48 2.0 -> 48
_ -> 112 _ -> 112
"# "
), ),
112, 112,
i64 i64
@ -77,11 +77,11 @@ fn branch_third_float() {
fn branch_first_int() { fn branch_first_int() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when 1 is when 1 is
1 -> 12 1 -> 12
_ -> 34 _ -> 34
"# "
), ),
12, 12,
i64 i64
@ -93,11 +93,11 @@ fn branch_first_int() {
fn branch_second_int() { fn branch_second_int() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when 2 is when 2 is
1 -> 63 1 -> 63
_ -> 48 _ -> 48
"# "
), ),
48, 48,
i64 i64
@ -109,12 +109,12 @@ fn branch_second_int() {
fn branch_third_int() { fn branch_third_int() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when 10 is when 10 is
1 -> 63 1 -> 63
2 -> 48 2 -> 48
_ -> 112 _ -> 112
"# "
), ),
112, 112,
i64 i64
@ -126,11 +126,11 @@ fn branch_third_int() {
fn branch_store_variable() { fn branch_store_variable() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when 0 is when 0 is
1 -> 12 1 -> 12
a -> a a -> a
"# "
), ),
0, 0,
i64 i64
@ -142,13 +142,13 @@ fn branch_store_variable() {
fn when_one_element_tag() { fn when_one_element_tag() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x : [Pair (Int a) (Int a)] x : [Pair (Int a) (Int a)]
x = Pair 0x2 0x3 x = Pair 0x2 0x3
when x is when x is
Pair l r -> l + r Pair l r -> l + r
"# "
), ),
5, 5,
i64 i64
@ -160,14 +160,14 @@ fn when_one_element_tag() {
fn when_two_element_tag_first() { fn when_two_element_tag_first() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x : [A (Int a), B (Int a)] x : [A (Int a), B (Int a)]
x = A 0x2 x = A 0x2
when x is when x is
A v -> v A v -> v
B v -> v B v -> v
"# "
), ),
2, 2,
i64 i64
@ -179,14 +179,14 @@ fn when_two_element_tag_first() {
fn when_two_element_tag_second() { fn when_two_element_tag_second() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x : [A (Int a), B (Int a)] x : [A (Int a), B (Int a)]
x = B 0x3 x = B 0x3
when x is when x is
A v -> v A v -> v
B v -> v B v -> v
"# "
), ),
3, 3,
i64 i64
@ -198,10 +198,10 @@ fn when_two_element_tag_second() {
fn gen_when_one_branch() { fn gen_when_one_branch() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when 1.23 is when 1.23 is
_ -> 23 _ -> 23
"# "
), ),
23, 23,
i64 i64
@ -213,7 +213,7 @@ fn gen_when_one_branch() {
fn gen_large_when_int() { fn gen_large_when_int() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
foo = \num -> foo = \num ->
when num is when num is
0 -> 200 0 -> 200
@ -224,7 +224,7 @@ fn gen_large_when_int() {
_ -> 1000 _ -> 1000
foo -3 foo -3
"# "
), ),
111, 111,
i64 i64
@ -236,7 +236,7 @@ fn gen_large_when_int() {
fn gen_large_when_float() { fn gen_large_when_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
foo = \num -> foo = \num ->
when num is when num is
0.5f64 -> 200.1 0.5f64 -> 200.1
@ -247,7 +247,7 @@ fn gen_large_when_float() {
_ -> 1000.6f64 _ -> 1000.6f64
foo -3.6 foo -3.6
"# "
), ),
111.2, 111.2,
f64 f64
@ -259,11 +259,11 @@ fn gen_large_when_float() {
fn or_pattern() { fn or_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when 2 is when 2 is
1 | 2 -> 42 1 | 2 -> 42
_ -> 1 _ -> 1
"# "
), ),
42, 42,
i64 i64
@ -275,11 +275,11 @@ fn or_pattern() {
fn apply_identity() { fn apply_identity() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
identity = \a -> a identity = \a -> a
identity 5 identity 5
"# "
), ),
5, 5,
i64 i64
@ -291,12 +291,12 @@ fn apply_identity() {
fn apply_unnamed_identity() { fn apply_unnamed_identity() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
wrapper = \{} -> wrapper = \{} ->
(\a -> a) 5 (\a -> a) 5
wrapper {} wrapper {}
"# "
), ),
5, 5,
i64 i64
@ -308,7 +308,7 @@ fn apply_unnamed_identity() {
fn return_unnamed_fn() { fn return_unnamed_fn() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
wrapper = \{} -> wrapper = \{} ->
alwaysFloatIdentity : Int * -> (Frac a -> Frac a) alwaysFloatIdentity : Int * -> (Frac a -> Frac a)
alwaysFloatIdentity = \_ -> alwaysFloatIdentity = \_ ->
@ -317,7 +317,7 @@ fn return_unnamed_fn() {
(alwaysFloatIdentity 2) 1.23f64 (alwaysFloatIdentity 2) 1.23f64
wrapper {} wrapper {}
"# "
), ),
1.23, 1.23,
f64 f64
@ -329,7 +329,7 @@ fn return_unnamed_fn() {
fn gen_when_fn() { fn gen_when_fn() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
limitedNegate = \num -> limitedNegate = \num ->
when num is when num is
1 -> -1 1 -> -1
@ -337,7 +337,7 @@ fn gen_when_fn() {
_ -> num _ -> num
limitedNegate 1 limitedNegate 1
"# "
), ),
-1, -1,
i64 i64
@ -349,11 +349,11 @@ fn gen_when_fn() {
fn gen_basic_def() { fn gen_basic_def() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
answer = 42 answer = 42
answer answer
"# "
), ),
42, 42,
i64 i64
@ -361,11 +361,11 @@ fn gen_basic_def() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
float = 1.23f64 float = 1.23f64
float float
"# "
), ),
1.23, 1.23,
f64 f64
@ -377,13 +377,13 @@ fn gen_basic_def() {
fn gen_multiple_defs() { fn gen_multiple_defs() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
answer = 42 answer = 42
float = 1.23f64 float = 1.23f64
if float > 3 then answer else answer if float > 3 then answer else answer
"# "
), ),
42, 42,
i64 i64
@ -391,13 +391,13 @@ fn gen_multiple_defs() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
answer = 42 answer = 42
float = 1.23f64 float = 1.23f64
if answer > 3 then float else float if answer > 3 then float else float
"# "
), ),
1.23, 1.23,
f64 f64
@ -411,7 +411,7 @@ fn gen_multiple_defs() {
// fn gen_chained_defs() { // fn gen_chained_defs() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
// r#" // r"
// x = i1 // x = i1
// i3 = i2 // i3 = i2
// i1 = 1337 // i1 = 1337
@ -419,7 +419,7 @@ fn gen_multiple_defs() {
// y = 12.4 // y = 12.4
// //
// i3 // i3
// "# // "
// ), // ),
// 1337, // 1337,
// i64 // i64
@ -431,7 +431,7 @@ fn gen_multiple_defs() {
// fn gen_nested_defs_old() { // fn gen_nested_defs_old() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
// r#" // r"
// x = 5 // x = 5
// //
// answer = // answer =
@ -461,7 +461,7 @@ fn gen_multiple_defs() {
// y = 12.4 // y = 12.4
// //
// answer // answer
// "# // "
// ), // ),
// 1337, // 1337,
// i64 // i64
@ -473,7 +473,7 @@ fn gen_multiple_defs() {
// fn let_x_in_x() { // fn let_x_in_x() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
// r#" // r"
// x = 5 // x = 5
// //
// answer = // answer =
@ -484,7 +484,7 @@ fn gen_multiple_defs() {
// nested // nested
// //
// answer // answer
// "# // "
// ), // ),
// 1337, // 1337,
// i64 // i64
@ -496,7 +496,7 @@ fn gen_multiple_defs() {
fn factorial() { fn factorial() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
factorial = \n, accum -> factorial = \n, accum ->
when n is when n is
0 -> 0 ->
@ -506,7 +506,7 @@ fn factorial() {
factorial (n - 1) (n * accum) factorial (n - 1) (n * accum)
factorial 10 1 factorial 10 1
"# "
), ),
3628800, 3628800,
i64 i64
@ -518,7 +518,7 @@ fn factorial() {
fn peano1() { fn peano1() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Peano : [S Peano, Z] Peano : [S Peano, Z]
three : Peano three : Peano
@ -527,7 +527,7 @@ fn peano1() {
when three is when three is
Z -> 2 Z -> 2
S _ -> 1 S _ -> 1
"# "
), ),
1, 1,
i64 i64
@ -539,7 +539,7 @@ fn peano1() {
fn peano2() { fn peano2() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Peano : [S Peano, Z] Peano : [S Peano, Z]
three : Peano three : Peano
@ -549,7 +549,7 @@ fn peano2() {
S (S _) -> 1 S (S _) -> 1
S (_) -> 0 S (_) -> 0
Z -> 0 Z -> 0
"# "
), ),
1, 1,
i64 i64
@ -833,7 +833,7 @@ fn linked_list_map() {
fn when_nested_maybe() { fn when_nested_maybe() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Maybe a : [Nothing, Just a] Maybe a : [Nothing, Just a]
x : Maybe (Maybe (Int a)) x : Maybe (Maybe (Int a))
@ -842,7 +842,7 @@ fn when_nested_maybe() {
when x is when x is
Just (Just v) -> v + 0x1 Just (Just v) -> v + 0x1
_ -> 0x1 _ -> 0x1
"# "
), ),
42, 42,
i64 i64
@ -850,7 +850,7 @@ fn when_nested_maybe() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Maybe a : [Nothing, Just a] Maybe a : [Nothing, Just a]
x : Maybe (Maybe (Int *)) x : Maybe (Maybe (Int *))
@ -860,7 +860,7 @@ fn when_nested_maybe() {
Just (Just v) -> v + 0x1 Just (Just v) -> v + 0x1
Just Nothing -> 0x2 Just Nothing -> 0x2
Nothing -> 0x1 Nothing -> 0x1
"# "
), ),
2, 2,
i64 i64
@ -868,7 +868,7 @@ fn when_nested_maybe() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Maybe a : [Nothing, Just a] Maybe a : [Nothing, Just a]
x : Maybe (Maybe (Int *)) x : Maybe (Maybe (Int *))
@ -878,7 +878,7 @@ fn when_nested_maybe() {
Just (Just v) -> v + 0x1 Just (Just v) -> v + 0x1
Just Nothing -> 0x2 Just Nothing -> 0x2
Nothing -> 0x1 Nothing -> 0x1
"# "
), ),
1, 1,
i64 i64
@ -890,7 +890,7 @@ fn when_nested_maybe() {
fn when_peano() { fn when_peano() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Peano : [S Peano, Z] Peano : [S Peano, Z]
three : Peano three : Peano
@ -900,7 +900,7 @@ fn when_peano() {
S (S _) -> 1 S (S _) -> 1
S (_) -> 2 S (_) -> 2
Z -> 3 Z -> 3
"# "
), ),
1, 1,
i64 i64
@ -908,7 +908,7 @@ fn when_peano() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Peano : [S Peano, Z] Peano : [S Peano, Z]
three : Peano three : Peano
@ -918,7 +918,7 @@ fn when_peano() {
S (S _) -> 1 S (S _) -> 1
S (_) -> 2 S (_) -> 2
Z -> 3 Z -> 3
"# "
), ),
2, 2,
i64 i64
@ -926,7 +926,7 @@ fn when_peano() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Peano : [S Peano, Z] Peano : [S Peano, Z]
three : Peano three : Peano
@ -936,7 +936,7 @@ fn when_peano() {
S (S _) -> 1 S (S _) -> 1
S (_) -> 2 S (_) -> 2
Z -> 3 Z -> 3
"# "
), ),
3, 3,
i64 i64
@ -955,7 +955,7 @@ fn when_peano() {
fn overflow_frees_list() { fn overflow_frees_list() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
myList = [1,2,3] myList = [1,2,3]
# integer overflow; must use the list so it is defined before the overflow # integer overflow; must use the list so it is defined before the overflow
@ -967,7 +967,7 @@ fn overflow_frees_list() {
index = Num.intCast n index = Num.intCast n
List.get myList index List.get myList index
"# "
), ),
(3, 0), (3, 0),
(i64, i8) (i64, i8)
@ -980,12 +980,12 @@ fn overflow_frees_list() {
fn undefined_variable() { fn undefined_variable() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
if Bool.true then if Bool.true then
x + z x + z
else else
y + z y + z
"# "
), ),
3, 3,
i64 i64
@ -1016,12 +1016,12 @@ fn a_crash() {
fn annotation_without_body() { fn annotation_without_body() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
foo : Int * foo : Int *
foo foo
"# "
), ),
3, 3,
i64 i64
@ -2022,11 +2022,11 @@ fn hof_conditional() {
// exposed issue with the if condition being just a symbol // exposed issue with the if condition being just a symbol
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
passTrue = \f -> f Bool.true passTrue = \f -> f Bool.true
passTrue (\trueVal -> if trueVal then Bool.false else Bool.true) passTrue (\trueVal -> if trueVal then Bool.false else Bool.true)
"# "
), ),
0, 0,
u8 u8
@ -2041,12 +2041,12 @@ fn hof_conditional() {
fn pattern_shadowing() { fn pattern_shadowing() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x = 4 x = 4
when 4 is when 4 is
x -> x x -> x
"# "
), ),
0, 0,
i64 i64
@ -2060,11 +2060,11 @@ fn pattern_shadowing() {
fn unsupported_pattern_str_interp() { fn unsupported_pattern_str_interp() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ x: 4 } = { x : 4 } { x: 4 } = { x : 4 }
x x
"# "
), ),
0, 0,
i64 i64
@ -2120,14 +2120,14 @@ fn case_or_pattern() {
// it is currently duplicated // it is currently duplicated
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x : [Red, Green, Blue] x : [Red, Green, Blue]
x = Red x = Red
when x is when x is
Red | Green -> 0 Red | Green -> 0
Blue -> 1 Blue -> 1
"# "
), ),
0, 0,
i64 i64
@ -2517,11 +2517,11 @@ fn backpassing_result() {
fn function_malformed_pattern() { fn function_malformed_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x = 3 x = 3
(\x -> x) 42 (\x -> x) 42
"# "
), ),
3, 3,
i64 i64
@ -2534,12 +2534,12 @@ fn function_malformed_pattern() {
fn call_invalid_layout() { fn call_invalid_layout() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f : I64 -> I64 f : I64 -> I64
f = \x -> x f = \x -> x
f {} f {}
"# "
), ),
3, 3,
i64, i64,
@ -3261,12 +3261,12 @@ fn polymophic_expression_captured_inside_closure() {
fn issue_2322() { fn issue_2322() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
double = \x -> x * 2 double = \x -> x * 2
doubleBind = \x -> (\_ -> double x) doubleBind = \x -> (\_ -> double x)
doubleThree = doubleBind 3 doubleThree = doubleBind 3
doubleThree {} doubleThree {}
"# "
), ),
6, 6,
i64 i64
@ -3312,14 +3312,14 @@ fn box_and_unbox_big_string() {
fn box_and_unbox_nonrecursive_tag() { fn box_and_unbox_nonrecursive_tag() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result U64 U64 result : Result U64 U64
result = Ok 42 result = Ok 42
result result
|> Box.box |> Box.box
|> Box.unbox |> Box.unbox
"# "
), ),
roc_std::RocResult::ok(42), roc_std::RocResult::ok(42),
roc_std::RocResult<u64, u64> roc_std::RocResult<u64, u64>
@ -3409,9 +3409,9 @@ fn box_and_unbox_f32() {
fn box_and_unbox_record_2_u64() { fn box_and_unbox_record_2_u64() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Box.unbox (Box.box { a: 15u64, b: 27u64 }) Box.unbox (Box.box { a: 15u64, b: 27u64 })
"# "
), ),
(15, 27), (15, 27),
(u64, u64) (u64, u64)
@ -3423,9 +3423,9 @@ fn box_and_unbox_record_2_u64() {
fn box_and_unbox_record_3_u64() { fn box_and_unbox_record_3_u64() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Box.unbox (Box.box { a: 15u64, b: 27u64, c: 34u64 }) Box.unbox (Box.box { a: 15u64, b: 27u64, c: 34u64 })
"# "
), ),
(15, 27, 34), (15, 27, 34),
(u64, u64, u64) (u64, u64, u64)
@ -3437,9 +3437,9 @@ fn box_and_unbox_record_3_u64() {
fn box_and_unbox_record_2_u8() { fn box_and_unbox_record_2_u8() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Box.unbox (Box.box { a: 15u8, b: 27u8 }) Box.unbox (Box.box { a: 15u8, b: 27u8 })
"# "
), ),
(15, 27), (15, 27),
(u8, u8) (u8, u8)
@ -3451,9 +3451,9 @@ fn box_and_unbox_record_2_u8() {
fn box_and_unbox_record_3_u8() { fn box_and_unbox_record_3_u8() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Box.unbox (Box.box { a: 15u8, b: 27u8, c: 34u8 }) Box.unbox (Box.box { a: 15u8, b: 27u8, c: 34u8 })
"# "
), ),
(15, 27, 34), (15, 27, 34),
(u8, u8, u8) (u8, u8, u8)
@ -3465,12 +3465,12 @@ fn box_and_unbox_record_3_u8() {
fn box_and_unbox_tag_union() { fn box_and_unbox_tag_union() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
v : [A U8, B U8] # usually stack allocated v : [A U8, B U8] # usually stack allocated
v = B 27u8 v = B 27u8
Box.unbox (Box.box v) Box.unbox (Box.box v)
"# "
), ),
(27, 1), (27, 1),
(u8, u8) (u8, u8)
@ -3534,7 +3534,7 @@ fn issue_2894() {
fn polymorphic_def_used_in_closure() { fn polymorphic_def_used_in_closure() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
a : I64 -> _ a : I64 -> _
a = \g -> a = \g ->
f = { r: g, h: 32 } f = { r: g, h: 32 }
@ -3543,7 +3543,7 @@ fn polymorphic_def_used_in_closure() {
h1 = (\{} -> f.h) {} h1 = (\{} -> f.h) {}
h1 h1
a 1 a 1
"# "
), ),
32, 32,
u64 u64
@ -3555,13 +3555,13 @@ fn polymorphic_def_used_in_closure() {
fn polymorphic_lambda_set_usage() { fn polymorphic_lambda_set_usage() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
id1 = \x -> x id1 = \x -> x
id2 = \y -> y id2 = \y -> y
id = if Bool.true then id1 else id2 id = if Bool.true then id1 else id2
id 9u8 id 9u8
"# "
), ),
9, 9,
u8 u8
@ -3573,7 +3573,7 @@ fn polymorphic_lambda_set_usage() {
fn polymorphic_lambda_set_multiple_specializations() { fn polymorphic_lambda_set_multiple_specializations() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
id1 = \x -> x id1 = \x -> x
id2 = \y -> y id2 = \y -> y
id = \z -> id = \z ->
@ -3581,7 +3581,7 @@ fn polymorphic_lambda_set_multiple_specializations() {
f z f z
(id 9u8) + Num.toU8 (id 16u16) (id 9u8) + Num.toU8 (id 16u16)
"# "
), ),
25, 25,
u8 u8
@ -3642,14 +3642,14 @@ fn mutual_recursion_top_level_defs() {
fn polymorphic_lambda_captures_polymorphic_value() { fn polymorphic_lambda_captures_polymorphic_value() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x = 2 x = 2
f1 = \_ -> x f1 = \_ -> x
f = if Bool.true then f1 else f1 f = if Bool.true then f1 else f1
f {} f {}
"# "
), ),
2, 2,
u64 u64
@ -3661,7 +3661,7 @@ fn polymorphic_lambda_captures_polymorphic_value() {
fn lambda_capture_niche_u64_vs_u8_capture() { fn lambda_capture_niche_u64_vs_u8_capture() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
capture : _ -> ({} -> Str) capture : _ -> ({} -> Str)
capture = \val -> capture = \val ->
\{} -> \{} ->
@ -3677,7 +3677,7 @@ fn lambda_capture_niche_u64_vs_u8_capture() {
capture 18u8 capture 18u8
fun {} fun {}
"# "
), ),
RocStr::from("123"), RocStr::from("123"),
RocStr RocStr
@ -3789,14 +3789,14 @@ fn lambda_capture_niches_have_captured_function_in_closure() {
fn recursive_call_capturing_function() { fn recursive_call_capturing_function() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
a = \b -> a = \b ->
c = \d -> c = \d ->
if d == 7 then d else c (d + b) if d == 7 then d else c (d + b)
c 1 c 1
a 6 a 6
"# "
), ),
7, 7,
i64 i64
@ -3808,13 +3808,13 @@ fn recursive_call_capturing_function() {
fn shared_pattern_variable_in_when_branches() { fn shared_pattern_variable_in_when_branches() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f = \t -> f = \t ->
when t is when t is
A x | B x -> x A x | B x -> x
{a: f (A 15u8), b: (B 31u8)} {a: f (A 15u8), b: (B 31u8)}
"# "
), ),
(15u8, 31u8), (15u8, 31u8),
(u8, u8) (u8, u8)
@ -3826,12 +3826,12 @@ fn shared_pattern_variable_in_when_branches() {
fn symbol_not_bound_in_all_patterns_runs_when_no_bound_symbol_used() { fn symbol_not_bound_in_all_patterns_runs_when_no_bound_symbol_used() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f = \t -> when t is f = \t -> when t is
A x | B y -> 31u8 A x | B y -> 31u8
{a: f (A 15u8), b: f (B 15u8)} {a: f (A 15u8), b: f (B 15u8)}
"# "
), ),
(31u8, 31u8), (31u8, 31u8),
(u8, u8), (u8, u8),
@ -3845,10 +3845,10 @@ fn symbol_not_bound_in_all_patterns_runs_when_no_bound_symbol_used() {
fn symbol_not_bound_in_all_patterns_runs_when_bound_pattern_reached() { fn symbol_not_bound_in_all_patterns_runs_when_bound_pattern_reached() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when A 15u8 is when A 15u8 is
A x | B y -> x A x | B y -> x
"# "
), ),
15u8, 15u8,
u8, u8,
@ -3865,10 +3865,10 @@ fn symbol_not_bound_in_all_patterns_runs_when_bound_pattern_reached() {
fn runtime_error_when_degenerate_pattern_reached() { fn runtime_error_when_degenerate_pattern_reached() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when B 15u8 is when B 15u8 is
A x | B y -> x + 5u8 A x | B y -> x + 5u8
"# "
), ),
15u8, 15u8,
u8, u8,
@ -4399,7 +4399,7 @@ fn pattern_as_of_symbol() {
fn function_specialization_information_in_lambda_set_thunk() { fn function_specialization_information_in_lambda_set_thunk() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r###" r#"
app "test" provides [main] to "./platform" app "test" provides [main] to "./platform"
andThen = \{} -> andThen = \{} ->
@ -4409,7 +4409,7 @@ fn function_specialization_information_in_lambda_set_thunk() {
between = andThen {} between = andThen {}
main = between \{} -> between \{} -> 10u8 main = between \{} -> between \{} -> 10u8
"### "#
), ),
30, 30,
u8 u8
@ -4421,7 +4421,7 @@ fn function_specialization_information_in_lambda_set_thunk() {
fn function_specialization_information_in_lambda_set_thunk_independent_defs() { fn function_specialization_information_in_lambda_set_thunk_independent_defs() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r###" r#"
app "test" provides [main] to "./platform" app "test" provides [main] to "./platform"
andThen = \{} -> andThen = \{} ->
@ -4433,7 +4433,7 @@ fn function_specialization_information_in_lambda_set_thunk_independent_defs() {
between2 = andThen {} between2 = andThen {}
main = between1 \{} -> between2 \{} -> 10u8 main = between1 \{} -> between2 \{} -> 10u8
"### "#
), ),
30, 30,
u8 u8
@ -4526,7 +4526,7 @@ fn layout_cache_structure_with_multiple_recursive_structures() {
fn reset_recursive_type_wraps_in_named_type() { fn reset_recursive_type_wraps_in_named_type() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r###" r#"
app "test" provides [main] to "./platform" app "test" provides [main] to "./platform"
main : Str main : Str
@ -4553,7 +4553,7 @@ fn reset_recursive_type_wraps_in_named_type() {
strX = f x strX = f x
strXs = printLinkedList xs f strXs = printLinkedList xs f
"Cons \(strX) (\(strXs))" "Cons \(strX) (\(strXs))"
"### "#
), ),
RocStr::from("Cons 2 (Cons 3 (Cons 4 (Nil)))"), RocStr::from("Cons 2 (Cons 3 (Cons 4 (Nil)))"),
RocStr RocStr
@ -4619,12 +4619,12 @@ fn many_arguments() {
// exhausts all argument registers on x86 and aarch // exhausts all argument registers on x86 and aarch
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
fun = \a,b,c,d, e,f,g,h, i -> fun = \a,b,c,d, e,f,g,h, i ->
(a + b + c + d) + (e + f + g + h) + i (a + b + c + d) + (e + f + g + h) + i
fun 0i64 1 2 3 4 5 6 7 8 fun 0i64 1 2 3 4 5 6 7 8
"# "
), ),
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8,
i64 i64
@ -4636,9 +4636,9 @@ fn many_arguments() {
fn multiple_uses_of_bool_true_record() { fn multiple_uses_of_bool_true_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
(Bool.true, Bool.true).0 (Bool.true, Bool.true).0
"# "
), ),
true, true,
bool bool
@ -4650,14 +4650,14 @@ fn multiple_uses_of_bool_true_record() {
fn multiple_uses_of_bool_true_tag_union() { fn multiple_uses_of_bool_true_tag_union() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x : [ One Bool Bool, Empty ] x : [ One Bool Bool, Empty ]
x = One Bool.true Bool.true x = One Bool.true Bool.true
when x is when x is
One a _ -> a One a _ -> a
Empty -> Bool.false Empty -> Bool.false
"# "
), ),
true, true,
bool bool

View file

@ -18,9 +18,9 @@ use roc_std::{RocList, RocStr};
fn basic_record() { fn basic_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ y: 17, x: 15, z: 19 }.x { y: 17, x: 15, z: 19 }.x
"# "
), ),
15, 15,
i64 i64
@ -28,9 +28,9 @@ fn basic_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ x: 15, y: 17, z: 19 }.y { x: 15, y: 17, z: 19 }.y
"# "
), ),
17, 17,
i64 i64
@ -38,9 +38,9 @@ fn basic_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ x: 15, y: 17, z: 19 }.z { x: 15, y: 17, z: 19 }.z
"# "
), ),
19, 19,
i64 i64
@ -52,11 +52,11 @@ fn basic_record() {
fn f64_record() { fn f64_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = { y: 17.2f64, x: 15.1f64, z: 19.3f64 } rec = { y: 17.2f64, x: 15.1f64, z: 19.3f64 }
rec.x rec.x
"# "
), ),
15.1, 15.1,
f64 f64
@ -64,11 +64,11 @@ fn f64_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = { y: 17.2f64, x: 15.1f64, z: 19.3f64 } rec = { y: 17.2f64, x: 15.1f64, z: 19.3f64 }
rec.y rec.y
"# "
), ),
17.2, 17.2,
f64 f64
@ -76,11 +76,11 @@ fn f64_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = { y: 17.2f64, x: 15.1f64, z: 19.3f64 } rec = { y: 17.2f64, x: 15.1f64, z: 19.3f64 }
rec.z rec.z
"# "
), ),
19.3, 19.3,
f64 f64
@ -93,14 +93,14 @@ fn pass_bool_record() {
// found a bug there the register to use was not incremented correctly // found a bug there the register to use was not incremented correctly
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
true : Bool true : Bool
true = Bool.true true = Bool.true
f = \_, x -> x f = \_, x -> x
f { x: true, y: true } 23 f { x: true, y: true } 23
"# "
), ),
23, 23,
i64 i64
@ -124,11 +124,11 @@ fn fn_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = { x: 15, y: 17, z: 19 } rec = { x: 15, y: 17, z: 19 }
rec.z + rec.x rec.z + rec.x
"# "
), ),
34, 34,
i64 i64
@ -140,11 +140,11 @@ fn fn_record() {
fn def_record() { fn def_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = { y: 17, x: 15, z: 19 } rec = { y: 17, x: 15, z: 19 }
rec.x rec.x
"# "
), ),
15, 15,
i64 i64
@ -152,11 +152,11 @@ fn def_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = { x: 15, y: 17, z: 19 } rec = { x: 15, y: 17, z: 19 }
rec.y rec.y
"# "
), ),
17, 17,
i64 i64
@ -164,11 +164,11 @@ fn def_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = { x: 15, y: 17, z: 19 } rec = { x: 15, y: 17, z: 19 }
rec.z rec.z
"# "
), ),
19, 19,
i64 i64
@ -180,10 +180,10 @@ fn def_record() {
fn when_on_record() { fn when_on_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when { x: 0x2 } is when { x: 0x2 } is
{ x } -> x + 3 { x } -> x + 3
"# "
), ),
5, 5,
i64 i64
@ -195,10 +195,10 @@ fn when_on_record() {
fn when_record_with_guard_pattern() { fn when_record_with_guard_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when { x: 0x2, y: 1.23 } is when { x: 0x2, y: 1.23 } is
{ x: var } -> var + 3 { x: var } -> var + 3
"# "
), ),
5, 5,
i64 i64
@ -210,11 +210,11 @@ fn when_record_with_guard_pattern() {
fn let_with_record_pattern() { fn let_with_record_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ x } = { x: 0x2, y: 1.23 } { x } = { x: 0x2, y: 1.23 }
x x
"# "
), ),
2, 2,
i64 i64
@ -226,11 +226,11 @@ fn let_with_record_pattern() {
fn record_guard_pattern() { fn record_guard_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when { x: 0x2, y: 1.23 } is when { x: 0x2, y: 1.23 } is
{ x: 0x4 } -> 5 { x: 0x4 } -> 5
{ x } -> x + 3 { x } -> x + 3
"# "
), ),
5, 5,
i64 i64
@ -242,11 +242,11 @@ fn record_guard_pattern() {
fn twice_record_access() { fn twice_record_access() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x = {a: 0x2, b: 0x3 } x = {a: 0x2, b: 0x3 }
x.a + x.b x.a + x.b
"# "
), ),
5, 5,
i64 i64
@ -257,11 +257,11 @@ fn twice_record_access() {
fn empty_record() { fn empty_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
v = {} v = {}
v v
"# "
), ),
(), (),
() ()
@ -272,9 +272,9 @@ fn empty_record() {
fn i64_record2_literal() { fn i64_record2_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ x: 3, y: 5 } { x: 3, y: 5 }
"# "
), ),
(3, 5), (3, 5),
(i64, i64) (i64, i64)
@ -286,9 +286,9 @@ fn i64_record2_literal() {
// fn i64_record3_literal() { // fn i64_record3_literal() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
// r#" // r"
// { x: 3, y: 5, z: 17 } // { x: 3, y: 5, z: 17 }
// "# // "
// ), // ),
// (3, 5, 17), // (3, 5, 17),
// (i64, i64, i64) // (i64, i64, i64)
@ -299,9 +299,9 @@ fn i64_record2_literal() {
fn f64_record2_literal() { fn f64_record2_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ x: 3.1f64, y: 5.1f64 } { x: 3.1f64, y: 5.1f64 }
"# "
), ),
(3.1, 5.1), (3.1, 5.1),
(f64, f64) (f64, f64)
@ -313,9 +313,9 @@ fn f64_record2_literal() {
// fn f64_record3_literal() { // fn f64_record3_literal() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
// r#" // r"
// { x: 3.1, y: 5.1, z: 17.1 } // { x: 3.1, y: 5.1, z: 17.1 }
// "# // "
// ), // ),
// (3.1, 5.1, 17.1), // (3.1, 5.1, 17.1),
// (f64, f64, f64) // (f64, f64, f64)
@ -327,12 +327,12 @@ fn f64_record2_literal() {
// fn bool_record4_literal() { // fn bool_record4_literal() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
// r#" // r"
// record : { a : Bool, b : Bool, c : Bool, d : Bool } // record : { a : Bool, b : Bool, c : Bool, d : Bool }
// record = { a: Bool.true, b: Bool.true, c : Bool.true, d : Bool } // record = { a: Bool.true, b: Bool.true, c : Bool.true, d : Bool }
// record // record
// "# // "
// ), // ),
// (true, false, false, true), // (true, false, false, true),
// (bool, bool, bool, bool) // (bool, bool, bool, bool)
@ -343,9 +343,9 @@ fn f64_record2_literal() {
fn i64_record1_literal() { fn i64_record1_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ a: 3 } { a: 3 }
"# "
), ),
3, 3,
i64 i64
@ -357,9 +357,9 @@ fn i64_record1_literal() {
// fn i64_record9_literal() { // fn i64_record9_literal() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
// r#" // r"
// { a: 3, b: 5, c: 17, d: 1, e: 9, f: 12, g: 13, h: 14, i: 15 } // { a: 3, b: 5, c: 17, d: 1, e: 9, f: 12, g: 13, h: 14, i: 15 }
// "# // "
// ), // ),
// (3, 5, 17, 1, 9, 12, 13, 14, 15), // (3, 5, 17, 1, 9, 12, 13, 14, 15),
// (i64, i64, i64, i64, i64, i64, i64, i64, i64) // (i64, i64, i64, i64, i64, i64, i64, i64, i64)
@ -371,9 +371,9 @@ fn i64_record1_literal() {
// fn f64_record3_literal() { // fn f64_record3_literal() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
// r#" // r"
// { x: 3.1, y: 5.1, z: 17.1 } // { x: 3.1, y: 5.1, z: 17.1 }
// "# // "
// ), // ),
// (3.1, 5.1, 17.1), // (3.1, 5.1, 17.1),
// (f64, f64, f64) // (f64, f64, f64)
@ -384,12 +384,12 @@ fn i64_record1_literal() {
fn bool_literal() { fn bool_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x : Bool x : Bool
x = Bool.true x = Bool.true
x x
"# "
), ),
true, true,
bool bool
@ -401,12 +401,12 @@ fn bool_literal() {
fn return_record() { fn return_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x = 4 x = 4
y = 3 y = 3
{ x, y } { x, y }
"# "
), ),
(4, 3), (4, 3),
(i64, i64) (i64, i64)
@ -446,7 +446,7 @@ fn optional_field_when_use_default() {
fn optional_field_when_use_default_nested() { fn optional_field_when_use_default_nested() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f = \r -> f = \r ->
when r is when r is
{ x: Blue, y ? 3 } -> y { x: Blue, y ? 3 } -> y
@ -458,7 +458,7 @@ fn optional_field_when_use_default_nested() {
d = f { x: Red } d = f { x: Red }
a * b * c * d a * b * c * d
"# "
), ),
3 * 5 * 7 * 11, 3 * 5 * 7 * 11,
i64 i64
@ -491,13 +491,13 @@ fn optional_field_destructure_module() {
fn optional_field_destructure_expr() { fn optional_field_destructure_expr() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
fn = \r -> fn = \r ->
{ x ? 10, y } = r { x ? 10, y } = r
x + y x + y
fn { x: 4, y: 9 } fn { x: 4, y: 9 }
"# "
), ),
13, 13,
i64 i64
@ -551,13 +551,13 @@ fn optional_field_let_no_use_default() {
fn optional_field_let_no_use_default_nested() { fn optional_field_let_no_use_default_nested() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f = \r -> f = \r ->
{ x ? 10, y } = r { x ? 10, y } = r
x + y x + y
f { y: 9, x: 4 } f { y: 9, x: 4 }
"# "
), ),
13, 13,
i64 i64
@ -569,12 +569,12 @@ fn optional_field_let_no_use_default_nested() {
fn optional_field_function_use_default() { fn optional_field_function_use_default() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f = \{ x ? 10, y } -> x + y f = \{ x ? 10, y } -> x + y
f { y: 9 } f { y: 9 }
"# "
), ),
19, 19,
i64 i64
@ -605,12 +605,12 @@ fn optional_field_function_no_use_default() {
fn optional_field_function_no_use_default_nested() { fn optional_field_function_no_use_default_nested() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f = \{ x ? 10, y } -> x + y f = \{ x ? 10, y } -> x + y
f { x: 4, y: 9 } f { x: 4, y: 9 }
"# "
), ),
13, 13,
i64 i64
@ -622,10 +622,10 @@ fn optional_field_function_no_use_default_nested() {
fn optional_field_singleton_record() { fn optional_field_singleton_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when { x : 4 } is when { x : 4 } is
{ x ? 3 } -> x { x ? 3 } -> x
"# "
), ),
4, 4,
i64 i64
@ -637,10 +637,10 @@ fn optional_field_singleton_record() {
fn optional_field_empty_record() { fn optional_field_empty_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when { } is when { } is
{ x ? 3 } -> x { x ? 3 } -> x
"# "
), ),
3, 3,
i64 i64
@ -652,9 +652,9 @@ fn optional_field_empty_record() {
fn return_record_2() { fn return_record_2() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ x: 3, y: 5 } { x: 3, y: 5 }
"# "
), ),
[3, 5], [3, 5],
[i64; 2] [i64; 2]
@ -666,9 +666,9 @@ fn return_record_2() {
fn return_record_3() { fn return_record_3() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ x: 3, y: 5, z: 4 } { x: 3, y: 5, z: 4 }
"# "
), ),
(3, 5, 4), (3, 5, 4),
(i64, i64, i64) (i64, i64, i64)
@ -680,9 +680,9 @@ fn return_record_3() {
fn return_record_4() { fn return_record_4() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ a: 3, b: 5, c: 4, d: 2 } { a: 3, b: 5, c: 4, d: 2 }
"# "
), ),
[3, 5, 4, 2], [3, 5, 4, 2],
[i64; 4] [i64; 4]
@ -694,9 +694,9 @@ fn return_record_4() {
fn return_record_5() { fn return_record_5() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ a: 3, b: 5, c: 4, d: 2, e: 1 } { a: 3, b: 5, c: 4, d: 2, e: 1 }
"# "
), ),
[3, 5, 4, 2, 1], [3, 5, 4, 2, 1],
[i64; 5] [i64; 5]
@ -708,9 +708,9 @@ fn return_record_5() {
fn return_record_6() { fn return_record_6() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ a: 3, b: 5, c: 4, d: 2, e: 1, f: 7 } { a: 3, b: 5, c: 4, d: 2, e: 1, f: 7 }
"# "
), ),
[3, 5, 4, 2, 1, 7], [3, 5, 4, 2, 1, 7],
[i64; 6] [i64; 6]
@ -722,9 +722,9 @@ fn return_record_6() {
fn return_record_7() { fn return_record_7() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ a: 3, b: 5, c: 4, d: 2, e: 1, f: 7, g: 8 } { a: 3, b: 5, c: 4, d: 2, e: 1, f: 7, g: 8 }
"# "
), ),
[3, 5, 4, 2, 1, 7, 8], [3, 5, 4, 2, 1, 7, 8],
[i64; 7] [i64; 7]
@ -736,9 +736,9 @@ fn return_record_7() {
fn return_record_float_int() { fn return_record_float_int() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ a: 1.23f64, b: 0x1 } { a: 1.23f64, b: 0x1 }
"# "
), ),
(1.23, 0x1), (1.23, 0x1),
(f64, i64) (f64, i64)
@ -750,9 +750,9 @@ fn return_record_float_int() {
fn return_record_int_float() { fn return_record_int_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ a: 0x1, b: 1.23f64 } { a: 0x1, b: 1.23f64 }
"# "
), ),
(0x1, 1.23), (0x1, 1.23),
(i64, f64) (i64, f64)
@ -764,9 +764,9 @@ fn return_record_int_float() {
fn return_record_float_float() { fn return_record_float_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ a: 2.46f64, b: 1.23f64 } { a: 2.46f64, b: 1.23f64 }
"# "
), ),
(2.46, 1.23), (2.46, 1.23),
(f64, f64) (f64, f64)
@ -778,9 +778,9 @@ fn return_record_float_float() {
fn return_record_float_float_float() { fn return_record_float_float_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ a: 2.46f64, b: 1.23f64, c: 0.1f64 } { a: 2.46f64, b: 1.23f64, c: 0.1f64 }
"# "
), ),
(2.46, 1.23, 0.1), (2.46, 1.23, 0.1),
(f64, f64, f64) (f64, f64, f64)
@ -792,9 +792,9 @@ fn return_record_float_float_float() {
fn return_nested_record() { fn return_nested_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
{ flag: 0x0, payload: { a: 2.46f64, b: 1.23f64, c: 0.1f64 } } { flag: 0x0, payload: { a: 2.46f64, b: 1.23f64, c: 0.1f64 } }
"# "
), ),
(0x0, (2.46, 1.23, 0.1)), (0x0, (2.46, 1.23, 0.1)),
(i64, (f64, f64, f64)) (i64, (f64, f64, f64))
@ -806,13 +806,13 @@ fn return_nested_record() {
fn nested_record_load() { fn nested_record_load() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x = { a : { b : 0x5 } } x = { a : { b : 0x5 } }
y = x.a y = x.a
y.b y.b
"# "
), ),
5, 5,
i64 i64
@ -844,9 +844,9 @@ fn accessor_multi_element_record() {
fn accessor_single_element_record() { fn accessor_single_element_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
.foo { foo: 4 } .foo { foo: 4 }
"# "
), ),
4, 4,
i64 i64
@ -858,11 +858,11 @@ fn accessor_single_element_record() {
fn update_record() { fn update_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = { foo: 42, bar: 2.46f64 } rec = { foo: 42, bar: 2.46f64 }
{ rec & foo: rec.foo + 1 } { rec & foo: rec.foo + 1 }
"# "
), ),
(2.46, 43), (2.46, 43),
(f64, i64) (f64, i64)
@ -874,11 +874,11 @@ fn update_record() {
fn update_single_element_record() { fn update_single_element_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = { foo: 42} rec = { foo: 42}
{ rec & foo: rec.foo + 1 } { rec & foo: rec.foo + 1 }
"# "
), ),
43, 43,
i64 i64
@ -927,14 +927,14 @@ fn alignment_in_record() {
fn blue_and_present() { fn blue_and_present() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f = \r -> f = \r ->
when r is when r is
{ x: Blue, y ? 3 } -> y { x: Blue, y ? 3 } -> y
{ x: Red, y ? 5 } -> y { x: Red, y ? 5 } -> y
f { x: Blue, y: 7 } f { x: Blue, y: 7 }
"# "
), ),
7, 7,
i64 i64
@ -946,14 +946,14 @@ fn blue_and_present() {
fn blue_and_absent() { fn blue_and_absent() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f = \r -> f = \r ->
when r is when r is
{ x: Blue, y ? 3 } -> y { x: Blue, y ? 3 } -> y
{ x: Red, y ? 5 } -> y { x: Red, y ? 5 } -> y
f { x: Blue } f { x: Blue }
"# "
), ),
3, 3,
i64 i64
@ -965,7 +965,7 @@ fn blue_and_absent() {
fn update_the_only_field() { fn update_the_only_field() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Model : { foo : I64 } Model : { foo : I64 }
model : Model model : Model
@ -977,7 +977,7 @@ fn update_the_only_field() {
newModel = { model & foo } newModel = { model & foo }
newModel.foo newModel.foo
"# "
), ),
4, 4,
i64 i64
@ -990,7 +990,7 @@ fn update_the_only_field() {
fn both_have_unique_fields() { fn both_have_unique_fields() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
a = { x: 42, y: 43 } a = { x: 42, y: 43 }
b = { x: 42, z: 44 } b = { x: 42, z: 44 }
@ -998,7 +998,7 @@ fn both_have_unique_fields() {
f = \{ x: x1}, { x: x2 } -> x1 + x2 f = \{ x: x1}, { x: x2 } -> x1 + x2
f a b f a b
"# "
), ),
84, 84,
i64 i64

View file

@ -17,12 +17,12 @@ use roc_std::{RocResult, RocStr};
fn with_default_ok() { fn with_default_ok() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result I64 {} result : Result I64 {}
result = Ok 12345 result = Ok 12345
Result.withDefault result 0 Result.withDefault result 0
"# "
), ),
12345, 12345,
i64 i64
@ -34,12 +34,12 @@ fn with_default_ok() {
fn with_default_err() { fn with_default_err() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result I64 {} result : Result I64 {}
result = Err {} result = Err {}
Result.withDefault result 0 Result.withDefault result 0
"# "
), ),
0, 0,
i64 i64
@ -51,14 +51,14 @@ fn with_default_err() {
fn result_map() { fn result_map() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result I64 {} result : Result I64 {}
result = Ok 2 result = Ok 2
result result
|> Result.map (\x -> x + 1) |> Result.map (\x -> x + 1)
|> Result.withDefault 0 |> Result.withDefault 0
"# "
), ),
3, 3,
i64 i64
@ -66,14 +66,14 @@ fn result_map() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result I64 {} result : Result I64 {}
result = Err {} result = Err {}
result result
|> Result.map (\x -> x + 1) |> Result.map (\x -> x + 1)
|> Result.withDefault 0 |> Result.withDefault 0
"# "
), ),
0, 0,
i64 i64
@ -85,14 +85,14 @@ fn result_map() {
fn result_map_err() { fn result_map_err() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result {} I64 result : Result {} I64
result = Err 2 result = Err 2
when Result.mapErr result (\x -> x + 1) is when Result.mapErr result (\x -> x + 1) is
Err n -> n Err n -> n
Ok _ -> 0 Ok _ -> 0
"# "
), ),
3, 3,
i64 i64
@ -100,14 +100,14 @@ fn result_map_err() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result {} I64 result : Result {} I64
result = Ok {} result = Ok {}
when Result.mapErr result (\x -> x + 1) is when Result.mapErr result (\x -> x + 1) is
Err n -> n Err n -> n
Ok _ -> 0 Ok _ -> 0
"# "
), ),
0, 0,
i64 i64
@ -119,10 +119,10 @@ fn result_map_err() {
fn err_type_var() { fn err_type_var() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Result.map (Ok 3) (\x -> x + 1) Result.map (Ok 3) (\x -> x + 1)
|> Result.withDefault -1 |> Result.withDefault -1
"# "
), ),
4, 4,
i64 i64
@ -134,13 +134,13 @@ fn err_type_var() {
fn err_type_var_annotation() { fn err_type_var_annotation() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
ok : Result I64 * ok : Result I64 *
ok = Ok 3 ok = Ok 3
Result.map ok (\x -> x + 1) Result.map ok (\x -> x + 1)
|> Result.withDefault -1 |> Result.withDefault -1
"# "
), ),
4, 4,
i64 i64
@ -152,13 +152,13 @@ fn err_type_var_annotation() {
fn err_empty_tag_union() { fn err_empty_tag_union() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
ok : Result I64 [] ok : Result I64 []
ok = Ok 3 ok = Ok 3
Result.map ok (\x -> x + 1) Result.map ok (\x -> x + 1)
|> Result.withDefault -1 |> Result.withDefault -1
"# "
), ),
4, 4,
i64 i64
@ -170,12 +170,12 @@ fn err_empty_tag_union() {
fn is_ok() { fn is_ok() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result I64 {} result : Result I64 {}
result = Ok 2 result = Ok 2
Result.isOk result Result.isOk result
"# "
), ),
true, true,
bool bool
@ -183,12 +183,12 @@ fn is_ok() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result I64 {} result : Result I64 {}
result = Err {} result = Err {}
Result.isOk result Result.isOk result
"# "
), ),
false, false,
bool bool
@ -200,12 +200,12 @@ fn is_ok() {
fn is_err() { fn is_err() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result I64 {} result : Result I64 {}
result = Ok 2 result = Ok 2
Result.isErr result Result.isErr result
"# "
), ),
false, false,
bool bool
@ -213,12 +213,12 @@ fn is_err() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result I64 {} result : Result I64 {}
result = Err {} result = Err {}
Result.isErr result Result.isErr result
"# "
), ),
true, true,
bool bool
@ -230,12 +230,12 @@ fn is_err() {
fn roc_result_ok_i64() { fn roc_result_ok_i64() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result I64 {} result : Result I64 {}
result = Ok 42 result = Ok 42
result result
"# "
), ),
RocResult::ok(42), RocResult::ok(42),
RocResult<i64, ()> RocResult<i64, ()>
@ -250,12 +250,12 @@ fn roc_result_ok_f64() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
result : Result F64 {} result : Result F64 {}
result = Ok 42.0 result = Ok 42.0
result result
"# "
), ),
RocResult::ok(42.0), RocResult::ok(42.0),
RocResult<f64, ()> RocResult<f64, ()>

View file

@ -20,9 +20,9 @@ use roc_std::RocList;
fn empty_len() { fn empty_len() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Set.len (Set.empty {}) Set.len (Set.empty {})
"# "
), ),
0, 0,
usize usize
@ -34,9 +34,9 @@ fn empty_len() {
fn single_len() { fn single_len() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Set.len (Set.single 42) Set.len (Set.single 42)
"# "
), ),
1, 1,
usize usize
@ -48,9 +48,9 @@ fn single_len() {
fn single_to_list() { fn single_to_list() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Set.toList (Set.single 42) Set.toList (Set.single 42)
"# "
), ),
RocList::from_slice(&[42]), RocList::from_slice(&[42]),
RocList<i64> RocList<i64>
@ -58,9 +58,9 @@ fn single_to_list() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Set.toList (Set.single 1) Set.toList (Set.single 1)
"# "
), ),
RocList::from_slice(&[1]), RocList::from_slice(&[1]),
RocList<i64> RocList<i64>
@ -72,13 +72,13 @@ fn single_to_list() {
fn insert() { fn insert() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Set.empty {} Set.empty {}
|> Set.insert 0 |> Set.insert 0
|> Set.insert 1 |> Set.insert 1
|> Set.insert 2 |> Set.insert 2
|> Set.toList |> Set.toList
"# "
), ),
RocList::from_slice(&[0, 1, 2]), RocList::from_slice(&[0, 1, 2]),
RocList<i64> RocList<i64>
@ -90,14 +90,14 @@ fn insert() {
fn remove() { fn remove() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Set.empty {} Set.empty {}
|> Set.insert 0 |> Set.insert 0
|> Set.insert 1 |> Set.insert 1
|> Set.remove 1 |> Set.remove 1
|> Set.remove 2 |> Set.remove 2
|> Set.toList |> Set.toList
"# "
), ),
RocList::from_slice(&[0]), RocList::from_slice(&[0]),
RocList<i64> RocList<i64>
@ -109,7 +109,7 @@ fn remove() {
fn union() { fn union() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
set1 : Set.Set I64 set1 : Set.Set I64
set1 = Set.fromList [1,2] set1 = Set.fromList [1,2]
@ -118,7 +118,7 @@ fn union() {
Set.union set1 set2 Set.union set1 set2
|> Set.toList |> Set.toList
"# "
), ),
RocList::from_slice(&[1, 3, 4, 2]), RocList::from_slice(&[1, 3, 4, 2]),
RocList<i64> RocList<i64>
@ -130,7 +130,7 @@ fn union() {
fn difference() { fn difference() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
set1 : Set.Set I64 set1 : Set.Set I64
set1 = Set.fromList [1,2] set1 = Set.fromList [1,2]
@ -139,7 +139,7 @@ fn difference() {
Set.difference set1 set2 Set.difference set1 set2
|> Set.toList |> Set.toList
"# "
), ),
RocList::from_slice(&[2]), RocList::from_slice(&[2]),
RocList<i64> RocList<i64>
@ -151,7 +151,7 @@ fn difference() {
fn intersection() { fn intersection() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
set1 : Set.Set I64 set1 : Set.Set I64
set1 = Set.fromList [1,2] set1 = Set.fromList [1,2]
@ -160,7 +160,7 @@ fn intersection() {
Set.intersection set1 set2 Set.intersection set1 set2
|> Set.toList |> Set.toList
"# "
), ),
RocList::from_slice(&[1]), RocList::from_slice(&[1]),
RocList<i64> RocList<i64>
@ -172,9 +172,9 @@ fn intersection() {
fn walk_sum() { fn walk_sum() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Set.walk (Set.fromList [1,2,3]) 0 (\x, y -> x + y) Set.walk (Set.fromList [1,2,3]) 0 (\x, y -> x + y)
"# "
), ),
6, 6,
i64 i64
@ -186,9 +186,9 @@ fn walk_sum() {
fn contains() { fn contains() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Set.contains (Set.fromList [1,3,4]) 4 Set.contains (Set.fromList [1,3,4]) 4
"# "
), ),
true, true,
bool bool
@ -196,9 +196,9 @@ fn contains() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Set.contains (Set.fromList [1,3,4]) 2 Set.contains (Set.fromList [1,3,4]) 2
"# "
), ),
false, false,
bool bool
@ -210,11 +210,11 @@ fn contains() {
fn from_list() { fn from_list() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
[1,2,2,3,1,4] [1,2,2,3,1,4]
|> Set.fromList |> Set.fromList
|> Set.toList |> Set.toList
"# "
), ),
RocList::from_slice(&[1, 2, 3, 4]), RocList::from_slice(&[1, 2, 3, 4]),
RocList<i64> RocList<i64>
@ -222,14 +222,14 @@ fn from_list() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
empty : List I64 empty : List I64
empty = [] empty = []
empty empty
|> Set.fromList |> Set.fromList
|> Set.toList |> Set.toList
"# "
), ),
RocList::<i64>::default(), RocList::<i64>::default(),
RocList<i64> RocList<i64>
@ -242,11 +242,11 @@ fn from_list() {
fn from_list_void() { fn from_list_void() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
[] []
|> Set.fromList |> Set.fromList
|> Set.toList |> Set.toList
"# "
), ),
RocList::<i64>::default(), RocList::<i64>::default(),
RocList<i64> RocList<i64>
@ -258,9 +258,9 @@ fn from_list_void() {
fn to_list_empty() { fn to_list_empty() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Set.toList (Set.empty {}) Set.toList (Set.empty {})
"# "
), ),
RocList::<std::convert::Infallible>::default(), RocList::<std::convert::Infallible>::default(),
RocList<std::convert::Infallible> RocList<std::convert::Infallible>

View file

@ -39,14 +39,14 @@ fn width_and_alignment_u8_u8() {
fn applied_tag_nothing() { fn applied_tag_nothing() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Maybe a : [Just a, Nothing] Maybe a : [Just a, Nothing]
x : Maybe I64 x : Maybe I64
x = Nothing x = Nothing
x x
"# "
), ),
1, 1,
(i64, u8), (i64, u8),
@ -59,14 +59,14 @@ fn applied_tag_nothing() {
fn applied_tag_just() { fn applied_tag_just() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Maybe a : [Just a, Nothing] Maybe a : [Just a, Nothing]
y : Maybe I64 y : Maybe I64
y = Just 0x4 y = Just 0x4
y y
"# "
), ),
(0x4, 0), (0x4, 0),
(i64, u8) (i64, u8)
@ -78,7 +78,7 @@ fn applied_tag_just() {
fn applied_tag_just_enum() { fn applied_tag_just_enum() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Fruit : [Orange, Apple, Banana] Fruit : [Orange, Apple, Banana]
Maybe a : [Just a, Nothing] Maybe a : [Just a, Nothing]
@ -89,7 +89,7 @@ fn applied_tag_just_enum() {
y = Just orange y = Just orange
y y
"# "
), ),
(2, 0), (2, 0),
(u8, u8) (u8, u8)
@ -101,12 +101,12 @@ fn applied_tag_just_enum() {
fn true_is_true() { fn true_is_true() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
bool : Bool bool : Bool
bool = Bool.true bool = Bool.true
bool bool
"# "
), ),
true, true,
bool bool
@ -118,12 +118,12 @@ fn true_is_true() {
fn false_is_false() { fn false_is_false() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
bool : Bool bool : Bool
bool = Bool.false bool = Bool.false
bool bool
"# "
), ),
false, false,
bool bool
@ -135,7 +135,7 @@ fn false_is_false() {
fn basic_enum() { fn basic_enum() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Fruit : [Apple, Orange, Banana] Fruit : [Apple, Orange, Banana]
apple : Fruit apple : Fruit
@ -145,7 +145,7 @@ fn basic_enum() {
orange = Orange orange = Orange
apple == orange apple == orange
"# "
), ),
false, false,
bool bool
@ -157,7 +157,7 @@ fn basic_enum() {
fn even_odd() { fn even_odd() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
even = \n -> even = \n ->
when n is when n is
0 -> Bool.true 0 -> Bool.true
@ -171,7 +171,7 @@ fn even_odd() {
_ -> even (n - 1) _ -> even (n - 1)
odd 5 && even 42 odd 5 && even 42
"# "
), ),
true, true,
bool bool
@ -183,9 +183,9 @@ fn even_odd() {
fn gen_literal_true() { fn gen_literal_true() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
if Bool.true then -1 else 1 if Bool.true then -1 else 1
"# "
), ),
-1, -1,
i64 i64
@ -197,9 +197,9 @@ fn gen_literal_true() {
fn gen_if_float() { fn gen_if_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
if Bool.true then -1.0 else 1.0f64 if Bool.true then -1.0 else 1.0f64
"# "
), ),
-1.0, -1.0,
f64 f64
@ -210,14 +210,14 @@ fn gen_if_float() {
fn when_on_nothing() { fn when_on_nothing() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x : [Nothing, Just I64] x : [Nothing, Just I64]
x = Nothing x = Nothing
when x is when x is
Nothing -> 0x2 Nothing -> 0x2
Just _ -> 0x1 Just _ -> 0x1
"# "
), ),
2, 2,
i64 i64
@ -229,14 +229,14 @@ fn when_on_nothing() {
fn when_on_just() { fn when_on_just() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x : [Nothing, Just I64] x : [Nothing, Just I64]
x = Just 41 x = Just 41
when x is when x is
Just v -> v + 0x1 Just v -> v + 0x1
Nothing -> 0x1 Nothing -> 0x1
"# "
), ),
42, 42,
i64 i64
@ -248,14 +248,14 @@ fn when_on_just() {
fn when_on_result() { fn when_on_result() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x : Result I64 I64 x : Result I64 I64
x = Err 41 x = Err 41
when x is when x is
Err v -> v + 1 Err v -> v + 1
Ok _ -> 1 Ok _ -> 1
"# "
), ),
42, 42,
i64 i64
@ -267,7 +267,7 @@ fn when_on_result() {
fn when_on_these() { fn when_on_these() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
These a b : [This a, That b, These a b] These a b : [This a, That b, These a b]
x : These I64 I64 x : These I64 I64
@ -277,7 +277,7 @@ fn when_on_these() {
These a b -> a + b These a b -> a + b
That v -> v That v -> v
This v -> v This v -> v
"# "
), ),
5, 5,
i64 i64
@ -290,11 +290,11 @@ fn match_on_two_values() {
// this will produce a Chain internally // this will produce a Chain internally
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when Pair 2 3 is when Pair 2 3 is
Pair 4 3 -> 9 Pair 4 3 -> 9
Pair a b -> a + b Pair a b -> a + b
"# "
), ),
5, 5,
i64 i64
@ -306,12 +306,12 @@ fn match_on_two_values() {
fn pair_with_underscore() { fn pair_with_underscore() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when Pair 2 3 is when Pair 2 3 is
Pair 4 _ -> 1 Pair 4 _ -> 1
Pair 3 _ -> 2 Pair 3 _ -> 2
Pair a b -> a + b Pair a b -> a + b
"# "
), ),
5, 5,
i64 i64
@ -324,7 +324,7 @@ fn result_with_underscore() {
// This test revealed an issue with hashing Test values // This test revealed an issue with hashing Test values
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x : Result I64 I64 x : Result I64 I64
x = Ok 2 x = Ok 2
@ -332,7 +332,7 @@ fn result_with_underscore() {
Ok 3 -> 1 Ok 3 -> 1
Ok _ -> 2 Ok _ -> 2
Err _ -> 3 Err _ -> 3
"# "
), ),
2, 2,
i64 i64
@ -369,7 +369,7 @@ fn maybe_is_just_not_nested() {
fn maybe_is_just_nested() { fn maybe_is_just_nested() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Maybe a : [Just a, Nothing] Maybe a : [Just a, Nothing]
isJust : Maybe a -> Bool isJust : Maybe a -> Bool
@ -379,7 +379,7 @@ fn maybe_is_just_nested() {
Just _ -> Bool.true Just _ -> Bool.true
isJust (Just 42) isJust (Just 42)
"# "
), ),
true, true,
bool bool
@ -391,7 +391,7 @@ fn maybe_is_just_nested() {
fn nested_pattern_match() { fn nested_pattern_match() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Maybe a : [Nothing, Just a] Maybe a : [Nothing, Just a]
x : Maybe (Maybe I64) x : Maybe (Maybe I64)
@ -400,7 +400,7 @@ fn nested_pattern_match() {
when x is when x is
Just (Just v) -> v + 0x1 Just (Just v) -> v + 0x1
_ -> 0x1 _ -> 0x1
"# "
), ),
42, 42,
i64 i64
@ -428,11 +428,11 @@ fn if_guard_vanilla() {
fn when_on_single_value_tag() { fn when_on_single_value_tag() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when Identity 0 is when Identity 0 is
Identity 0 -> 6 Identity 0 -> 6
Identity s -> s Identity s -> s
"# "
), ),
6, 6,
i64 i64
@ -444,7 +444,7 @@ fn when_on_single_value_tag() {
fn if_guard_multiple() { fn if_guard_multiple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f = \n -> f = \n ->
when Identity n 0 is when Identity n 0 is
Identity x _ if x == 0 -> x + 0 Identity x _ if x == 0 -> x + 0
@ -453,7 +453,7 @@ fn if_guard_multiple() {
Identity x _ -> x - x Identity x _ -> x - x
{ a: f 0, b: f 1, c: f 2, d: f 4 } { a: f 0, b: f 1, c: f 2, d: f 4 }
"# "
), ),
[0, 1, 2, 0], [0, 1, 2, 0],
[i64; 4] [i64; 4]
@ -465,13 +465,13 @@ fn if_guard_multiple() {
fn if_guard_constructor_switch() { fn if_guard_constructor_switch() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when Identity 32 0 is when Identity 32 0 is
Identity 41 _ -> 0 Identity 41 _ -> 0
Identity s 0 if s == 32 -> 3 Identity s 0 if s == 32 -> 3
# Identity s 0 -> s # Identity s 0 -> s
Identity z _ -> z Identity z _ -> z
"# "
), ),
3, 3,
i64 i64
@ -509,12 +509,12 @@ fn if_guard_constructor_switch() {
fn if_guard_constructor_chain() { fn if_guard_constructor_chain() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when Identity 43 0 is when Identity 43 0 is
Identity 42 _ if 3 == 3 -> 43 Identity 42 _ if 3 == 3 -> 43
# Identity 42 _ -> 1 # Identity 42 _ -> 1
Identity z _ -> z Identity z _ -> z
"# "
), ),
43, 43,
i64 i64
@ -526,14 +526,14 @@ fn if_guard_constructor_chain() {
fn if_guard_pattern_false() { fn if_guard_pattern_false() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
wrapper = \{} -> wrapper = \{} ->
when 2 is when 2 is
2 if Bool.false -> 0 2 if Bool.false -> 0
_ -> 42 _ -> 42
wrapper {} wrapper {}
"# "
), ),
42, 42,
i64 i64
@ -545,14 +545,14 @@ fn if_guard_pattern_false() {
fn if_guard_switch() { fn if_guard_switch() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
wrapper = \{} -> wrapper = \{} ->
when 2 is when 2 is
2 | 3 if Bool.false -> 0 2 | 3 if Bool.false -> 0
_ -> 42 _ -> 42
wrapper {} wrapper {}
"# "
), ),
42, 42,
i64 i64
@ -564,14 +564,14 @@ fn if_guard_switch() {
fn if_guard_pattern_true() { fn if_guard_pattern_true() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
wrapper = \{} -> wrapper = \{} ->
when 2 is when 2 is
2 if Bool.true -> 42 2 if Bool.true -> 42
_ -> 0 _ -> 0
wrapper {} wrapper {}
"# "
), ),
42, 42,
i64 i64
@ -583,14 +583,14 @@ fn if_guard_pattern_true() {
fn if_guard_exhaustiveness() { fn if_guard_exhaustiveness() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
wrapper = \{} -> wrapper = \{} ->
when 2 is when 2 is
_ if Bool.false -> 0 _ if Bool.false -> 0
_ -> 42 _ -> 42
wrapper {} wrapper {}
"# "
), ),
42, 42,
i64 i64
@ -602,7 +602,7 @@ fn if_guard_exhaustiveness() {
fn when_on_enum() { fn when_on_enum() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Fruit : [Apple, Orange, Banana] Fruit : [Apple, Orange, Banana]
apple : Fruit apple : Fruit
@ -612,7 +612,7 @@ fn when_on_enum() {
Apple -> 1 Apple -> 1
Banana -> 2 Banana -> 2
Orange -> 3 Orange -> 3
"# "
), ),
1, 1,
i64 i64
@ -624,14 +624,14 @@ fn when_on_enum() {
fn pattern_matching_unit() { fn pattern_matching_unit() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Unit : [Unit] Unit : [Unit]
f : Unit -> I64 f : Unit -> I64
f = \Unit -> 42 f = \Unit -> 42
f Unit f Unit
"# "
), ),
42, 42,
i64 i64
@ -639,7 +639,7 @@ fn pattern_matching_unit() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Unit : [Unit] Unit : [Unit]
x : Unit x : Unit
@ -647,7 +647,7 @@ fn pattern_matching_unit() {
when x is when x is
Unit -> 42 Unit -> 42
"# "
), ),
42, 42,
i64 i64
@ -655,12 +655,12 @@ fn pattern_matching_unit() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f : {} -> I64 f : {} -> I64
f = \{} -> 42 f = \{} -> 42
f {} f {}
"# "
), ),
42, 42,
i64 i64
@ -668,10 +668,10 @@ fn pattern_matching_unit() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when {} is when {} is
{} -> 42 {} -> 42
"# "
), ),
42, 42,
i64 i64
@ -683,12 +683,12 @@ fn pattern_matching_unit() {
fn one_element_tag() { fn one_element_tag() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x : [Pair I64] x : [Pair I64]
x = Pair 2 x = Pair 2
x x
"# "
), ),
2, 2,
i64 i64
@ -721,14 +721,14 @@ fn nested_tag_union() {
fn unit_type() { fn unit_type() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Unit : [Unit] Unit : [Unit]
v : Unit v : Unit
v = Unit v = Unit
v v
"# "
), ),
(), (),
() ()
@ -740,12 +740,12 @@ fn unit_type() {
fn join_point_if() { fn join_point_if() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x = x =
if Bool.true then 1 else 2 if Bool.true then 1 else 2
x x
"# "
), ),
1, 1,
i64 i64
@ -757,7 +757,7 @@ fn join_point_if() {
fn join_point_when() { fn join_point_when() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
wrapper = \{} -> wrapper = \{} ->
x : [Red, White, Blue] x : [Red, White, Blue]
x = Blue x = Blue
@ -771,7 +771,7 @@ fn join_point_when() {
y y
wrapper {} wrapper {}
"# "
), ),
3.1, 3.1,
f64 f64
@ -783,7 +783,7 @@ fn join_point_when() {
fn join_point_with_cond_expr() { fn join_point_with_cond_expr() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
wrapper = \{} -> wrapper = \{} ->
y = y =
when 1 + 2 is when 1 + 2 is
@ -794,7 +794,7 @@ fn join_point_with_cond_expr() {
y y
wrapper {} wrapper {}
"# "
), ),
3, 3,
i64 i64
@ -802,7 +802,7 @@ fn join_point_with_cond_expr() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
y = y =
if 1 + 2 > 0 then if 1 + 2 > 0 then
3 3
@ -810,7 +810,7 @@ fn join_point_with_cond_expr() {
0 0
y y
"# "
), ),
3, 3,
i64 i64
@ -1135,12 +1135,12 @@ fn applied_tag_function_pair() {
fn tag_must_be_its_own_type() { fn tag_must_be_its_own_type() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
z : [A, B, C] z : [A, B, C]
z = Z z = Z
z z
"# "
), ),
1, 1,
i64 i64
@ -1171,12 +1171,12 @@ fn recursive_tag_union_into_flat_tag_union() {
fn monomorphized_tag() { fn monomorphized_tag() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
b = \{} -> Bar b = \{} -> Bar
f : [Foo, Bar], [Bar, Baz] -> U8 f : [Foo, Bar], [Bar, Baz] -> U8
f = \_, _ -> 18 f = \_, _ -> 18
f (b {}) (b {}) f (b {}) (b {})
"# "
), ),
18, 18,
u8 u8
@ -1391,7 +1391,7 @@ fn issue_2445() {
fn issue_2458() { fn issue_2458() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
Foo a : [Blah (Bar a), Nothing {}] Foo a : [Blah (Bar a), Nothing {}]
Bar a : Foo a Bar a : Foo a
@ -1401,7 +1401,7 @@ fn issue_2458() {
when v is when v is
Blah (Blah (Nothing {})) -> 15 Blah (Blah (Nothing {})) -> 15
_ -> 25 _ -> 25
"# "
), ),
15, 15,
u8 u8
@ -1471,11 +1471,11 @@ fn issue_1162() {
fn polymorphic_tag() { fn polymorphic_tag() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x : [Y U8] x : [Y U8]
x = Y 3 x = Y 3
x x
"# "
), ),
3, // Y is a newtype, it gets unwrapped 3, // Y is a newtype, it gets unwrapped
u8 u8
@ -1487,11 +1487,11 @@ fn polymorphic_tag() {
fn issue_2725_alias_polymorphic_lambda() { fn issue_2725_alias_polymorphic_lambda() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
wrap = \value -> Tag value wrap = \value -> Tag value
wrapIt = wrap wrapIt = wrap
wrapIt 42 wrapIt 42
"# "
), ),
42, // Tag is a newtype, it gets unwrapped 42, // Tag is a newtype, it gets unwrapped
i64 i64
@ -1717,7 +1717,7 @@ fn instantiate_annotated_as_recursive_alias_multiple_polymorphic_expr() {
fn issue_3560_nested_tag_constructor_is_newtype() { fn issue_3560_nested_tag_constructor_is_newtype() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f : _ -> u8 f : _ -> u8
f = \t -> f = \t ->
when t is when t is
@ -1725,7 +1725,7 @@ fn issue_3560_nested_tag_constructor_is_newtype() {
Wrapper (AlternatePayload it) -> it Wrapper (AlternatePayload it) -> it
{a: f (Wrapper (Payload 15u8)), b: f(Wrapper (AlternatePayload 31u8))} {a: f (Wrapper (Payload 15u8)), b: f(Wrapper (AlternatePayload 31u8))}
"# "
), ),
(15, 31), (15, 31),
(u8, u8) (u8, u8)
@ -1737,7 +1737,7 @@ fn issue_3560_nested_tag_constructor_is_newtype() {
fn issue_3560_nested_tag_constructor_is_record_newtype() { fn issue_3560_nested_tag_constructor_is_record_newtype() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f : _ -> u8 f : _ -> u8
f = \t -> f = \t ->
when t is when t is
@ -1745,7 +1745,7 @@ fn issue_3560_nested_tag_constructor_is_record_newtype() {
{wrapper: (AlternatePayload it)} -> it {wrapper: (AlternatePayload it)} -> it
{a: f {wrapper: (Payload 15u8)}, b: f {wrapper: (AlternatePayload 31u8)}} {a: f {wrapper: (Payload 15u8)}, b: f {wrapper: (AlternatePayload 31u8)}}
"# "
), ),
(15, 31), (15, 31),
(u8, u8) (u8, u8)
@ -1791,7 +1791,7 @@ fn alignment_i128() {
fn error_type_in_tag_union_payload() { fn error_type_in_tag_union_payload() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
f : ([] -> Bool) -> Bool f : ([] -> Bool) -> Bool
f = \fun -> f = \fun ->
if Bool.true then if Bool.true then
@ -1800,7 +1800,7 @@ fn error_type_in_tag_union_payload() {
Bool.false Bool.false
f (\x -> x) f (\x -> x)
"# "
), ),
0, 0,
u8, u8,
@ -1864,7 +1864,7 @@ fn issue_3653_recursion_pointer_in_naked_opaque_localized() {
fn issue_2165_recursive_tag_destructure() { fn issue_2165_recursive_tag_destructure() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
SomeTag : [ Ctor { rec : List SomeTag } ] SomeTag : [ Ctor { rec : List SomeTag } ]
x : SomeTag x : SomeTag
@ -1872,7 +1872,7 @@ fn issue_2165_recursive_tag_destructure() {
when x is when x is
Ctor { rec } -> Num.toStr (List.len rec) Ctor { rec } -> Num.toStr (List.len rec)
"# "
), ),
RocStr::from("0"), RocStr::from("0"),
RocStr RocStr
@ -2183,7 +2183,7 @@ fn issue_5162_recast_nested_nullable_unwrapped_layout() {
with_larger_debug_stack(|| { with_larger_debug_stack(|| {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r###" r#"
app "test" provides [main] to "./platform" app "test" provides [main] to "./platform"
Concept : [ Concept : [
@ -2197,7 +2197,7 @@ fn issue_5162_recast_nested_nullable_unwrapped_layout() {
main = main =
when Dict.single bottom 0 is when Dict.single bottom 0 is
_ -> Bool.true _ -> Bool.true
"### "#
), ),
true, true,
bool bool
@ -2210,7 +2210,7 @@ fn issue_5162_recast_nested_nullable_unwrapped_layout() {
fn nullable_wrapped_eq_issue_5434() { fn nullable_wrapped_eq_issue_5434() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r###" r#"
app "test" provides [main] to "./platform" app "test" provides [main] to "./platform"
Value : [ Value : [
@ -2229,7 +2229,7 @@ fn nullable_wrapped_eq_issue_5434() {
Bool.true Bool.true
else else
Bool.false Bool.false
"### "#
), ),
false, false,
bool bool
@ -2241,7 +2241,7 @@ fn nullable_wrapped_eq_issue_5434() {
fn recursive_tag_id_in_allocation_basic() { fn recursive_tag_id_in_allocation_basic() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r###" r#"
app "test" provides [main] to "./platform" app "test" provides [main] to "./platform"
Value : [ Value : [
@ -2270,7 +2270,7 @@ fn recursive_tag_id_in_allocation_basic() {
G _ -> "G" G _ -> "G"
H _ -> "H" H _ -> "H"
I _ -> "I" I _ -> "I"
"### "#
), ),
RocStr::from("H"), RocStr::from("H"),
RocStr RocStr
@ -2282,7 +2282,7 @@ fn recursive_tag_id_in_allocation_basic() {
fn recursive_tag_id_in_allocation_eq() { fn recursive_tag_id_in_allocation_eq() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r###" r#"
app "test" provides [main] to "./platform" app "test" provides [main] to "./platform"
Value : [ Value : [
@ -2304,7 +2304,7 @@ fn recursive_tag_id_in_allocation_eq() {
y = H 42 y = H 42
main = (x == x) && (x != y) && (y == y) main = (x == x) && (x != y) && (y == y)
"### "#
), ),
true, true,
bool bool

View file

@ -18,9 +18,9 @@ use roc_std::RocStr;
fn basic_tuple() { fn basic_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
( 15, 17, 19 ).0 ( 15, 17, 19 ).0
"# "
), ),
15, 15,
i64 i64
@ -28,9 +28,9 @@ fn basic_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
( 15, 17, 19 ).1 ( 15, 17, 19 ).1
"# "
), ),
17, 17,
i64 i64
@ -38,9 +38,9 @@ fn basic_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
( 15, 17, 19 ).2 ( 15, 17, 19 ).2
"# "
), ),
19, 19,
i64 i64
@ -52,11 +52,11 @@ fn basic_tuple() {
fn f64_tuple() { fn f64_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
tup = (17.2f64, 15.1f64, 19.3f64) tup = (17.2f64, 15.1f64, 19.3f64)
tup.0 tup.0
"# "
), ),
17.2, 17.2,
f64 f64
@ -64,11 +64,11 @@ fn f64_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
tup = (17.2f64, 15.1f64, 19.3f64) tup = (17.2f64, 15.1f64, 19.3f64)
tup.1 tup.1
"# "
), ),
15.1, 15.1,
f64 f64
@ -76,11 +76,11 @@ fn f64_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
tup = (17.2f64, 15.1f64, 19.3f64) tup = (17.2f64, 15.1f64, 19.3f64)
tup.2 tup.2
"# "
), ),
19.3, 19.3,
f64 f64
@ -104,11 +104,11 @@ fn fn_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = (15, 17, 19) rec = (15, 17, 19)
rec.2 + rec.0 rec.2 + rec.0
"# "
), ),
34, 34,
i64 i64
@ -120,11 +120,11 @@ fn fn_tuple() {
fn int_tuple() { fn int_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = (15, 17, 19) rec = (15, 17, 19)
rec.0 rec.0
"# "
), ),
15, 15,
i64 i64
@ -132,11 +132,11 @@ fn int_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = (15, 17, 19) rec = (15, 17, 19)
rec.1 rec.1
"# "
), ),
17, 17,
i64 i64
@ -144,11 +144,11 @@ fn int_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
rec = (15, 17, 19) rec = (15, 17, 19)
rec.2 rec.2
"# "
), ),
19, 19,
i64 i64
@ -160,10 +160,10 @@ fn int_tuple() {
fn when_on_tuple() { fn when_on_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when (0x2, 0x3) is when (0x2, 0x3) is
(x, y) -> x + y (x, y) -> x + y
"# "
), ),
5, 5,
i64 i64
@ -175,10 +175,10 @@ fn when_on_tuple() {
fn when_tuple_with_guard_pattern() { fn when_tuple_with_guard_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when (0x2, 1.23) is when (0x2, 1.23) is
(var, _) -> var + 3 (var, _) -> var + 3
"# "
), ),
5, 5,
i64 i64
@ -190,11 +190,11 @@ fn when_tuple_with_guard_pattern() {
fn let_with_tuple_pattern() { fn let_with_tuple_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
(x, _ ) = (0x2, 1.23) (x, _ ) = (0x2, 1.23)
x x
"# "
), ),
2, 2,
i64 i64
@ -202,11 +202,11 @@ fn let_with_tuple_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
(_, y) = (0x2, 0x3) (_, y) = (0x2, 0x3)
y y
"# "
), ),
3, 3,
i64 i64
@ -218,11 +218,11 @@ fn let_with_tuple_pattern() {
fn tuple_guard_pattern() { fn tuple_guard_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when (0x2, 1.23) is when (0x2, 1.23) is
(0x4, _) -> 5 (0x4, _) -> 5
(x, _) -> x + 4 (x, _) -> x + 4
"# "
), ),
6, 6,
i64 i64
@ -230,11 +230,11 @@ fn tuple_guard_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
when (0x2, 0x3) is when (0x2, 0x3) is
(_, 0x4) -> 5 (_, 0x4) -> 5
(_, x) -> x + 4 (_, x) -> x + 4
"# "
), ),
7, 7,
i64 i64
@ -246,11 +246,11 @@ fn tuple_guard_pattern() {
fn twice_tuple_access() { fn twice_tuple_access() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x = (0x2, 0x3) x = (0x2, 0x3)
x.0 + x.1 x.0 + x.1
"# "
), ),
5, 5,
i64 i64
@ -262,9 +262,9 @@ fn twice_tuple_access() {
fn i64_tuple2_literal() { fn i64_tuple2_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
(3, 5) (3, 5)
"# "
), ),
(3, 5), (3, 5),
(i64, i64) (i64, i64)
@ -276,9 +276,9 @@ fn i64_tuple2_literal() {
fn i64_tuple3_literal() { fn i64_tuple3_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
(3, 5, 17) (3, 5, 17)
"# "
), ),
(3, 5, 17), (3, 5, 17),
(i64, i64, i64) (i64, i64, i64)
@ -290,9 +290,9 @@ fn i64_tuple3_literal() {
fn f64_tuple2_literal() { fn f64_tuple2_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
(3.1f64, 5.1f64) (3.1f64, 5.1f64)
"# "
), ),
(3.1, 5.1), (3.1, 5.1),
(f64, f64) (f64, f64)
@ -304,12 +304,12 @@ fn f64_tuple2_literal() {
fn bool_tuple4_literal() { fn bool_tuple4_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
tuple : (Bool, Bool, Bool, Bool) tuple : (Bool, Bool, Bool, Bool)
tuple = (Bool.true, Bool.false, Bool.false, Bool.true) tuple = (Bool.true, Bool.false, Bool.false, Bool.true)
tuple tuple
"# "
), ),
(true, false, false, true), (true, false, false, true),
(bool, bool, bool, bool) (bool, bool, bool, bool)
@ -323,9 +323,9 @@ fn bool_tuple4_literal() {
fn i64_tuple9_literal() { fn i64_tuple9_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
( 3, 5, 17, 1, 9, 12, 13, 14, 15 ) ( 3, 5, 17, 1, 9, 12, 13, 14, 15 )
"# "
), ),
[3, 5, 17, 1, 9, 12, 13, 14, 15], [3, 5, 17, 1, 9, 12, 13, 14, 15],
[i64; 9] [i64; 9]
@ -337,12 +337,12 @@ fn i64_tuple9_literal() {
fn return_tuple() { fn return_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x = 4 x = 4
y = 3 y = 3
(x, y) (x, y)
"# "
), ),
(4, 3), (4, 3),
(i64, i64) (i64, i64)
@ -354,9 +354,9 @@ fn return_tuple() {
fn return_tuple_2() { fn return_tuple_2() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
(3, 5) (3, 5)
"# "
), ),
[3, 5], [3, 5],
[i64; 2] [i64; 2]
@ -368,9 +368,9 @@ fn return_tuple_2() {
fn return_tuple_3() { fn return_tuple_3() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
( 3, 5, 4 ) ( 3, 5, 4 )
"# "
), ),
(3, 5, 4), (3, 5, 4),
(i64, i64, i64) (i64, i64, i64)
@ -382,9 +382,9 @@ fn return_tuple_3() {
fn return_tuple_4() { fn return_tuple_4() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
( 3, 5, 4, 2 ) ( 3, 5, 4, 2 )
"# "
), ),
[3, 5, 4, 2], [3, 5, 4, 2],
[i64; 4] [i64; 4]
@ -398,9 +398,9 @@ fn return_tuple_4() {
fn return_tuple_5() { fn return_tuple_5() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
( 3, 5, 4, 2, 1 ) ( 3, 5, 4, 2, 1 )
"# "
), ),
[3, 5, 4, 2, 1], [3, 5, 4, 2, 1],
[i64; 5] [i64; 5]
@ -414,9 +414,9 @@ fn return_tuple_5() {
fn return_tuple_6() { fn return_tuple_6() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
( 3, 5, 4, 2, 1, 7 ) ( 3, 5, 4, 2, 1, 7 )
"# "
), ),
[3, 5, 4, 2, 1, 7], [3, 5, 4, 2, 1, 7],
[i64; 6] [i64; 6]
@ -430,9 +430,9 @@ fn return_tuple_6() {
fn return_tuple_7() { fn return_tuple_7() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
( 3, 5, 4, 2, 1, 7, 8 ) ( 3, 5, 4, 2, 1, 7, 8 )
"# "
), ),
[3, 5, 4, 2, 1, 7, 8], [3, 5, 4, 2, 1, 7, 8],
[i64; 7] [i64; 7]
@ -444,9 +444,9 @@ fn return_tuple_7() {
fn return_tuple_float_int() { fn return_tuple_float_int() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
(1.23f64, 0x1) (1.23f64, 0x1)
"# "
), ),
(1.23, 0x1), (1.23, 0x1),
(f64, i64) (f64, i64)
@ -458,9 +458,9 @@ fn return_tuple_float_int() {
fn return_tuple_int_float() { fn return_tuple_int_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
( 0x1, 1.23f64 ) ( 0x1, 1.23f64 )
"# "
), ),
(0x1, 1.23), (0x1, 1.23),
(i64, f64) (i64, f64)
@ -472,9 +472,9 @@ fn return_tuple_int_float() {
fn return_tuple_float_float() { fn return_tuple_float_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
( 2.46f64, 1.23f64 ) ( 2.46f64, 1.23f64 )
"# "
), ),
(2.46, 1.23), (2.46, 1.23),
(f64, f64) (f64, f64)
@ -486,9 +486,9 @@ fn return_tuple_float_float() {
fn return_tuple_float_float_float() { fn return_tuple_float_float_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
( 2.46f64, 1.23f64, 0.1f64 ) ( 2.46f64, 1.23f64, 0.1f64 )
"# "
), ),
(2.46, 1.23, 0.1), (2.46, 1.23, 0.1),
(f64, f64, f64) (f64, f64, f64)
@ -500,9 +500,9 @@ fn return_tuple_float_float_float() {
fn return_nested_tuple() { fn return_nested_tuple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
(0x0, (2.46f64, 1.23f64, 0.1f64)) (0x0, (2.46f64, 1.23f64, 0.1f64))
"# "
), ),
(0x0, (2.46, 1.23, 0.1)), (0x0, (2.46, 1.23, 0.1)),
(i64, (f64, f64, f64)) (i64, (f64, f64, f64))
@ -514,13 +514,13 @@ fn return_nested_tuple() {
fn nested_tuple_load() { fn nested_tuple_load() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
x = (0, (0x2, 0x5, 0x6)) x = (0, (0x2, 0x5, 0x6))
y = x.1 y = x.1
y.2 y.2
"# "
), ),
6, 6,
i64 i64
@ -572,7 +572,7 @@ fn alignment_in_tuple() {
fn tuple_length_polymorphism() { fn tuple_length_polymorphism() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r"
a = (42, 43) a = (42, 43)
b = (1, 2, 44) b = (1, 2, 44)
@ -580,7 +580,7 @@ fn tuple_length_polymorphism() {
f = \(x1, x2), (x3, x4) -> x1 + x2 + x3 + x4 f = \(x1, x2), (x3, x4) -> x1 + x2 + x3 + x4
f a b f a b
"# "
), ),
88, 88,
i64 i64

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -438,11 +438,19 @@ impl<R: Read> Read for ProgressReporter<R> {
self.read += size; self.read += size;
if let Some(total) = self.total { if let Some(total) = self.total {
let total = total as f32 / 1_000_000.0;
let read = self.read as f32 / 1_000_000.0;
if total < 1.0 {
eprint!( eprint!(
"\u{001b}[2K\u{001b}[G[{:.1} / {:.1} MB]", "\u{001b}[2K\u{001b}[G[{:.1} / {:.1} KB]",
self.read as f32 / 1_000_000.0, // Convert MB to KB
total as f32 / 1_000_000.0, read * 1000.0,
total * 1000.0,
); );
} else {
eprint!("\u{001b}[2K\u{001b}[G[{:.1} / {:.1} MB]", read, total,);
}
} else { } else {
eprint!( eprint!(
"\u{001b}[2K\u{001b}[G[{:.1} MB]", "\u{001b}[2K\u{001b}[G[{:.1} MB]",

View file

@ -238,12 +238,12 @@ mod test {
"# "#
), ),
indoc!( indoc!(
r#" r"
This expectation failed: This expectation failed:
5 expect 1 == 2 5 expect 1 == 2
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
"# "
), ),
); );
} }
@ -265,7 +265,7 @@ mod test {
"# "#
), ),
indoc!( indoc!(
r#" r"
This expectation failed: This expectation failed:
5> expect 5> expect
@ -281,7 +281,7 @@ mod test {
b : Num * b : Num *
b = 2 b = 2
"# "
), ),
); );
} }
@ -380,7 +380,7 @@ mod test {
"# "#
), ),
indoc!( indoc!(
r#" r"
This expectation failed: This expectation failed:
5> expect 5> expect
@ -397,7 +397,7 @@ mod test {
expected : Result I64 [OutOfBounds] expected : Result I64 [OutOfBounds]
expected = Ok 42 expected = Ok 42
"# "
), ),
); );
} }
@ -463,7 +463,7 @@ mod test {
"# "#
), ),
indoc!( indoc!(
r#" r"
This expectation failed: This expectation failed:
5> expect 5> expect
@ -485,7 +485,7 @@ mod test {
y : U8, y : U8,
} }
vec2 = { x: 4, y: 8 } vec2 = { x: 4, y: 8 }
"# "
), ),
); );
} }
@ -965,22 +965,22 @@ mod test {
fn issue_i4389() { fn issue_i4389() {
run_expect_test( run_expect_test(
indoc!( indoc!(
r#" r"
interface Test exposes [] imports [] interface Test exposes [] imports []
expect expect
totalCount = \{} -> 1u8 totalCount = \{} -> 1u8
totalCount {} == 96u8 totalCount {} == 96u8
"# "
), ),
indoc!( indoc!(
r#" r"
This expectation failed: This expectation failed:
3> expect 3> expect
4> totalCount = \{} -> 1u8 4> totalCount = \{} -> 1u8
5> totalCount {} == 96u8 5> totalCount {} == 96u8
"# "
), ),
); );
} }
@ -989,7 +989,7 @@ mod test {
fn adjacent_lists() { fn adjacent_lists() {
run_expect_test( run_expect_test(
indoc!( indoc!(
r#" r"
interface Test exposes [] imports [] interface Test exposes [] imports []
expect expect
@ -1007,10 +1007,10 @@ mod test {
x: [115, 116, 117], x: [115, 116, 117],
} }
actual == expected actual == expected
"# "
), ),
indoc!( indoc!(
r#" r"
This expectation failed: This expectation failed:
3> expect 3> expect
@ -1044,7 +1044,7 @@ mod test {
x : List (Int Unsigned8), x : List (Int Unsigned8),
} }
expected = { body: [42, 43, 44], headers: [15, 16, 17], x: [115, 116, 117] } expected = { body: [42, 43, 44], headers: [15, 16, 17], x: [115, 116, 117] }
"# "
), ),
); );
} }
@ -1113,7 +1113,7 @@ mod test {
fn tag_payloads_of_different_size() { fn tag_payloads_of_different_size() {
run_expect_test( run_expect_test(
indoc!( indoc!(
r#" r"
interface Test exposes [] imports [] interface Test exposes [] imports []
actual : [Leftover (List U8), TooShort] actual : [Leftover (List U8), TooShort]
@ -1124,10 +1124,10 @@ mod test {
expected = TooShort expected = TooShort
actual == expected actual == expected
"# "
), ),
indoc!( indoc!(
r#" r"
This expectation failed: This expectation failed:
6> expect 6> expect
@ -1143,7 +1143,7 @@ mod test {
TooShort, TooShort,
] ]
expected = TooShort expected = TooShort
"# "
), ),
); );
} }
@ -1220,7 +1220,7 @@ mod test {
fn match_on_opaque_number_type() { fn match_on_opaque_number_type() {
run_expect_test( run_expect_test(
indoc!( indoc!(
r#" r"
interface Test exposes [] imports [] interface Test exposes [] imports []
hexToByte : U8, U8 -> U8 hexToByte : U8, U8 -> U8
@ -1231,10 +1231,10 @@ mod test {
actual = hexToByte 7 4 actual = hexToByte 7 4
expected = 't' expected = 't'
actual == expected actual == expected
"# "
), ),
indoc!( indoc!(
r#" r"
This expectation failed: This expectation failed:
7> expect 7> expect
@ -1249,7 +1249,7 @@ mod test {
expected : Int Unsigned8 expected : Int Unsigned8
expected = 116 expected = 116
"# "
), ),
); );
} }

View file

@ -124,11 +124,11 @@ fn bool_basic_equality() {
fn bool_true() { fn bool_true() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
Bool.true Bool.true
"# "
), ),
r#"Bool.true : Bool"#, r"Bool.true : Bool",
); );
} }
@ -136,11 +136,11 @@ fn bool_true() {
fn bool_false() { fn bool_false() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
Bool.false Bool.false
"# "
), ),
r#"Bool.false : Bool"#, r"Bool.false : Bool",
); );
} }
@ -315,24 +315,24 @@ fn nested_string_list() {
#[test] #[test]
fn nested_num_list() { fn nested_num_list() {
expect_success( expect_success(
r#"[[[4, 3, 2], [1, 0]], [[]], []]"#, r"[[[4, 3, 2], [1, 0]], [[]], []]",
r#"[[[4, 3, 2], [1, 0]], [[]], []] : List (List (List (Num *)))"#, r"[[[4, 3, 2], [1, 0]], [[]], []] : List (List (List (Num *)))",
); );
} }
#[test] #[test]
fn nested_int_list() { fn nested_int_list() {
expect_success( expect_success(
r#"[[[4, 3, 2], [1, 0x0]], [[]], []]"#, r"[[[4, 3, 2], [1, 0x0]], [[]], []]",
r#"[[[4, 3, 2], [1, 0]], [[]], []] : List (List (List (Int *)))"#, r"[[[4, 3, 2], [1, 0]], [[]], []] : List (List (List (Int *)))",
); );
} }
#[test] #[test]
fn nested_float_list() { fn nested_float_list() {
expect_success( expect_success(
r#"[[[4, 3, 2], [1, 0.0]], [[]], []]"#, r"[[[4, 3, 2], [1, 0.0]], [[]], []]",
r#"[[[4, 3, 2], [1, 0]], [[]], []] : List (List (List (Frac *)))"#, r"[[[4, 3, 2], [1, 0]], [[]], []] : List (List (List (Frac *)))",
); );
} }
@ -641,7 +641,7 @@ fn too_few_args() {
expect_failure( expect_failure(
"Num.add 2", "Num.add 2",
indoc!( indoc!(
r#" r"
TOO FEW ARGS TOO FEW ARGS
The add function expects 2 arguments, but it got only 1: The add function expects 2 arguments, but it got only 1:
@ -651,7 +651,7 @@ fn too_few_args() {
Roc does not allow functions to be partially applied. Use a closure to Roc does not allow functions to be partially applied. Use a closure to
make partial application explicit. make partial application explicit.
"# "
), ),
); );
} }
@ -970,7 +970,7 @@ fn large_nullable_wrapped_tag_union() {
fn issue_2300() { fn issue_2300() {
expect_success( expect_success(
r#"\Email str -> str == """#, r#"\Email str -> str == """#,
r#"<function> : [Email Str] -> Bool"#, r"<function> : [Email Str] -> Bool",
) )
} }
@ -978,8 +978,8 @@ fn issue_2300() {
#[test] #[test]
fn function_in_list() { fn function_in_list() {
expect_success( expect_success(
r#"[\x -> x + 1, \s -> s * 2]"#, r"[\x -> x + 1, \s -> s * 2]",
r#"[<function>, <function>] : List (Num a -> Num a)"#, r"[<function>, <function>] : List (Num a -> Num a)",
) )
} }
@ -987,8 +987,8 @@ fn function_in_list() {
#[test] #[test]
fn function_in_record() { fn function_in_record() {
expect_success( expect_success(
r#"{ n: 1, adder: \x -> x + 1 }"#, r"{ n: 1, adder: \x -> x + 1 }",
r#"{ adder: <function>, n: 1 } : { adder : Num a -> Num a, n : Num * }"#, r"{ adder: <function>, n: 1 } : { adder : Num a -> Num a, n : Num * }",
) )
} }
@ -996,8 +996,8 @@ fn function_in_record() {
#[test] #[test]
fn function_in_unwrapped_record() { fn function_in_unwrapped_record() {
expect_success( expect_success(
r#"{ adder: \x -> x + 1 }"#, r"{ adder: \x -> x + 1 }",
r#"{ adder: <function> } : { adder : Num a -> Num a }"#, r"{ adder: <function> } : { adder : Num a -> Num a }",
) )
} }
@ -1005,16 +1005,16 @@ fn function_in_unwrapped_record() {
#[test] #[test]
fn function_in_tag() { fn function_in_tag() {
expect_success( expect_success(
r#"Adder (\x -> x + 1)"#, r"Adder (\x -> x + 1)",
r#"Adder <function> : [Adder (Num a -> Num a)]"#, r"Adder <function> : [Adder (Num a -> Num a)]",
) )
} }
#[test] #[test]
fn newtype_of_record_of_tag_of_record_of_tag() { fn newtype_of_record_of_tag_of_record_of_tag() {
expect_success( expect_success(
r#"A {b: C {d: 1}}"#, r"A {b: C {d: 1}}",
r#"A { b: C { d: 1 } } : [A { b : [C { d : Num * }] }]"#, r"A { b: C { d: 1 } } : [A { b : [C { d : Num * }] }]",
) )
} }
@ -1022,11 +1022,11 @@ fn newtype_of_record_of_tag_of_record_of_tag() {
fn print_u8s() { fn print_u8s() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
x : U8 x : U8
x = 129 x = 129
x x
"# "
), ),
"129 : U8", "129 : U8",
) )
@ -1062,17 +1062,17 @@ fn parse_problem() {
fn issue_2343_complete_mono_with_shadowed_vars() { fn issue_2343_complete_mono_with_shadowed_vars() {
expect_failure( expect_failure(
indoc!( indoc!(
r#" r"
b = False b = False
f = \b -> f = \b ->
when b is when b is
True -> 5 True -> 5
False -> 15 False -> 15
f b f b
"# "
), ),
indoc!( indoc!(
r#" r"
DUPLICATE NAME DUPLICATE NAME
The b name is first defined here: The b name is first defined here:
@ -1087,7 +1087,7 @@ fn issue_2343_complete_mono_with_shadowed_vars() {
Since these variables have the same name, it's easy to use the wrong Since these variables have the same name, it's easy to use the wrong
one by accident. Give one of them a new name. one by accident. Give one of them a new name.
"# "
), ),
); );
} }
@ -1126,12 +1126,12 @@ fn tag_with_type_behind_alias() {
fn issue_2588_record_with_function_and_nonfunction() { fn issue_2588_record_with_function_and_nonfunction() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
x = 1 x = 1
f = \n -> n * 2 f = \n -> n * 2
{ y: f x, f }"# { y: f x, f }"
), ),
r#"{ f: <function>, y: 2 } : { f : Num a -> Num a, y : Num * }"#, r"{ f: <function>, y: 2 } : { f : Num a -> Num a, y : Num * }",
) )
} }
@ -1139,10 +1139,10 @@ fn issue_2588_record_with_function_and_nonfunction() {
fn opaque_apply() { fn opaque_apply() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
Age := U32 Age := U32
@Age 23"# @Age 23"
), ),
"@Age 23 : Age", "@Age 23 : Age",
) )
@ -1165,14 +1165,14 @@ fn opaque_apply_polymorphic() {
fn opaque_pattern_and_call() { fn opaque_pattern_and_call() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
F t u := [Package t u] F t u := [Package t u]
f = \@F (Package A {}) -> @F (Package {} A) f = \@F (Package A {}) -> @F (Package {} A)
f (@F (Package A {}))"# f (@F (Package A {}))"
), ),
r#"@F (Package {} A) : F {} [A]"#, r"@F (Package {} A) : F {} [A]",
) )
} }
@ -1180,10 +1180,10 @@ fn opaque_pattern_and_call() {
fn dec_in_repl() { fn dec_in_repl() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
x: Dec x: Dec
x=1.23 x=1.23
x"# x"
), ),
"1.23 : Dec", "1.23 : Dec",
) )
@ -1193,12 +1193,12 @@ fn dec_in_repl() {
fn print_i8_issue_2710() { fn print_i8_issue_2710() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
a : I8 a : I8
a = -1 a = -1
a"# a"
), ),
r#"-1 : I8"#, r"-1 : I8",
) )
} }
@ -1243,11 +1243,11 @@ fn issue_2582_specialize_result_value() {
fn issue_2818() { fn issue_2818() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
f : {} -> List Str f : {} -> List Str
f = \_ -> f = \_ ->
x = [] x = []
x"# x"
), ),
r"<function> : {} -> List Str", r"<function> : {} -> List Str",
) )
@ -1257,7 +1257,7 @@ fn issue_2818() {
fn issue_2810_recursive_layout_inside_nonrecursive() { fn issue_2810_recursive_layout_inside_nonrecursive() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
Command : [Command Tool] Command : [Command Tool]
Job : [Job Command] Job : [Job Command]
@ -1266,7 +1266,7 @@ fn issue_2810_recursive_layout_inside_nonrecursive() {
a : Job a : Job
a = Job (Command (FromJob (Job (Command SystemTool)))) a = Job (Command (FromJob (Job (Command SystemTool))))
a"# a"
), ),
"Job (Command (FromJob (Job (Command SystemTool)))) : Job", "Job (Command (FromJob (Job (Command SystemTool)))) : Job",
) )
@ -1276,12 +1276,12 @@ fn issue_2810_recursive_layout_inside_nonrecursive() {
fn render_nullable_unwrapped_passing_through_alias() { fn render_nullable_unwrapped_passing_through_alias() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
Deep : [L DeepList] Deep : [L DeepList]
DeepList : [Nil, Cons Deep] DeepList : [Nil, Cons Deep]
v : DeepList v : DeepList
v = (Cons (L (Cons (L (Cons (L Nil)))))) v = (Cons (L (Cons (L (Cons (L Nil))))))
v"# v"
), ),
"Cons (L (Cons (L (Cons (L Nil))))) : DeepList", "Cons (L (Cons (L (Cons (L Nil))))) : DeepList",
) )
@ -1291,9 +1291,9 @@ fn render_nullable_unwrapped_passing_through_alias() {
fn opaque_wrap_function() { fn opaque_wrap_function() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
A a := a A a := a
List.map [1u8, 2u8, 3u8] @A"# List.map [1u8, 2u8, 3u8] @A"
), ),
"[@A 1, @A 2, @A 3] : List (A U8)", "[@A 1, @A 2, @A 3] : List (A U8)",
); );
@ -1305,10 +1305,10 @@ fn opaque_wrap_function() {
fn dict_get_single() { fn dict_get_single() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
Dict.single 0 {a: 1, c: 2} |> Dict.get 0"# Dict.single 0 {a: 1, c: 2} |> Dict.get 0"
), ),
r#"Ok { a: 1, c: 2 } : Result { a : Num *, c : Num * } [KeyNotFound]"#, r"Ok { a: 1, c: 2 } : Result { a : Num *, c : Num * } [KeyNotFound]",
) )
} }
@ -1319,7 +1319,7 @@ fn record_of_poly_function() {
r#" r#"
{ a: \_ -> "a" }"# { a: \_ -> "a" }"#
), ),
r#"{ a: <function> } : { a : * -> Str }"#, r"{ a: <function> } : { a : * -> Str }",
); );
} }
@ -1338,18 +1338,18 @@ fn record_of_poly_function_and_string() {
fn newtype_by_void_is_wrapped() { fn newtype_by_void_is_wrapped() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
Result.try (Err 42) (\x -> Err (x+1))"# Result.try (Err 42) (\x -> Err (x+1))"
), ),
r#"Err 42 : Result b (Num *)"#, r"Err 42 : Result b (Num *)",
); );
expect_success( expect_success(
indoc!( indoc!(
r#" r"
Result.try (Ok 42) (\x -> Ok (x+1))"# Result.try (Ok 42) (\x -> Ok (x+1))"
), ),
r#"Ok 43 : Result (Num *) err"#, r"Ok 43 : Result (Num *) err",
); );
} }
@ -1357,11 +1357,11 @@ fn newtype_by_void_is_wrapped() {
fn enum_tag_union_in_list() { fn enum_tag_union_in_list() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
[E, F, G, H] [E, F, G, H]
"# "
), ),
r#"[E, F, G, H] : List [E, F, G, H]"#, r"[E, F, G, H] : List [E, F, G, H]",
); );
} }
@ -1373,7 +1373,7 @@ fn str_to_dec() {
Str.toDec "1234.1234" Str.toDec "1234.1234"
"# "#
), ),
r#"Ok 1234.1234 : Result Dec [InvalidNumStr]"#, r"Ok 1234.1234 : Result Dec [InvalidNumStr]",
); );
} }
@ -1405,7 +1405,7 @@ fn nested_tuple() {
fn ordered_tag_union_memory_layout() { fn ordered_tag_union_memory_layout() {
expect_success( expect_success(
indoc!( indoc!(
r#" r"
Loc : { line: U32, column: U32 } Loc : { line: U32, column: U32 }
Node : [ A Loc, Height U8 Loc ] Node : [ A Loc, Height U8 Loc ]
@ -1413,9 +1413,9 @@ fn ordered_tag_union_memory_layout() {
x : Node x : Node
x = Height 1 { line: 2, column: 3 } x = Height 1 { line: 2, column: 3 }
x x
"# "
), ),
r#"Height 1 { column: 3, line: 2 } : Node"#, r"Height 1 { column: 3, line: 2 } : Node",
); );
} }

View file

@ -2,6 +2,7 @@ use std::path::PathBuf;
use roc_collections::MutMap; use roc_collections::MutMap;
use roc_module::symbol::{Interns, ModuleId}; use roc_module::symbol::{Interns, ModuleId};
use roc_problem::can::Problem;
use roc_region::all::LineInfo; use roc_region::all::LineInfo;
use roc_solve_problem::TypeError; use roc_solve_problem::TypeError;
@ -87,29 +88,6 @@ pub fn report_problems(
// Report parsing and canonicalization problems // Report parsing and canonicalization problems
let alloc = RocDocAllocator::new(&src_lines, *home, interns); let alloc = RocDocAllocator::new(&src_lines, *home, interns);
let problems = can_problems.remove(home).unwrap_or_default();
for problem in problems.into_iter() {
let report = can_problem(&alloc, &lines, module_path.clone(), problem);
let severity = report.severity;
let mut buf = String::new();
report.render_color_terminal(&mut buf, &alloc, &palette);
match severity {
Warning => {
warnings.push(buf);
}
RuntimeError => {
errors.push(buf);
}
Fatal => {
fatally_errored = true;
errors.push(buf);
}
}
}
let problems = type_problems.remove(home).unwrap_or_default(); let problems = type_problems.remove(home).unwrap_or_default();
for problem in problems { for problem in problems {
@ -133,6 +111,43 @@ pub fn report_problems(
} }
} }
} }
// Shadowing errors often cause cryptic type errors. To make it easy to spot the root cause,
// we print the shadowing errors last.
let problems = can_problems.remove(home).unwrap_or_default();
let (shadowing_errs, mut ordered): (Vec<Problem>, Vec<Problem>) =
problems.into_iter().partition(|p| {
matches!(
p,
Problem::Shadowing {
original_region: _,
shadow: _,
kind: _,
}
)
});
ordered.extend(shadowing_errs);
for problem in ordered.into_iter() {
let report = can_problem(&alloc, &lines, module_path.clone(), problem);
let severity = report.severity;
let mut buf = String::new();
report.render_color_terminal(&mut buf, &alloc, &palette);
match severity {
Warning => {
warnings.push(buf);
}
RuntimeError => {
errors.push(buf);
}
Fatal => {
fatally_errored = true;
errors.push(buf);
}
}
}
} }
debug_assert!(can_problems.is_empty() && type_problems.is_empty(), "After reporting problems, there were {:?} can_problems and {:?} type_problems that could not be reported because they did not have corresponding entries in `sources`.", can_problems.len(), type_problems.len()); debug_assert!(can_problems.is_empty() && type_problems.is_empty(), "After reporting problems, there were {:?} can_problems and {:?} type_problems that could not be reported because they did not have corresponding entries in `sources`.", can_problems.len(), type_problems.len());

View file

@ -149,7 +149,7 @@ fn run_with_valgrind(binary_path: &std::path::Path) {
let memory_errors = extract_valgrind_errors(&raw_xml).unwrap_or_else(|err| { let memory_errors = extract_valgrind_errors(&raw_xml).unwrap_or_else(|err| {
panic!( panic!(
indoc!( indoc!(
r#" r"
failed to parse the `valgrind` xml output: failed to parse the `valgrind` xml output:
Error was: Error was:
@ -167,7 +167,7 @@ fn run_with_valgrind(binary_path: &std::path::Path) {
valgrind stderr was: valgrind stderr was:
{} {}
"# "
), ),
err, raw_xml, valgrind_out.stdout, valgrind_out.stderr err, raw_xml, valgrind_out.stdout, valgrind_out.stderr
); );
@ -214,7 +214,7 @@ fn list_concat_consumes_first_argument() {
#[test] #[test]
fn list_concat_consumes_second_argument() { fn list_concat_consumes_second_argument() {
valgrind_test(indoc!( valgrind_test(indoc!(
r#" r"
( (
a : List U8 a : List U8
a = [] a = []
@ -223,7 +223,7 @@ fn list_concat_consumes_second_argument() {
|> List.len |> List.len
|> Num.toStr |> Num.toStr
) )
"# "
)); ));
} }
@ -273,7 +273,7 @@ fn str_concat_first_argument_not_unique() {
#[test] #[test]
fn list_concat_empty_list_zero_sized_type() { fn list_concat_empty_list_zero_sized_type() {
valgrind_test(indoc!( valgrind_test(indoc!(
r#" r"
( (
a = List.reserve [] 11 a = List.reserve [] 11
b = [] b = []
@ -281,7 +281,7 @@ fn list_concat_empty_list_zero_sized_type() {
|> List.len |> List.len
|> Num.toStr |> Num.toStr
) )
"# "
)); ));
} }
@ -316,7 +316,7 @@ fn str_trim_start_capacity() {
#[test] #[test]
fn str_concat_later_referencing_empty_list_with_capacity() { fn str_concat_later_referencing_empty_list_with_capacity() {
valgrind_test(indoc!( valgrind_test(indoc!(
r#" r"
( (
a : List U8 a : List U8
a = List.withCapacity 1 a = List.withCapacity 1
@ -326,7 +326,7 @@ fn str_concat_later_referencing_empty_list_with_capacity() {
|> Num.addWrap (List.len a) |> Num.addWrap (List.len a)
|> Num.toStr |> Num.toStr
) )
"# "
)); ));
} }
@ -504,7 +504,7 @@ fn tree_rebalance() {
#[test] #[test]
fn lowlevel_list_calls() { fn lowlevel_list_calls() {
valgrind_test(indoc!( valgrind_test(indoc!(
r#" r"
( (
a = List.map [1,1,1,1,1] (\x -> x + 0) a = List.map [1,1,1,1,1] (\x -> x + 0)
b = List.map2 a [1,1,1,1,1] (\x, y -> x + y) b = List.map2 a [1,1,1,1,1] (\x, y -> x + y)
@ -514,7 +514,7 @@ fn lowlevel_list_calls() {
Num.toStr (List.len e) Num.toStr (List.len e)
) )
"# "
)); ));
} }

View file

@ -1,6 +1,8 @@
mod frame; mod frame;
mod instance; mod instance;
#[cfg(test)]
mod tests; mod tests;
mod value_store; mod value_store;
pub mod wasi; pub mod wasi;

View file

@ -0,0 +1,814 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "addr2line"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "allocator-api2"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
[[package]]
name = "arrayvec"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "backtrace"
version = "0.3.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]]
name = "base64"
version = "0.21.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitmaps"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2"
dependencies = [
"typenum",
]
[[package]]
name = "bitvec"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]]
name = "bumpalo"
version = "3.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
[[package]]
name = "cc"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
"cfg-if",
]
[[package]]
name = "deranged"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8810e7e2cf385b1e9b50d68264908ec367ba642c96d02edfe61c39e88e2a3c01"
[[package]]
name = "doc-comment"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "encode_unicode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]]
name = "flate2"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "funty"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "gimli"
version = "0.27.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "host"
version = "0.0.1"
dependencies = [
"libc",
"pulldown-cmark",
"roc_highlight",
"roc_std",
"syntect",
]
[[package]]
name = "html-escape"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476"
dependencies = [
"utf8-width",
]
[[package]]
name = "im"
version = "15.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9"
dependencies = [
"bitmaps",
"rand_core",
"rand_xoshiro",
"sized-chunks",
"typenum",
"version_check",
]
[[package]]
name = "im-rc"
version = "15.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe"
dependencies = [
"bitmaps",
"rand_core",
"rand_xoshiro",
"sized-chunks",
"typenum",
"version_check",
]
[[package]]
name = "indexmap"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
]
[[package]]
name = "itoa"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]]
name = "libc"
version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "line-wrap"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9"
dependencies = [
"safemem",
]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "miniz_oxide"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
dependencies = [
"adler",
]
[[package]]
name = "object"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "onig"
version = "6.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
dependencies = [
"bitflags",
"libc",
"once_cell",
"onig_sys",
]
[[package]]
name = "onig_sys"
version = "69.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7"
dependencies = [
"cc",
"pkg-config",
]
[[package]]
name = "pkg-config"
version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "plist"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdc0001cfea3db57a2e24bc0d818e9e20e554b5f97fabb9bc231dc240269ae06"
dependencies = [
"base64",
"indexmap",
"line-wrap",
"quick-xml",
"serde",
"time",
]
[[package]]
name = "proc-macro2"
version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "pulldown-cmark"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998"
dependencies = [
"bitflags",
"memchr",
"unicase",
]
[[package]]
name = "quick-xml"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51"
dependencies = [
"memchr",
]
[[package]]
name = "quote"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
dependencies = [
"proc-macro2",
]
[[package]]
name = "radium"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]]
name = "rand_xoshiro"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
dependencies = [
"rand_core",
]
[[package]]
name = "regex-syntax"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
[[package]]
name = "roc_collections"
version = "0.0.1"
dependencies = [
"bitvec",
"bumpalo",
"fnv",
"hashbrown 0.14.3",
"im",
"im-rc",
"smallvec",
"wyhash",
]
[[package]]
name = "roc_error_macros"
version = "0.0.1"
[[package]]
name = "roc_highlight"
version = "0.0.1"
dependencies = [
"html-escape",
"roc_parse",
"roc_region",
]
[[package]]
name = "roc_ident"
version = "0.0.1"
[[package]]
name = "roc_module"
version = "0.0.1"
dependencies = [
"bumpalo",
"roc_collections",
"roc_error_macros",
"roc_ident",
"roc_region",
"snafu",
"static_assertions",
]
[[package]]
name = "roc_parse"
version = "0.0.1"
dependencies = [
"bumpalo",
"encode_unicode",
"roc_collections",
"roc_error_macros",
"roc_module",
"roc_region",
]
[[package]]
name = "roc_region"
version = "0.0.1"
dependencies = [
"static_assertions",
]
[[package]]
name = "roc_std"
version = "0.0.1"
dependencies = [
"arrayvec",
"static_assertions",
]
[[package]]
name = "rustc-demangle"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "ryu"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "safemem"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "serde"
version = "1.0.180"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ea67f183f058fe88a4e3ec6e2788e003840893b91bac4559cabedd00863b3ed"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.180"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24e744d7782b686ab3b73267ef05697159cc0e5abbed3f47f9933165e5219036"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]]
name = "serde_json"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sized-chunks"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e"
dependencies = [
"bitmaps",
"typenum",
]
[[package]]
name = "smallvec"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]]
name = "snafu"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6"
dependencies = [
"backtrace",
"doc-comment",
"snafu-derive",
]
[[package]]
name = "snafu-derive"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syntect"
version = "5.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e02b4b303bf8d08bfeb0445cba5068a3d306b6baece1d5582171a9bf49188f91"
dependencies = [
"bincode",
"bitflags",
"flate2",
"fnv",
"once_cell",
"onig",
"plist",
"regex-syntax",
"serde",
"serde_json",
"thiserror",
"walkdir",
"yaml-rust",
]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "thiserror"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.43",
]
[[package]]
name = "time"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b79eabcd964882a646b3584543ccabeae7869e9ac32a46f6f22b7a5bd405308b"
dependencies = [
"deranged",
"itoa",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
[[package]]
name = "time-macros"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd"
dependencies = [
"time-core",
]
[[package]]
name = "typenum"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-ident"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "utf8-width"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "walkdir"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "wyhash"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf6e163c25e3fac820b4b453185ea2dea3b6a3e0a721d4d23d75bd33734c295"
dependencies = [
"rand_core",
]
[[package]]
name = "wyz"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
dependencies = [
"tap",
]
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "zerocopy"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.43",
]

View file

@ -3,8 +3,8 @@ let
inherit (compile-deps) zigPkg llvmPkgs llvmVersion llvmMajorMinorStr glibcPath libGccSPath; inherit (compile-deps) zigPkg llvmPkgs llvmVersion llvmMajorMinorStr glibcPath libGccSPath;
subPackagePath = if subPackage != null then "crates/${subPackage}" else null; subPackagePath = if subPackage != null then "crates/${subPackage}" else null;
mainBin = if subPackage == "lang_srv" then "roc_ls" else "roc"; mainBin = if subPackage == "lang_srv" then "roc_ls" else "roc";
filteredSource = pkgs.callPackage ./fileFilter.nix { };
in in
rustPlatform.buildRustPackage { rustPlatform.buildRustPackage {
pname = "roc" + lib.optionalString (subPackage != null) "_${subPackage}"; pname = "roc" + lib.optionalString (subPackage != null) "_${subPackage}";
@ -12,7 +12,7 @@ rustPlatform.buildRustPackage {
buildAndTestSubdir = subPackagePath; buildAndTestSubdir = subPackagePath;
src = pkgs.nix-gitignore.gitignoreSource [ ] ../.; src = filteredSource;
cargoLock = { cargoLock = {
lockFile = ../Cargo.lock; lockFile = ../Cargo.lock;

80
nix/fileFilter.nix Normal file
View file

@ -0,0 +1,80 @@
{ lib, nix-gitignore }:
let
# See https://nix.dev/tutorials/file-sets for a guide on how the file set api works
fs = lib.fileset;
fileDoesNotHaveExt = fileExts: file: (!lib.lists.any (ext: file.hasExt ext) fileExts);
repoRoot = ../.;
# The file set api does not currently have a way to easily remove folders dynamically.
# The nix build does not run tests, so we try to remove any folders with only tests.
removedTests =
let
dirFilter = pathStr: (
let dirName = baseNameOf pathStr; in !(
# remove any folder whos name is `tests` or starts with `test_`
dirName == "tests"
)
);
removeTestFilter =
path: type:
# only do a "real" check on directory, allow everything else through
(type == "directory" && dirFilter path)
|| type != "directory";
in
lib.sources.cleanSourceWith { src = repoRoot; filter = removeTestFilter; };
fsBase = fs.fromSource removedTests;
# fsBase = fs.fromSource repoRoot;
# only look at files in the crates folder
onlyCratesFolder = fs.intersection ../crates fsBase;
# the above filter only has the subfolder, put some needed files from the root back in
includeCargoRootFiles = fs.unions [
../Cargo.toml
../Cargo.lock
../version.txt
onlyCratesFolder
];
# Remove any "simple" files like markdown/pictures since they probably wont be used in the actual code
removedSimpleFiles =
let
extensionsToRemove = [ "md" "svg" "png" ];
in
fs.intersection
includeCargoRootFiles
(fs.fileFilter (fileDoesNotHaveExt extensionsToRemove) repoRoot);
# the above filter can make the doc crate sad since it has pictures
docsAddedBack = fs.unions [
../crates/docs
removedSimpleFiles
];
# ===============================
# If you are trying to see what is ok to exclude from the "main" builds (cli/lang_server)
# use `cargo tree` https://doc.rust-lang.org/cargo/commands/cargo-tree.html
#
# Ex: `cargo tree -i roc_build` will show all deps of the `roc_build` crate
# if only the package passed with `-i` is shown, nothing depends on it
# ===============================
# remove www folder from checkmate crate since it's not built with nix
removedWWW = fs.difference docsAddedBack ../crates/compiler/checkmate/www;
# potential packages/folders that could be removed
# repl_* -> I don't think nix will build those
filteredSrc = fs.toSource {
root = repoRoot;
# to debug you can switch to
# fileset = fs.traceVal <file set>
fileset = removedWWW;
};
in
filteredSrc

View file

@ -153,6 +153,19 @@ the data model that would break their call sites, even if that change would impr
On a historical note, `Maybe` may have been thought of as a substitute for null references—as opposed to something that emerged organically based on specific motivating use cases after `Result` already existed. That said, in languages that do not have an equivalent of Roc's tag unions, it's much less ergonomic to write something like `Result a [ListWasEmpty]`, so that design would not fit those languages as well as it fits Roc. On a historical note, `Maybe` may have been thought of as a substitute for null references—as opposed to something that emerged organically based on specific motivating use cases after `Result` already existed. That said, in languages that do not have an equivalent of Roc's tag unions, it's much less ergonomic to write something like `Result a [ListWasEmpty]`, so that design would not fit those languages as well as it fits Roc.
## Why doesn't Roc have a builtin "arbitrary-sized" number type like BigNum or BigDecimal?
Like all programming languages, Roc is subject to the limitations of the universe. Almost all numbers in mathematics cannot even be represented in the universe because you'd run out of matter trying to write them down, and therefore Roc must choose what subset of mathematics to support—including which numbers to support.
Roc supports 128-bit integers, 128-bit fixed-point decimal numbers. Here are some approximate ranges for those:
- `I128`: ±170000000000000000000000000000000000000
- `Dec`: ±170000000000000000000.000000000000000000
For heap-allocated numbers to be worth including in Roc's builtins, a sufficient number of real-world use cases would need to exist where the above ranges are too small, but a heap-allocated number would be big enough, _and_ the performance hit from the heap-allocated numbers would be acceptable to those use cases, _and_ a user-created implementation of heap-allocated numbers would not be acceptable, _and_ using 64-bit floating-point numbers (which can be even larger than these, at the cost of precision loss in some operations) would not be acceptable either.
So far, this has not happened.
## Why doesn't Roc have higher-kinded polymorphism or arbitrary-rank types? ## Why doesn't Roc have higher-kinded polymorphism or arbitrary-rank types?
_Since this is a FAQ answer, it assumes familiarity with higher-kinded types and higher-rank types instead of including a primer on them._ _Since this is a FAQ answer, it assumes familiarity with higher-kinded types and higher-rank types instead of including a primer on them._