Merge branch 'trunk' of github.com:rtfeldman/roc into wasm-link-builtins

This commit is contained in:
Brian Carroll 2021-11-09 15:08:43 +00:00
commit d0f1698db2
68 changed files with 7010 additions and 7074 deletions

4
.cargo/config Normal file
View file

@ -0,0 +1,4 @@
[alias]
test-gen-llvm = "test -p test_gen"
test-gen-dev = "test -p test_gen --no-default-features --features gen-dev"
test-gen-wasm = "test -p test_gen --no-default-features --features gen-wasm"

View file

@ -50,3 +50,4 @@ Martin Janiczek <martin@janiczek.cz>
Eric Newbury <enewbury@users.noreply.github.com> Eric Newbury <enewbury@users.noreply.github.com>
Ayaz Hafiz <ayaz.hafiz.1@gmail.com> Ayaz Hafiz <ayaz.hafiz.1@gmail.com>
Johannes Maas <github@j-maas.de> Johannes Maas <github@j-maas.de>
Takeshi Sato <doublequotation@gmail.com>

View file

@ -88,7 +88,9 @@ Using [nix](https://nixos.org/download.html) is a quick way to get an environmen
Anyone having trouble installing the proper version of LLVM themselves might also prefer this method. Anyone having trouble installing the proper version of LLVM themselves might also prefer this method.
First, install nix: If you are running ArchLinux or a derivative like Manjaro, you'll need to run `sudo sysctl -w kernel.unprivileged_userns_clone=1` before installing nix.
Install nix:
`curl -L https://nixos.org/nix/install | sh` `curl -L https://nixos.org/nix/install | sh`

42
Cargo.lock generated
View file

@ -4068,29 +4068,6 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "test_dev"
version = "0.1.0"
dependencies = [
"bumpalo",
"indoc",
"libloading 0.7.1",
"roc_build",
"roc_builtins",
"roc_can",
"roc_collections",
"roc_constrain",
"roc_gen_dev",
"roc_load",
"roc_mono",
"roc_parse",
"roc_problem",
"roc_reporting",
"roc_std",
"target-lexicon",
"tempfile",
]
[[package]] [[package]]
name = "test_gen" name = "test_gen"
version = "0.1.0" version = "0.1.0"
@ -4108,7 +4085,9 @@ dependencies = [
"roc_can", "roc_can",
"roc_collections", "roc_collections",
"roc_constrain", "roc_constrain",
"roc_gen_dev",
"roc_gen_llvm", "roc_gen_llvm",
"roc_gen_wasm",
"roc_load", "roc_load",
"roc_module", "roc_module",
"roc_mono", "roc_mono",
@ -4122,7 +4101,6 @@ dependencies = [
"roc_unify", "roc_unify",
"target-lexicon", "target-lexicon",
"tempfile", "tempfile",
"test_wasm",
"wasmer", "wasmer",
"wasmer-wasi", "wasmer-wasi",
] ]
@ -4152,22 +4130,6 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "test_wasm"
version = "0.1.0"
dependencies = [
"bumpalo",
"indoc",
"roc_builtins",
"roc_can",
"roc_collections",
"roc_gen_wasm",
"roc_load",
"roc_std",
"wasmer",
"wasmer-wasi",
]
[[package]] [[package]]
name = "textwrap" name = "textwrap"
version = "0.11.0" version = "0.11.0"

View file

@ -15,7 +15,6 @@ members = [
"compiler/reporting", "compiler/reporting",
"compiler/fmt", "compiler/fmt",
"compiler/mono", "compiler/mono",
"compiler/test_mono_macros",
"compiler/test_mono", "compiler/test_mono",
"compiler/load", "compiler/load",
"compiler/gen_llvm", "compiler/gen_llvm",
@ -23,9 +22,7 @@ members = [
"compiler/gen_wasm", "compiler/gen_wasm",
"compiler/build", "compiler/build",
"compiler/arena_pool", "compiler/arena_pool",
"compiler/test_dev",
"compiler/test_gen", "compiler/test_gen",
"compiler/test_wasm",
"vendor/ena", "vendor/ena",
"vendor/inkwell", "vendor/inkwell",
"vendor/pathfinding", "vendor/pathfinding",
@ -33,14 +30,19 @@ members = [
"editor", "editor",
"ast", "ast",
"cli", "cli",
"cli/cli_utils",
"code_markup", "code_markup",
"roc_std", "roc_std",
"utils", "utils",
"docs", "docs",
"linker", "linker",
] ]
exclude = [ "ci/bench-runner" ] exclude = [
"ci/bench-runner",
# Ignore building these normally. They are only imported by tests.
# The tests will still correctly build them.
"cli_utils",
"compiler/test_mono_macros",
]
# Needed to be able to run `cargo run -p roc_cli --no-default-features` - # Needed to be able to run `cargo run -p roc_cli --no-default-features` -
# see www/build.sh for more. # see www/build.sh for more.
# #

View file

@ -47,7 +47,7 @@ install-zig-llvm-valgrind-clippy-rustfmt:
copy-dirs: copy-dirs:
FROM +install-zig-llvm-valgrind-clippy-rustfmt FROM +install-zig-llvm-valgrind-clippy-rustfmt
COPY --dir cli compiler docs editor ast code_markup utils roc_std vendor examples linker Cargo.toml Cargo.lock version.txt ./ COPY --dir cli cli_utils compiler docs editor ast code_markup utils roc_std vendor examples linker Cargo.toml Cargo.lock version.txt ./
test-zig: test-zig:
FROM +install-zig-llvm-valgrind-clippy-rustfmt FROM +install-zig-llvm-valgrind-clippy-rustfmt
@ -67,7 +67,7 @@ check-rustfmt:
check-typos: check-typos:
RUN cargo install typos-cli --version 1.0.11 # version set to prevent confusion if the version is updated automatically RUN cargo install typos-cli --version 1.0.11 # version set to prevent confusion if the version is updated automatically
COPY --dir .github ci cli compiler docs editor examples ast code_markup utils linker nightly_benches packages roc_std www *.md LEGAL_DETAILS shell.nix version.txt ./ COPY --dir .github ci cli cli_utils compiler docs editor examples ast code_markup utils linker nightly_benches packages roc_std www *.md LEGAL_DETAILS shell.nix version.txt ./
RUN typos RUN typos
test-rust: test-rust:
@ -79,10 +79,13 @@ test-rust:
# not pre-compiling the host can cause race conditions # not pre-compiling the host can cause race conditions
RUN echo "4" | cargo run --release examples/benchmarks/NQueens.roc RUN echo "4" | cargo run --release examples/benchmarks/NQueens.roc
RUN --mount=type=cache,target=$SCCACHE_DIR \ RUN --mount=type=cache,target=$SCCACHE_DIR \
cargo test --release --features with_sound --workspace --exclude test_wasm && sccache --show-stats cargo test --release --features with_sound --workspace && sccache --show-stats
# test_wasm has some multithreading problems to do with the wasmer runtime. Run it single-threaded as a separate job # test the dev and wasm backend: they require an explicit feature flag.
RUN --mount=type=cache,target=$SCCACHE_DIR \ RUN --mount=type=cache,target=$SCCACHE_DIR \
cargo test --release --package test_wasm -- --test-threads=1 && sccache --show-stats cargo test --release --package test_gen --no-default-features --features gen-dev && sccache --show-stats
# gen-wasm has some multithreading problems to do with the wasmer runtime. Run it single-threaded as a separate job
RUN --mount=type=cache,target=$SCCACHE_DIR \
cargo test --release --package test_gen --no-default-features --features gen-wasm -- --test-threads=1 && sccache --show-stats
# run i386 (32-bit linux) cli tests # run i386 (32-bit linux) cli tests
RUN echo "4" | cargo run --release --features="target-x86" -- --backend=x86_32 examples/benchmarks/NQueens.roc RUN echo "4" | cargo run --release --features="target-x86" -- --backend=x86_32 examples/benchmarks/NQueens.roc
RUN --mount=type=cache,target=$SCCACHE_DIR \ RUN --mount=type=cache,target=$SCCACHE_DIR \

236
cli/Cargo.lock generated
View file

@ -1,236 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "ascii"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "autocfg"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "combine"
version = "3.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ascii 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "either"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fraction"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "im-rc"
version = "13.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"sized-chunks 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazy_static"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "log"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
"num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-bigint"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-complex"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-integer"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-iter"
version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-rational"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "roc"
version = "0.1.0"
dependencies = [
"combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fraction 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"im-rc 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "roc-cli"
version = "0.1.0"
dependencies = [
"roc 0.1.0",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "sized-chunks"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "typenum"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unreachable"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum ascii 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5fc969a8ce2c9c0c4b0429bb8431544f6658283c8326ba5ff8c762b75369335"
"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf"
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
"checksum combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680"
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
"checksum fraction 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1055159ac82fb210c813303f716b6c8db57ace9d5ec2dbbc2e1d7a864c1dd74e"
"checksum im-rc 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0197597d095c0d11107975d3175173f810ee572c2501ff4de64f4f3f119806"
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db"
"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718"
"checksum num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fcb0cf31fb3ff77e6d2a6ebd6800df7fdcd106f2ad89113c9130bcd07f93dffc"
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
"checksum num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "76bd5272412d173d6bf9afdf98db8612bbabc9a7a830b7bfc9c188911716132e"
"checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum sized-chunks 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2a2eb3fe454976eefb479f78f9b394d34d661b647c6326a3a6e66f68bb12c26"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"

View file

@ -89,7 +89,7 @@ indoc = "1.0.3"
serial_test = "0.5.1" serial_test = "0.5.1"
tempfile = "3.2.0" tempfile = "3.2.0"
criterion = { git = "https://github.com/Anton-4/criterion.rs"} criterion = { git = "https://github.com/Anton-4/criterion.rs"}
cli_utils = { path = "cli_utils" } cli_utils = { path = "../cli_utils" }
[[bench]] [[bench]]
name = "time_bench" name = "time_bench"

3898
cli_utils/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -10,10 +10,10 @@ description = "Shared code for cli tests and benchmarks"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
roc_cli = { path = "../../cli" } roc_cli = { path = "../cli" }
roc_collections = { path = "../../compiler/collections" } roc_collections = { path = "../compiler/collections" }
roc_load = { path = "../../compiler/load" } roc_load = { path = "../compiler/load" }
roc_module = { path = "../../compiler/module" } roc_module = { path = "../compiler/module" }
bumpalo = { version = "3.8.0", features = ["collections"] } bumpalo = { version = "3.8.0", features = ["collections"] }
criterion = { git = "https://github.com/Anton-4/criterion.rs"} criterion = { git = "https://github.com/Anton-4/criterion.rs"}
serde = { version = "1.0.130", features = ["derive"] } serde = { version = "1.0.130", features = ["derive"] }

View file

@ -862,6 +862,32 @@ pub fn listSwap(
return newList; return newList;
} }
pub fn listTakeFirst(
list: RocList,
alignment: u32,
element_width: usize,
take_count: usize,
) callconv(.C) RocList {
if (list.bytes) |source_ptr| {
if (take_count == 0) {
return RocList.empty();
}
const in_len = list.len();
const out_len = std.math.min(take_count, in_len);
const output = RocList.allocate(alignment, out_len, element_width);
const target_ptr = output.bytes orelse unreachable;
@memcpy(target_ptr, source_ptr, out_len * element_width);
utils.decref(list.bytes, in_len * element_width, alignment);
return output;
} else {
return RocList.empty();
}
}
pub fn listDrop( pub fn listDrop(
list: RocList, list: RocList,
alignment: u32, alignment: u32,
@ -1307,3 +1333,39 @@ inline fn listSetImmutable(
//return list; //return list;
return new_bytes; return new_bytes;
} }
pub fn listFindUnsafe(
list: RocList,
caller: Caller1,
data: Opaque,
inc_n_data: IncN,
data_is_owned: bool,
alignment: u32,
element_width: usize,
inc: Inc,
dec: Dec,
) callconv(.C) extern struct { value: Opaque, found: bool } {
if (list.bytes) |source_ptr| {
const size = list.len();
if (data_is_owned) {
inc_n_data(data, size);
}
var i: usize = 0;
while (i < size) : (i += 1) {
var theOne = false;
const element = source_ptr + (i * element_width);
inc(element);
caller(data, element, @ptrCast(?[*]u8, &theOne));
if (theOne) {
return .{ .value = element, .found = true };
} else {
dec(element);
}
}
return .{ .value = null, .found = false };
} else {
return .{ .value = null, .found = false };
}
}

View file

@ -45,12 +45,14 @@ comptime {
exportListFn(list.listReverse, "reverse"); exportListFn(list.listReverse, "reverse");
exportListFn(list.listSortWith, "sort_with"); exportListFn(list.listSortWith, "sort_with");
exportListFn(list.listConcat, "concat"); exportListFn(list.listConcat, "concat");
exportListFn(list.listTakeFirst, "take_first");
exportListFn(list.listDrop, "drop"); exportListFn(list.listDrop, "drop");
exportListFn(list.listDropAt, "drop_at"); exportListFn(list.listDropAt, "drop_at");
exportListFn(list.listSet, "set"); exportListFn(list.listSet, "set");
exportListFn(list.listSetInPlace, "set_in_place"); exportListFn(list.listSetInPlace, "set_in_place");
exportListFn(list.listSwap, "swap"); exportListFn(list.listSwap, "swap");
exportListFn(list.listAny, "any"); exportListFn(list.listAny, "any");
exportListFn(list.listFindUnsafe, "find_unsafe");
} }
// Dict Module // Dict Module

View file

@ -690,3 +690,7 @@ all : List elem, (elem -> Bool) -> Bool
## Run the given predicate on each element of the list, returning `True` if ## Run the given predicate on each element of the list, returning `True` if
## any of the elements satisfy it. ## any of the elements satisfy it.
any : List elem, (elem -> Bool) -> Bool any : List elem, (elem -> Bool) -> Bool
## Returns the first element of the list satisfying a predicate function.
## If no satisfying element is found, an `Err NotFound` is returned.
find : List elem, (elem -> Bool) -> Result elem [ NotFound ]*

View file

@ -177,6 +177,7 @@ pub const LIST_CONTAINS: &str = "roc_builtins.list.contains";
pub const LIST_REPEAT: &str = "roc_builtins.list.repeat"; pub const LIST_REPEAT: &str = "roc_builtins.list.repeat";
pub const LIST_APPEND: &str = "roc_builtins.list.append"; pub const LIST_APPEND: &str = "roc_builtins.list.append";
pub const LIST_PREPEND: &str = "roc_builtins.list.prepend"; pub const LIST_PREPEND: &str = "roc_builtins.list.prepend";
pub const LIST_TAKE_FIRST: &str = "roc_builtins.list.take_first";
pub const LIST_DROP: &str = "roc_builtins.list.drop"; pub const LIST_DROP: &str = "roc_builtins.list.drop";
pub const LIST_DROP_AT: &str = "roc_builtins.list.drop_at"; pub const LIST_DROP_AT: &str = "roc_builtins.list.drop_at";
pub const LIST_SWAP: &str = "roc_builtins.list.swap"; pub const LIST_SWAP: &str = "roc_builtins.list.swap";
@ -189,6 +190,7 @@ pub const LIST_CONCAT: &str = "roc_builtins.list.concat";
pub const LIST_SET: &str = "roc_builtins.list.set"; pub const LIST_SET: &str = "roc_builtins.list.set";
pub const LIST_SET_IN_PLACE: &str = "roc_builtins.list.set_in_place"; pub const LIST_SET_IN_PLACE: &str = "roc_builtins.list.set_in_place";
pub const LIST_ANY: &str = "roc_builtins.list.any"; pub const LIST_ANY: &str = "roc_builtins.list.any";
pub const LIST_FIND_UNSAFE: &str = "roc_builtins.list.find_unsafe";
pub const DEC_FROM_F64: &str = "roc_builtins.dec.from_f64"; pub const DEC_FROM_F64: &str = "roc_builtins.dec.from_f64";
pub const DEC_EQ: &str = "roc_builtins.dec.eq"; pub const DEC_EQ: &str = "roc_builtins.dec.eq";

View file

@ -5,7 +5,7 @@ use roc_region::all::Region;
use roc_types::builtin_aliases::{ use roc_types::builtin_aliases::{
bool_type, dict_type, float_type, i128_type, int_type, list_type, nat_type, num_type, bool_type, dict_type, float_type, i128_type, int_type, list_type, nat_type, num_type,
ordering_type, result_type, set_type, str_type, str_utf8_byte_problem_type, u16_type, u32_type, ordering_type, result_type, set_type, str_type, str_utf8_byte_problem_type, u16_type, u32_type,
u64_type, u8_type, u8_type,
}; };
use roc_types::solved_types::SolvedType; use roc_types::solved_types::SolvedType;
use roc_types::subs::VarId; use roc_types::subs::VarId;
@ -971,6 +971,13 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
Box::new(list_type(flex(TVAR1))), Box::new(list_type(flex(TVAR1))),
); );
// takeFirst : List elem, Nat -> List elem
add_top_level_function_type!(
Symbol::LIST_TAKE_FIRST,
vec![list_type(flex(TVAR1)), nat_type()],
Box::new(list_type(flex(TVAR1))),
);
// drop : List elem, Nat -> List elem // drop : List elem, Nat -> List elem
add_top_level_function_type!( add_top_level_function_type!(
Symbol::LIST_DROP, Symbol::LIST_DROP,
@ -1079,14 +1086,24 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
Box::new(list_type(flex(TVAR1))), Box::new(list_type(flex(TVAR1))),
); );
// Dict module // find : List elem, (elem -> Bool) -> Result elem [ NotFound ]*
{
let not_found = SolvedType::TagUnion(
vec![(TagName::Global("NotFound".into()), vec![])],
Box::new(SolvedType::Wildcard),
);
let (elem, cvar) = (TVAR1, TVAR2);
add_top_level_function_type!(
Symbol::LIST_FIND,
vec![
list_type(flex(elem)),
closure(vec![flex(elem)], cvar, Box::new(bool_type())),
],
Box::new(result_type(flex(elem), not_found)),
)
}
// Dict.hashTestOnly : U64, v -> U64 // Dict module
add_top_level_function_type!(
Symbol::DICT_TEST_HASH,
vec![u64_type(), flex(TVAR2)],
Box::new(u64_type())
);
// len : Dict * * -> Nat // len : Dict * * -> Nat
add_top_level_function_type!( add_top_level_function_type!(

View file

@ -91,6 +91,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
LIST_MAP2 => list_map2, LIST_MAP2 => list_map2,
LIST_MAP3 => list_map3, LIST_MAP3 => list_map3,
LIST_MAP4 => list_map4, LIST_MAP4 => list_map4,
LIST_TAKE_FIRST => list_take_first,
LIST_DROP => list_drop, LIST_DROP => list_drop,
LIST_DROP_AT => list_drop_at, LIST_DROP_AT => list_drop_at,
LIST_DROP_FIRST => list_drop_first, LIST_DROP_FIRST => list_drop_first,
@ -106,7 +107,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
LIST_WALK_UNTIL => list_walk_until, LIST_WALK_UNTIL => list_walk_until,
LIST_SORT_WITH => list_sort_with, LIST_SORT_WITH => list_sort_with,
LIST_ANY => list_any, LIST_ANY => list_any,
DICT_TEST_HASH => dict_hash_test_only, LIST_FIND => list_find,
DICT_LEN => dict_len, DICT_LEN => dict_len,
DICT_EMPTY => dict_empty, DICT_EMPTY => dict_empty,
DICT_SINGLE => dict_single, DICT_SINGLE => dict_single,
@ -2006,6 +2007,29 @@ fn list_swap(symbol: Symbol, var_store: &mut VarStore) -> Def {
) )
} }
/// List.takeFirst : List elem, Nat -> List elem
fn list_take_first(symbol: Symbol, var_store: &mut VarStore) -> Def {
let list_var = var_store.fresh();
let len_var = var_store.fresh();
let body = RunLowLevel {
op: LowLevel::ListTakeFirst,
args: vec![
(list_var, Var(Symbol::ARG_1)),
(len_var, Var(Symbol::ARG_2)),
],
ret_var: list_var,
};
defn(
symbol,
vec![(list_var, Symbol::ARG_1), (len_var, Symbol::ARG_2)],
var_store,
body,
list_var,
)
}
/// List.drop : List elem, Nat -> List elem /// List.drop : List elem, Nat -> List elem
fn list_drop(symbol: Symbol, var_store: &mut VarStore) -> Def { fn list_drop(symbol: Symbol, var_store: &mut VarStore) -> Def {
let list_var = var_store.fresh(); let list_var = var_store.fresh();
@ -2701,9 +2725,85 @@ fn list_any(symbol: Symbol, var_store: &mut VarStore) -> Def {
lowlevel_2(symbol, LowLevel::ListAny, var_store) lowlevel_2(symbol, LowLevel::ListAny, var_store)
} }
/// Dict.hashTestOnly : k, v -> Nat /// List.find : List elem, (elem -> Bool) -> Result elem [ NotFound ]*
fn dict_hash_test_only(symbol: Symbol, var_store: &mut VarStore) -> Def { fn list_find(symbol: Symbol, var_store: &mut VarStore) -> Def {
lowlevel_2(symbol, LowLevel::Hash, var_store) let list = Symbol::ARG_1;
let find_predicate = Symbol::ARG_2;
let find_result = Symbol::LIST_FIND_RESULT;
let t_list = var_store.fresh();
let t_pred_fn = var_store.fresh();
let t_bool = var_store.fresh();
let t_found = var_store.fresh();
let t_value = var_store.fresh();
let t_ret = var_store.fresh();
let t_find_result = var_store.fresh();
let t_ext_var1 = var_store.fresh();
let t_ext_var2 = var_store.fresh();
// ListFindUnsafe returns { value: elem, found: Bool }.
// When `found` is true, the value was found. Otherwise `List.find` should return `Err ...`
let find_result_def = Def {
annotation: None,
expr_var: t_find_result,
loc_expr: no_region(RunLowLevel {
op: LowLevel::ListFindUnsafe,
args: vec![(t_list, Var(list)), (t_pred_fn, Var(find_predicate))],
ret_var: t_find_result,
}),
loc_pattern: no_region(Pattern::Identifier(find_result)),
pattern_vars: Default::default(),
};
let get_value = Access {
record_var: t_find_result,
ext_var: t_ext_var1,
field_var: t_value,
loc_expr: Box::new(no_region(Var(find_result))),
field: "value".into(),
};
let get_found = Access {
record_var: t_find_result,
ext_var: t_ext_var2,
field_var: t_found,
loc_expr: Box::new(no_region(Var(find_result))),
field: "found".into(),
};
let make_ok = tag("Ok", vec![get_value], var_store);
let make_err = tag(
"Err",
vec![tag("NotFound", Vec::new(), var_store)],
var_store,
);
let inspect = If {
cond_var: t_bool,
branch_var: t_ret,
branches: vec![(
// if-condition
no_region(get_found),
no_region(make_ok),
)],
final_else: Box::new(no_region(make_err)),
};
let body = LetNonRec(
Box::new(find_result_def),
Box::new(no_region(inspect)),
t_ret,
);
defn(
symbol,
vec![(t_list, Symbol::ARG_1), (t_pred_fn, Symbol::ARG_2)],
var_store,
body,
t_ret,
)
} }
/// Dict.len : Dict * * -> Nat /// Dict.len : Dict * * -> Nat

View file

@ -67,10 +67,9 @@ This is the general procedure I follow with some helpful links:
1. Find a feature that is just n+1. 1. Find a feature that is just n+1.
For example, since we already have integers, adding a builtin that functions on them should be n+1. For example, since we already have integers, adding a builtin that functions on them should be n+1.
On the other hand, since we don't yet have booleans/conditionals, adding if statements may not yet be n+1. On the other hand, since we don't yet have booleans/conditionals, adding if statements may not yet be n+1.
A good place to look for missing features is in the test files for both the [regular](https://github.com/rtfeldman/roc/tree/trunk/compiler/gen/tests) and [dev](https://github.com/rtfeldman/roc/tree/trunk/compiler/gen_dev/tests) backend. A good place to look for missing features is in the test files for generation in [test_gen](https://github.com/rtfeldman/roc/tree/trunk/compiler/test_gen). Any test that is not enabled for the `gen-dev` feature still needs to be added to the dev backend. Eventually all features should be enabled for the dev backend.
Eventually these test files should be practically identical.
1. Pick/write the simplest test case you can find for the new feature. 1. Pick/write the simplest test case you can find for the new feature.
Just uncomment/copy over the test if it already exists. Just add `feature = "gen-dev"` to the `cfg` line for the test case.
1. Uncomment the code to print out procedures [from here](https://github.com/rtfeldman/roc/blob/trunk/compiler/gen_dev/tests/helpers/eval.rs) and run the test. 1. Uncomment the code to print out procedures [from here](https://github.com/rtfeldman/roc/blob/trunk/compiler/gen_dev/tests/helpers/eval.rs) and run the test.
It should fail and print out the mono ir for this test case. It should fail and print out the mono ir for this test case.
Seeing the actual mono ir tends to be very helpful for complex additions. Seeing the actual mono ir tends to be very helpful for complex additions.

View file

@ -9,10 +9,10 @@ use crate::llvm::build_dict::{
use crate::llvm::build_hash::generic_hash; use crate::llvm::build_hash::generic_hash;
use crate::llvm::build_list::{ use crate::llvm::build_list::{
self, allocate_list, empty_list, empty_polymorphic_list, list_any, list_append, list_concat, self, allocate_list, empty_list, empty_polymorphic_list, list_any, list_append, list_concat,
list_contains, list_drop, list_drop_at, list_get_unsafe, list_join, list_keep_errs, list_contains, list_drop, list_drop_at, list_find_trivial_not_found, list_find_unsafe,
list_keep_if, list_keep_oks, list_len, list_map, list_map2, list_map3, list_map4, list_get_unsafe, list_join, list_keep_errs, list_keep_if, list_keep_oks, list_len, list_map,
list_map_with_index, list_prepend, list_range, list_repeat, list_reverse, list_set, list_map2, list_map3, list_map4, list_map_with_index, list_prepend, list_range, list_repeat,
list_single, list_sort_with, list_swap, list_reverse, list_set, list_single, list_sort_with, list_swap, list_take_first,
}; };
use crate::llvm::build_str::{ use crate::llvm::build_str::{
empty_str, str_concat, str_count_graphemes, str_ends_with, str_from_float, str_from_int, empty_str, str_concat, str_count_graphemes, str_ends_with, str_from_float, str_from_int,
@ -4887,6 +4887,37 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
_ => unreachable!("invalid list layout"), _ => unreachable!("invalid list layout"),
} }
} }
ListFindUnsafe { xs } => {
let (list, list_layout) = load_symbol_and_layout(scope, &xs);
let (function, closure, closure_layout) = function_details!();
match list_layout {
Layout::Builtin(Builtin::EmptyList) => {
// Returns { found: False, elem: \empty }, where the `elem` field is zero-sized.
// NB: currently we never hit this case, since the only caller of this
// lowlevel, namely List.find, will fail during monomorphization when there is no
// concrete list element type. This is because List.find returns a
// `Result elem [ NotFound ]*`, and we can't figure out the size of that if
// `elem` is not concrete.
list_find_trivial_not_found(env)
}
Layout::Builtin(Builtin::List(element_layout)) => {
let argument_layouts = &[**element_layout];
let roc_function_call = roc_function_call(
env,
layout_ids,
function,
closure,
closure_layout,
function_owns_closure_data,
argument_layouts,
);
list_find_unsafe(env, layout_ids, roc_function_call, list, element_layout)
}
_ => unreachable!("invalid list layout"),
}
}
DictWalk { xs, state } => { DictWalk { xs, state } => {
let (dict, dict_layout) = load_symbol_and_layout(scope, &xs); let (dict, dict_layout) = load_symbol_and_layout(scope, &xs);
let (default, default_layout) = load_symbol_and_layout(scope, &state); let (default, default_layout) = load_symbol_and_layout(scope, &state);
@ -5152,6 +5183,26 @@ fn run_low_level<'a, 'ctx, 'env>(
_ => unreachable!("Invalid layout {:?} in List.swap", list_layout), _ => unreachable!("Invalid layout {:?} in List.swap", list_layout),
} }
} }
ListTakeFirst => {
// List.takeFirst : List elem, Nat -> List elem
debug_assert_eq!(args.len(), 2);
let (list, list_layout) = load_symbol_and_layout(scope, &args[0]);
let original_wrapper = list.into_struct_value();
let count = load_symbol(scope, &args[1]);
match list_layout {
Layout::Builtin(Builtin::EmptyList) => empty_list(env),
Layout::Builtin(Builtin::List(element_layout)) => list_take_first(
env,
original_wrapper,
count.into_int_value(),
element_layout,
),
_ => unreachable!("Invalid layout {:?} in List.takeFirst", list_layout),
}
}
ListDrop => { ListDrop => {
// List.drop : List elem, Nat -> List elem // List.drop : List elem, Nat -> List elem
debug_assert_eq!(args.len(), 2); debug_assert_eq!(args.len(), 2);
@ -5737,7 +5788,9 @@ fn run_low_level<'a, 'ctx, 'env>(
ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListKeepIf | ListWalk ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListKeepIf | ListWalk
| ListWalkUntil | ListWalkBackwards | ListKeepOks | ListKeepErrs | ListSortWith | ListWalkUntil | ListWalkBackwards | ListKeepOks | ListKeepErrs | ListSortWith
| ListAny | DictWalk => unreachable!("these are higher order, and are handled elsewhere"), | ListAny | ListFindUnsafe | DictWalk => {
unreachable!("these are higher order, and are handled elsewhere")
}
} }
} }

View file

@ -297,6 +297,25 @@ pub fn list_swap<'a, 'ctx, 'env>(
) )
} }
/// List.takeFirst : List elem, Nat -> List elem
pub fn list_take_first<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
original_wrapper: StructValue<'ctx>,
count: IntValue<'ctx>,
element_layout: &Layout<'a>,
) -> BasicValueEnum<'ctx> {
call_bitcode_fn_returns_list(
env,
&[
pass_list_cc(env, original_wrapper.into()),
env.alignment_intvalue(element_layout),
layout_width(env, element_layout),
count.into(),
],
bitcode::LIST_TAKE_FIRST,
)
}
/// List.drop : List elem, Nat -> List elem /// List.drop : List elem, Nat -> List elem
pub fn list_drop<'a, 'ctx, 'env>( pub fn list_drop<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,
@ -917,6 +936,123 @@ pub fn list_any<'a, 'ctx, 'env>(
) )
} }
/// List.findUnsafe : List elem, (elem -> Bool) -> { value: elem, found: bool }
pub fn list_find_unsafe<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
layout_ids: &mut LayoutIds<'a>,
roc_function_call: RocFunctionCall<'ctx>,
list: BasicValueEnum<'ctx>,
element_layout: &Layout<'a>,
) -> BasicValueEnum<'ctx> {
let inc_element_fn = build_inc_wrapper(env, layout_ids, element_layout);
let dec_element_fn = build_dec_wrapper(env, layout_ids, element_layout);
// { value: *const u8, found: bool }
let result = call_bitcode_fn(
env,
&[
pass_list_cc(env, list),
roc_function_call.caller.into(),
pass_as_opaque(env, roc_function_call.data),
roc_function_call.inc_n_data.into(),
roc_function_call.data_is_owned.into(),
env.alignment_intvalue(element_layout),
layout_width(env, element_layout),
inc_element_fn.as_global_value().as_pointer_value().into(),
dec_element_fn.as_global_value().as_pointer_value().into(),
],
bitcode::LIST_FIND_UNSAFE,
)
.into_struct_value();
// We promised the caller we'd give them back a struct containing the element
// loaded on the stack, so we do that now. The element can't be loaded directly
// in the Zig definition called above, because we don't know the size of the
// element until user compile time, which is later than the compile time of bitcode defs.
let value_u8_ptr = env
.builder
.build_extract_value(result, 0, "get_value_ptr")
.unwrap()
.into_pointer_value();
let found = env
.builder
.build_extract_value(result, 1, "get_found")
.unwrap()
.into_int_value();
let start_block = env.builder.get_insert_block().unwrap();
let parent = start_block.get_parent().unwrap();
let if_not_null = env.context.append_basic_block(parent, "if_not_null");
let done_block = env.context.append_basic_block(parent, "done");
let value_bt = basic_type_from_layout(env, element_layout);
let default = value_bt.const_zero();
env.builder
.build_conditional_branch(found, if_not_null, done_block);
env.builder.position_at_end(if_not_null);
let value_ptr = env
.builder
.build_bitcast(
value_u8_ptr,
value_bt.ptr_type(AddressSpace::Generic),
"from_opaque",
)
.into_pointer_value();
let loaded = env.builder.build_load(value_ptr, "load_value");
env.builder.build_unconditional_branch(done_block);
env.builder.position_at_end(done_block);
let result_phi = env.builder.build_phi(value_bt, "result");
result_phi.add_incoming(&[(&default, start_block), (&loaded, if_not_null)]);
let value = result_phi.as_basic_value();
let result = env
.context
.struct_type(&[value_bt, env.context.bool_type().into()], false)
.const_zero();
let result = env
.builder
.build_insert_value(result, value, 0, "insert_value")
.unwrap();
env.builder
.build_insert_value(result, found, 1, "insert_found")
.unwrap()
.into_struct_value()
.into()
}
/// Returns { value: \empty, found: False }, representing that no element was found in a call
/// to List.find when the layout of the element is also unknown.
pub fn list_find_trivial_not_found<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
) -> BasicValueEnum<'ctx> {
let empty_type = env.context.custom_width_int_type(0);
let result = env
.context
.struct_type(&[empty_type.into(), env.context.bool_type().into()], false)
.const_zero();
env.builder
.build_insert_value(
result,
env.context.bool_type().const_zero(),
1,
"insert_found",
)
.unwrap()
.into_struct_value()
.into()
}
pub fn decrementing_elem_loop<'ctx, LoopFn>( pub fn decrementing_elem_loop<'ctx, LoopFn>(
builder: &Builder<'ctx>, builder: &Builder<'ctx>,
ctx: &'ctx Context, ctx: &'ctx Context,

View file

@ -42,10 +42,12 @@ pub enum LowLevel {
ListKeepOks, ListKeepOks,
ListKeepErrs, ListKeepErrs,
ListSortWith, ListSortWith,
ListTakeFirst,
ListDrop, ListDrop,
ListDropAt, ListDropAt,
ListSwap, ListSwap,
ListAny, ListAny,
ListFindUnsafe,
DictSize, DictSize,
DictEmpty, DictEmpty,
DictInsert, DictInsert,
@ -131,6 +133,7 @@ macro_rules! first_order {
| ListLen | ListLen
| ListGetUnsafe | ListGetUnsafe
| ListSet | ListSet
| ListTakeFirst
| ListDrop | ListDrop
| ListDropAt | ListDropAt
| ListSingle | ListSingle
@ -223,6 +226,7 @@ macro_rules! higher_order {
| ListKeepErrs | ListKeepErrs
| ListSortWith | ListSortWith
| ListAny | ListAny
| ListFindUnsafe
| DictWalk | DictWalk
}; };
} }
@ -257,6 +261,7 @@ impl LowLevel {
ListKeepErrs => 1, ListKeepErrs => 1,
ListSortWith => 1, ListSortWith => 1,
ListAny => 1, ListAny => 1,
ListFindUnsafe => 1,
DictWalk => 2, DictWalk => 2,
} }
} }

View file

@ -1065,6 +1065,9 @@ define_builtins! {
42 LIST_JOIN_MAP: "joinMap" 42 LIST_JOIN_MAP: "joinMap"
43 LIST_JOIN_MAP_CONCAT: "#joinMapConcat" 43 LIST_JOIN_MAP_CONCAT: "#joinMapConcat"
44 LIST_ANY: "any" 44 LIST_ANY: "any"
45 LIST_TAKE_FIRST: "takeFirst"
46 LIST_FIND: "find"
47 LIST_FIND_RESULT: "#find_result" // symbol used in the definition of List.find
} }
5 RESULT: "Result" => { 5 RESULT: "Result" => {
0 RESULT_RESULT: "Result" imported // the Result.Result type alias 0 RESULT_RESULT: "Result" imported // the Result.Result type alias
@ -1084,18 +1087,14 @@ define_builtins! {
7 DICT_INSERT: "insert" 7 DICT_INSERT: "insert"
8 DICT_LEN: "len" 8 DICT_LEN: "len"
// This should not be exposed to users, its for testing the 9 DICT_REMOVE: "remove"
// hash function ONLY 10 DICT_CONTAINS: "contains"
9 DICT_TEST_HASH: "hashTestOnly" 11 DICT_KEYS: "keys"
12 DICT_VALUES: "values"
10 DICT_REMOVE: "remove" 13 DICT_UNION: "union"
11 DICT_CONTAINS: "contains" 14 DICT_INTERSECTION: "intersection"
12 DICT_KEYS: "keys" 15 DICT_DIFFERENCE: "difference"
13 DICT_VALUES: "values"
14 DICT_UNION: "union"
15 DICT_INTERSECTION: "intersection"
16 DICT_DIFFERENCE: "difference"
} }
7 SET: "Set" => { 7 SET: "Set" => {
0 SET_SET: "Set" imported // the Set.Set type alias 0 SET_SET: "Set" imported // the Set.Set type alias

View file

@ -1093,6 +1093,41 @@ fn call_spec(
add_loop(builder, block, state_type, init_state, loop_body) add_loop(builder, block, state_type, init_state, loop_body)
} }
ListFindUnsafe { xs } => {
let list = env.symbols[xs];
// ListFindUnsafe returns { value: v, found: Bool=Int1 }
let output_layouts = vec![arg_layouts[0], Layout::Builtin(Builtin::Int1)];
let output_layout = Layout::Struct(&output_layouts);
let output_type = layout_spec(builder, &output_layout)?;
let loop_body = |builder: &mut FuncDefBuilder, block, output| {
let bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?;
let element = builder.add_bag_get(block, bag)?;
let _is_found = call_function!(builder, block, [element]);
// We may or may not use the element we got from the list in the output struct,
// depending on whether we found the element to satisfy the "find" predicate.
// If we did find the element, our output "changes" to be a record including that element.
let found_branch = builder.add_block();
let new_output =
builder.add_unknown_with(block, &[element], output_type)?;
let not_found_branch = builder.add_block();
builder.add_choice(
block,
&[
BlockExpr(found_branch, new_output),
BlockExpr(not_found_branch, output),
],
)
};
// Assume the output is initially { found: False, value: \empty }
let output_state = builder.add_unknown_with(block, &[], output_type)?;
add_loop(builder, block, output_type, output_state, loop_body)
}
} }
} }
} }

View file

@ -618,7 +618,8 @@ impl<'a> BorrowInfState<'a> {
| ListKeepIf { xs } | ListKeepIf { xs }
| ListKeepOks { xs } | ListKeepOks { xs }
| ListKeepErrs { xs } | ListKeepErrs { xs }
| ListAny { xs } => { | ListAny { xs }
| ListFindUnsafe { xs } => {
// own the list if the function wants to own the element // own the list if the function wants to own the element
if !function_ps[0].borrow { if !function_ps[0].borrow {
self.own_var(*xs); self.own_var(*xs);
@ -959,10 +960,12 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
arena.alloc_slice_copy(&[owned, owned, function, closure_data]) arena.alloc_slice_copy(&[owned, owned, function, closure_data])
} }
ListSortWith => arena.alloc_slice_copy(&[owned, function, closure_data]), ListSortWith => arena.alloc_slice_copy(&[owned, function, closure_data]),
ListFindUnsafe => arena.alloc_slice_copy(&[owned, function, closure_data]),
// TODO when we have lists with capacity (if ever) // TODO when we have lists with capacity (if ever)
// List.append should own its first argument // List.append should own its first argument
ListAppend => arena.alloc_slice_copy(&[owned, owned]), ListAppend => arena.alloc_slice_copy(&[owned, owned]),
ListTakeFirst => arena.alloc_slice_copy(&[owned, irrelevant]),
ListDrop => arena.alloc_slice_copy(&[owned, irrelevant]), ListDrop => arena.alloc_slice_copy(&[owned, irrelevant]),
ListDropAt => arena.alloc_slice_copy(&[owned, irrelevant]), ListDropAt => arena.alloc_slice_copy(&[owned, irrelevant]),
ListSwap => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]), ListSwap => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),

View file

@ -531,7 +531,8 @@ impl<'a> Context<'a> {
| ListKeepIf { xs } | ListKeepIf { xs }
| ListKeepOks { xs } | ListKeepOks { xs }
| ListKeepErrs { xs } | ListKeepErrs { xs }
| ListAny { xs } => { | ListAny { xs }
| ListFindUnsafe { xs } => {
let borrows = [function_ps[0].borrow, FUNCTION, CLOSURE_DATA]; let borrows = [function_ps[0].borrow, FUNCTION, CLOSURE_DATA];
let b = self.add_dec_after_lowlevel(arguments, &borrows, b, b_live_vars); let b = self.add_dec_after_lowlevel(arguments, &borrows, b, b_live_vars);

View file

@ -4164,6 +4164,11 @@ pub fn with_hole<'a>(
match_on_closure_argument!(ListMap4, [xs, ys, zs, ws]) match_on_closure_argument!(ListMap4, [xs, ys, zs, ws])
} }
ListFindUnsafe => {
debug_assert_eq!(arg_symbols.len(), 2);
let xs = arg_symbols[0];
match_on_closure_argument!(ListFindUnsafe, [xs])
}
_ => { _ => {
let call = self::Call { let call = self::Call {
call_type: CallType::LowLevel { call_type: CallType::LowLevel {

View file

@ -50,6 +50,9 @@ pub enum HigherOrder {
ListAny { ListAny {
xs: Symbol, xs: Symbol,
}, },
ListFindUnsafe {
xs: Symbol,
},
DictWalk { DictWalk {
xs: Symbol, xs: Symbol,
state: Symbol, state: Symbol,
@ -71,6 +74,7 @@ impl HigherOrder {
HigherOrder::ListKeepOks { .. } => 1, HigherOrder::ListKeepOks { .. } => 1,
HigherOrder::ListKeepErrs { .. } => 1, HigherOrder::ListKeepErrs { .. } => 1,
HigherOrder::ListSortWith { .. } => 2, HigherOrder::ListSortWith { .. } => 2,
HigherOrder::ListFindUnsafe { .. } => 1,
HigherOrder::DictWalk { .. } => 2, HigherOrder::DictWalk { .. } => 2,
HigherOrder::ListAny { .. } => 1, HigherOrder::ListAny { .. } => 1,
} }
@ -96,6 +100,7 @@ enum FirstOrder {
ListLen, ListLen,
ListGetUnsafe, ListGetUnsafe,
ListSet, ListSet,
ListTakeFirst,
ListDrop, ListDrop,
ListDropAt, ListDropAt,
ListSingle, ListSingle,

View file

@ -3745,6 +3745,18 @@ mod solve_expr {
); );
} }
#[test]
fn list_take_first() {
infer_eq_without_problem(
indoc!(
r#"
List.takeFirst
"#
),
"List a, Nat -> List a",
);
}
#[test] #[test]
fn list_drop_last() { fn list_drop_last() {
infer_eq_without_problem( infer_eq_without_problem(

View file

@ -1,25 +0,0 @@
[package]
name = "test_dev"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
roc_collections = { path = "../collections" }
roc_can = { path = "../can" }
roc_build = { path = "../build" }
roc_parse = { path = "../parse" }
roc_reporting = { path = "../reporting" }
roc_load = { path = "../load" }
roc_constrain = { path = "../constrain" }
roc_std = { path = "../../roc_std" }
roc_gen_dev = { path = "../gen_dev" }
roc_mono = { path = "../mono" }
roc_problem = { path = "../problem" }
roc_builtins = { path = "../builtins" }
indoc = "1.0.3"
bumpalo = { version = "3.8.0", features = ["collections"] }
tempfile = "3.2.0"
libloading = "0.7.1"
target-lexicon = "0.12.2"

View file

@ -1,871 +0,0 @@
#![cfg(all(test, any(target_os = "linux", target_os = "macos"), any(target_arch = "x86_64"/*, target_arch = "aarch64"*/)))]
use crate::assert_evals_to;
use indoc::indoc;
#[test]
fn i64_values() {
assert_evals_to!("0", 0, i64);
assert_evals_to!("-0", 0, i64);
assert_evals_to!("-1", -1, i64);
assert_evals_to!("1", 1, i64);
assert_evals_to!("9_000_000_000_000", 9_000_000_000_000, i64);
assert_evals_to!("-9_000_000_000_000", -9_000_000_000_000, i64);
assert_evals_to!("0b1010", 0b1010, i64);
assert_evals_to!("0o17", 0o17, i64);
assert_evals_to!("0x1000_0000_0000_0000", 0x1000_0000_0000_0000, i64);
}
#[test]
fn f64_values() {
assert_evals_to!("0.0", 0.0, f64);
assert_evals_to!("-0.0", 0.0, f64);
assert_evals_to!("1.0", 1.0, f64);
assert_evals_to!("-1.0", -1.0, f64);
assert_evals_to!("3.1415926535897932", 3.141_592_653_589_793, f64);
assert_evals_to!(&format!("{:0.1}", f64::MIN), f64::MIN, f64);
assert_evals_to!(&format!("{:0.1}", f64::MAX), f64::MAX, f64);
}
#[test]
fn gen_add_i64() {
assert_evals_to!(
indoc!(
r#"
1 + 2 + 3
"#
),
6,
i64
);
}
#[test]
fn gen_add_f64() {
assert_evals_to!(
indoc!(
r#"
1.1 + 2.4 + 3
"#
),
6.5,
f64
);
}
#[test]
fn gen_sub_i64() {
assert_evals_to!(
indoc!(
r#"
1 - 2 - 3
"#
),
-4,
i64
);
}
#[test]
fn gen_mul_i64() {
assert_evals_to!(
indoc!(
r#"
2 * 4 * 6
"#
),
48,
i64
);
}
#[test]
fn i64_force_stack() {
// This claims 33 registers. One more than Arm and RISC-V, and many more than x86-64.
assert_evals_to!(
indoc!(
r#"
a = 0
b = 1
c = 2
d = 3
e = 4
f = 5
g = 6
h = 7
i = 8
j = 9
k = 10
l = 11
m = 12
n = 13
o = 14
p = 15
q = 16
r = 17
s = 18
t = 19
u = 20
v = 21
w = 22
x = 23
y = 24
z = 25
aa = 26
ab = 27
ac = 28
ad = 29
ae = 30
af = 31
ag = 32
a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + aa + ab + ac + ad + ae + af + ag
"#
),
528,
i64
);
}
#[test]
fn i64_abs() {
assert_evals_to!("Num.abs -6", 6, i64);
assert_evals_to!("Num.abs 7", 7, i64);
assert_evals_to!("Num.abs 0", 0, i64);
assert_evals_to!("Num.abs -0", 0, i64);
assert_evals_to!("Num.abs -1", 1, i64);
assert_evals_to!("Num.abs 1", 1, i64);
assert_evals_to!("Num.abs 9_000_000_000_000", 9_000_000_000_000, i64);
assert_evals_to!("Num.abs -9_000_000_000_000", 9_000_000_000_000, i64);
}
#[test]
fn gen_int_eq() {
assert_evals_to!(
indoc!(
r#"
4 == 4
"#
),
true,
bool
);
assert_evals_to!(
indoc!(
r#"
3 == 4
"#
),
false,
bool
);
}
#[test]
fn gen_basic_fn() {
assert_evals_to!(
indoc!(
r#"
always42 : Num.Num (Num.Integer Num.Signed64) -> Num.Num (Num.Integer Num.Signed64)
always42 = \_ -> 42
always42 5
"#
),
42,
i64
);
}
#[test]
fn gen_wrap_add_nums() {
assert_evals_to!(
indoc!(
r#"
add2 = \num1, num2 -> num1 + num2
add2 4 5
"#
),
9,
i64
);
}
#[test]
fn gen_wrap_add_nums_force_stack() {
assert_evals_to!(
indoc!(
r#"
add9 = \num1, num2, num3, num4, num5, num6, num7, num8, num9 -> num1 + num2 + num3 + num4 + num5 + num6 + num7 + num8 + num9
add9 1 2 3 4 5 6 7 8 9
"#
),
45,
i64
);
}
#[test]
fn pow_int() {
assert_evals_to!("Num.powInt 2 3", 8, i64);
}
#[test]
fn acos() {
assert_evals_to!("Num.acos 0.5", 1.0471975511965979, f64);
}
#[test]
fn asin() {
assert_evals_to!("Num.asin 0.5", 0.5235987755982989, f64);
}
#[test]
fn atan() {
assert_evals_to!("Num.atan 10", 1.4711276743037347, f64);
}
#[test]
fn gen_if_fn() {
assert_evals_to!(
indoc!(
r#"
limitedNegate = \num ->
x =
if num == 1 then
-1
else if num == -1 then
1
else
num
x
limitedNegate 1
"#
),
-1,
i64
);
}
#[test]
fn gen_fib_fn() {
assert_evals_to!(
indoc!(
r#"
fib = \n ->
if n == 0 then
0
else if n == 1 then
1
else
(fib (n - 1)) + (fib (n - 2))
fib 10
"#
),
55,
i64
);
}
#[test]
fn gen_fast_fib_fn() {
assert_evals_to!(
indoc!(
r#"
fib = \n, a, b ->
if n == 0 then
a
else
fib (n - 1) b (a + b)
fib 10 0 1
"#
),
55,
i64
);
}
#[test]
fn f64_abs() {
assert_evals_to!("Num.abs -4.7", 4.7, f64);
assert_evals_to!("Num.abs 5.8", 5.8, f64);
}
#[test]
fn f64_round() {
assert_evals_to!("Num.round 3.6", 4, i64);
assert_evals_to!("Num.round 3.4", 3, i64);
assert_evals_to!("Num.round 2.5", 3, i64);
assert_evals_to!("Num.round -2.3", -2, i64);
assert_evals_to!("Num.round -2.5", -3, i64);
}
// #[test]
// fn f64_sqrt() {
// // FIXME this works with normal types, but fails when checking uniqueness types
// assert_evals_to!(
// indoc!(
// r#"
// when Num.sqrt 100 is
// Ok val -> val
// Err _ -> -1
// "#
// ),
// 10.0,
// f64
// );
// }
// #[test]
// fn gen_float_eq() {
// assert_evals_to!(
// indoc!(
// r#"
// 1.0 == 1.0
// "#
// ),
// true,
// bool
// );
// }
// #[test]
// fn gen_div_f64() {
// // FIXME this works with normal types, but fails when checking uniqueness types
// assert_evals_to!(
// indoc!(
// r#"
// when 48 / 2 is
// Ok val -> val
// Err _ -> -1
// "#
// ),
// 24.0,
// f64
// );
// }
// #[test]
// fn gen_int_neq() {
// assert_evals_to!(
// indoc!(
// r#"
// 4 != 5
// "#
// ),
// true,
// bool
// );
// }
// #[test]
// fn gen_wrap_int_neq() {
// assert_evals_to!(
// indoc!(
// r#"
// wrappedNotEq : a, a -> Bool
// wrappedNotEq = \num1, num2 ->
// num1 != num2
// wrappedNotEq 2 3
// "#
// ),
// true,
// bool
// );
// }
// #[test]
// fn gen_sub_f64() {
// assert_evals_to!(
// indoc!(
// r#"
// 1.5 - 2.4 - 3
// "#
// ),
// -3.9,
// f64
// );
// }
// #[test]
// fn gen_div_i64() {
// assert_evals_to!(
// indoc!(
// r#"
// when 1000 // 10 is
// Ok val -> val
// Err _ -> -1
// "#
// ),
// 100,
// i64
// );
// }
// #[test]
// fn gen_div_by_zero_i64() {
// assert_evals_to!(
// indoc!(
// r#"
// when 1000 // 0 is
// Err DivByZero -> 99
// _ -> -24
// "#
// ),
// 99,
// i64
// );
// }
// #[test]
// fn gen_rem_i64() {
// assert_evals_to!(
// indoc!(
// r#"
// when Num.rem 8 3 is
// Ok val -> val
// Err _ -> -1
// "#
// ),
// 2,
// i64
// );
// }
// #[test]
// fn gen_rem_div_by_zero_i64() {
// assert_evals_to!(
// indoc!(
// r#"
// when Num.rem 8 0 is
// Err DivByZero -> 4
// Ok _ -> -23
// "#
// ),
// 4,
// i64
// );
// }
// #[test]
// fn gen_is_zero_i64() {
// assert_evals_to!("Num.isZero 0", true, bool);
// assert_evals_to!("Num.isZero 1", false, bool);
// }
// #[test]
// fn gen_is_positive_i64() {
// assert_evals_to!("Num.isPositive 0", false, bool);
// assert_evals_to!("Num.isPositive 1", true, bool);
// assert_evals_to!("Num.isPositive -5", false, bool);
// }
// #[test]
// fn gen_is_negative_i64() {
// assert_evals_to!("Num.isNegative 0", false, bool);
// assert_evals_to!("Num.isNegative 3", false, bool);
// assert_evals_to!("Num.isNegative -2", true, bool);
// }
// #[test]
// fn gen_is_positive_f64() {
// assert_evals_to!("Num.isPositive 0.0", false, bool);
// assert_evals_to!("Num.isPositive 4.7", true, bool);
// assert_evals_to!("Num.isPositive -8.5", false, bool);
// }
// #[test]
// fn gen_is_negative_f64() {
// assert_evals_to!("Num.isNegative 0.0", false, bool);
// assert_evals_to!("Num.isNegative 9.9", false, bool);
// assert_evals_to!("Num.isNegative -4.4", true, bool);
// }
// #[test]
// fn gen_is_zero_f64() {
// assert_evals_to!("Num.isZero 0", true, bool);
// assert_evals_to!("Num.isZero 0_0", true, bool);
// assert_evals_to!("Num.isZero 0.0", true, bool);
// assert_evals_to!("Num.isZero 1", false, bool);
// }
// #[test]
// fn gen_is_odd() {
// assert_evals_to!("Num.isOdd 4", false, bool);
// assert_evals_to!("Num.isOdd 5", true, bool);
// }
// #[test]
// fn gen_is_even() {
// assert_evals_to!("Num.isEven 6", true, bool);
// assert_evals_to!("Num.isEven 7", false, bool);
// }
// #[test]
// fn sin() {
// assert_evals_to!("Num.sin 0", 0.0, f64);
// assert_evals_to!("Num.sin 1.41421356237", 0.9877659459922529, f64);
// }
// #[test]
// fn cos() {
// assert_evals_to!("Num.cos 0", 1.0, f64);
// assert_evals_to!("Num.cos 3.14159265359", -1.0, f64);
// }
// #[test]
// fn tan() {
// assert_evals_to!("Num.tan 0", 0.0, f64);
// assert_evals_to!("Num.tan 1", 1.557407724654902, f64);
// }
// #[test]
// fn lt_i64() {
// assert_evals_to!("1 < 2", true, bool);
// assert_evals_to!("1 < 1", false, bool);
// assert_evals_to!("2 < 1", false, bool);
// assert_evals_to!("0 < 0", false, bool);
// }
// #[test]
// fn lte_i64() {
// assert_evals_to!("1 <= 1", true, bool);
// assert_evals_to!("2 <= 1", false, bool);
// assert_evals_to!("1 <= 2", true, bool);
// assert_evals_to!("0 <= 0", true, bool);
// }
// #[test]
// fn gt_i64() {
// assert_evals_to!("2 > 1", true, bool);
// assert_evals_to!("2 > 2", false, bool);
// assert_evals_to!("1 > 1", false, bool);
// assert_evals_to!("0 > 0", false, bool);
// }
// #[test]
// fn gte_i64() {
// assert_evals_to!("1 >= 1", true, bool);
// assert_evals_to!("1 >= 2", false, bool);
// assert_evals_to!("2 >= 1", true, bool);
// assert_evals_to!("0 >= 0", true, bool);
// }
// #[test]
// fn lt_f64() {
// assert_evals_to!("1.1 < 1.2", true, bool);
// assert_evals_to!("1.1 < 1.1", false, bool);
// assert_evals_to!("1.2 < 1.1", false, bool);
// assert_evals_to!("0.0 < 0.0", false, bool);
// }
// #[test]
// fn lte_f64() {
// assert_evals_to!("1.1 <= 1.1", true, bool);
// assert_evals_to!("1.2 <= 1.1", false, bool);
// assert_evals_to!("1.1 <= 1.2", true, bool);
// assert_evals_to!("0.0 <= 0.0", true, bool);
// }
// #[test]
// fn gt_f64() {
// assert_evals_to!("2.2 > 1.1", true, bool);
// assert_evals_to!("2.2 > 2.2", false, bool);
// assert_evals_to!("1.1 > 2.2", false, bool);
// assert_evals_to!("0.0 > 0.0", false, bool);
// }
// #[test]
// fn gte_f64() {
// assert_evals_to!("1.1 >= 1.1", true, bool);
// assert_evals_to!("1.1 >= 1.2", false, bool);
// assert_evals_to!("1.2 >= 1.1", true, bool);
// assert_evals_to!("0.0 >= 0.0", true, bool);
// }
#[test]
fn gen_order_of_arithmetic_ops() {
assert_evals_to!(
indoc!(
r#"
1 + 3 * 7 - 2
"#
),
20,
i64
);
}
// #[test]
// fn gen_order_of_arithmetic_ops_complex_float() {
// assert_evals_to!(
// indoc!(
// r#"
// 3 - 48 * 2.0
// "#
// ),
// -93.0,
// f64
// );
// }
#[test]
fn if_guard_bind_variable_false() {
assert_evals_to!(
indoc!(
r#"
wrapper = \{} ->
when 10 is
x if x == 5 -> 0
_ -> 42
wrapper {}
"#
),
42,
i64
);
}
#[test]
fn if_guard_bind_variable_true() {
assert_evals_to!(
indoc!(
r#"
wrapper = \{} ->
when 10 is
x if x == 10 -> 42
_ -> 0
wrapper {}
"#
),
42,
i64
);
}
#[test]
fn tail_call_elimination() {
assert_evals_to!(
indoc!(
r#"
sum = \n, accum ->
when n is
0 -> accum
_ -> sum (n - 1) (n + accum)
sum 1_000_000 0
"#
),
500000500000,
i64
);
}
// #[test]
// fn int_negate() {
// assert_evals_to!("Num.neg 123", -123, i64);
// }
// #[test]
// fn gen_wrap_int_neg() {
// assert_evals_to!(
// indoc!(
// r#"
// wrappedNeg = \num -> -num
// wrappedNeg 3
// "#
// ),
// -3,
// i64
// );
// }
// #[test]
// fn int_to_float() {
// assert_evals_to!("Num.toFloat 0x9", 9.0, f64);
// }
// #[test]
// fn num_to_float() {
// assert_evals_to!("Num.toFloat 9", 9.0, f64);
// }
// #[test]
// fn float_to_float() {
// assert_evals_to!("Num.toFloat 0.5", 0.5, f64);
// }
// #[test]
// fn int_compare() {
// assert_evals_to!("Num.compare 0 1", RocOrder::Lt, RocOrder);
// assert_evals_to!("Num.compare 1 1", RocOrder::Eq, RocOrder);
// assert_evals_to!("Num.compare 1 0", RocOrder::Gt, RocOrder);
// }
// #[test]
// fn float_compare() {
// assert_evals_to!("Num.compare 0.01 3.14", RocOrder::Lt, RocOrder);
// assert_evals_to!("Num.compare 3.14 3.14", RocOrder::Eq, RocOrder);
// assert_evals_to!("Num.compare 3.14 0.01", RocOrder::Gt, RocOrder);
// }
// #[test]
// fn pow() {
// assert_evals_to!("Num.pow 2.0 2.0", 4.0, f64);
// }
// #[test]
// fn ceiling() {
// assert_evals_to!("Num.ceiling 1.1", 2, i64);
// }
// #[test]
// fn floor() {
// assert_evals_to!("Num.floor 1.9", 1, i64);
// }
// // #[test]
// // #[should_panic(expected = r#"Roc failed with message: "integer addition overflowed!"#)]
// // fn int_overflow() {
// // assert_evals_to!(
// // indoc!(
// // r#"
// // 9_223_372_036_854_775_807 + 1
// // "#
// // ),
// // 0,
// // i64
// // );
// // }
// #[test]
// fn int_add_checked() {
// assert_evals_to!(
// indoc!(
// r#"
// when Num.addChecked 1 2 is
// Ok v -> v
// _ -> -1
// "#
// ),
// 3,
// i64
// );
// assert_evals_to!(
// indoc!(
// r#"
// when Num.addChecked 9_223_372_036_854_775_807 1 is
// Err Overflow -> -1
// Ok v -> v
// "#
// ),
// -1,
// i64
// );
// }
// #[test]
// fn int_add_wrap() {
// assert_evals_to!(
// indoc!(
// r#"
// Num.addWrap 9_223_372_036_854_775_807 1
// "#
// ),
// std::i64::MIN,
// i64
// );
// }
// #[test]
// fn float_add_checked_pass() {
// assert_evals_to!(
// indoc!(
// r#"
// when Num.addChecked 1.0 0.0 is
// Ok v -> v
// Err Overflow -> -1.0
// "#
// ),
// 1.0,
// f64
// );
// }
// #[test]
// fn float_add_checked_fail() {
// assert_evals_to!(
// indoc!(
// r#"
// when Num.addChecked 1.7976931348623157e308 1.7976931348623157e308 is
// Err Overflow -> -1
// Ok v -> v
// "#
// ),
// -1.0,
// f64
// );
// }
// // #[test]
// // #[should_panic(expected = r#"Roc failed with message: "float addition overflowed!"#)]
// // fn float_overflow() {
// // assert_evals_to!(
// // indoc!(
// // r#"
// // 1.7976931348623157e308 + 1.7976931348623157e308
// // "#
// // ),
// // 0.0,
// // f64
// // );
// // }
// #[test]
// fn max_i128() {
// assert_evals_to!(
// indoc!(
// r#"
// Num.maxI128
// "#
// ),
// i128::MAX,
// i128
// );
// }
// #[test]
// fn num_max_int() {
// assert_evals_to!(
// indoc!(
// r#"
// Num.maxInt
// "#
// ),
// i64::MAX,
// i64
// );
// }
// #[test]
// fn num_min_int() {
// assert_evals_to!(
// indoc!(
// r#"
// Num.minInt
// "#
// ),
// i64::MIN,
// i64
// );
// }

View file

@ -1,933 +0,0 @@
#![cfg(all(test, any(target_os = "linux", target_os = "macos"), any(target_arch = "x86_64"/*, target_arch = "aarch64"*/)))]
use crate::assert_evals_to;
use indoc::indoc;
#[test]
fn basic_record() {
assert_evals_to!(
indoc!(
r#"
{ y: 17, x: 15, z: 19 }.x
"#
),
15,
i64
);
assert_evals_to!(
indoc!(
r#"
{ x: 15, y: 17, z: 19 }.y
"#
),
17,
i64
);
assert_evals_to!(
indoc!(
r#"
{ x: 15, y: 17, z: 19 }.z
"#
),
19,
i64
);
}
#[test]
fn nested_record() {
assert_evals_to!(
indoc!(
r#"
{ x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.x
"#
),
15,
i64
);
assert_evals_to!(
indoc!(
r#"
{ x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.y.a
"#
),
12,
i64
);
assert_evals_to!(
indoc!(
r#"
{ x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.y.b
"#
),
15,
i64
);
assert_evals_to!(
indoc!(
r#"
{ x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.y.c
"#
),
2,
i64
);
assert_evals_to!(
indoc!(
r#"
{ x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.z
"#
),
19,
i64
);
}
#[test]
fn f64_record() {
assert_evals_to!(
indoc!(
r#"
rec = { y: 17.2, x: 15.1, z: 19.3 }
rec.x
"#
),
15.1,
f64
);
assert_evals_to!(
indoc!(
r#"
rec = { y: 17.2, x: 15.1, z: 19.3 }
rec.y
"#
),
17.2,
f64
);
assert_evals_to!(
indoc!(
r#"
rec = { y: 17.2, x: 15.1, z: 19.3 }
rec.z
"#
),
19.3,
f64
);
}
// #[test]
// fn fn_record() {
// assert_evals_to!(
// indoc!(
// r#"
// getRec = \x -> { y: 17, x, z: 19 }
// (getRec 15).x
// "#
// ),
// 15,
// i64
// );
// assert_evals_to!(
// indoc!(
// r#"
// rec = { x: 15, y: 17, z: 19 }
// rec.y
// "#
// ),
// 17,
// i64
// );
// assert_evals_to!(
// indoc!(
// r#"
// rec = { x: 15, y: 17, z: 19 }
// rec.z
// "#
// ),
// 19,
// i64
// );
// assert_evals_to!(
// indoc!(
// r#"
// rec = { x: 15, y: 17, z: 19 }
// rec.z + rec.x
// "#
// ),
// 34,
// i64
// );
// }
#[test]
fn def_record() {
assert_evals_to!(
indoc!(
r#"
rec = { y: 17, x: 15, z: 19 }
rec.x
"#
),
15,
i64
);
assert_evals_to!(
indoc!(
r#"
rec = { x: 15, y: 17, z: 19 }
rec.y
"#
),
17,
i64
);
assert_evals_to!(
indoc!(
r#"
rec = { x: 15, y: 17, z: 19 }
rec.z
"#
),
19,
i64
);
}
#[test]
fn when_on_record() {
assert_evals_to!(
indoc!(
r#"
when { x: 0x2 } is
{ x } -> x + 3
"#
),
5,
i64
);
}
#[test]
fn when_record_with_guard_pattern() {
assert_evals_to!(
indoc!(
r#"
when { x: 0x2, y: 3.14 } is
{ x: var } -> var + 3
"#
),
5,
i64
);
}
#[test]
fn let_with_record_pattern() {
assert_evals_to!(
indoc!(
r#"
{ x } = { x: 0x2, y: 3.14 }
x
"#
),
2,
i64
);
}
#[test]
fn record_guard_pattern() {
assert_evals_to!(
indoc!(
r#"
when { x: 0x2, y: 3.14 } is
{ x: 0x4 } -> 5
{ x } -> x + 3
"#
),
5,
i64
);
}
#[test]
fn twice_record_access() {
assert_evals_to!(
indoc!(
r#"
x = {a: 0x2, b: 0x3 }
x.a + x.b
"#
),
5,
i64
);
}
#[test]
fn empty_record() {
assert_evals_to!(
indoc!(
r#"
v = {}
v
"#
),
(),
()
);
}
#[test]
fn i64_record1_literal() {
assert_evals_to!(
indoc!(
r#"
{ x: 3 }
"#
),
3,
i64
);
}
// #[test]
// fn i64_record2_literal() {
// assert_evals_to!(
// indoc!(
// r#"
// { x: 3, y: 5 }
// "#
// ),
// (3, 5),
// (i64, i64)
// );
// }
// // #[test]
// // fn i64_record3_literal() {
// // assert_evals_to!(
// // indoc!(
// // r#"
// // { x: 3, y: 5, z: 17 }
// // "#
// // ),
// // (3, 5, 17),
// // (i64, i64, i64)
// // );
// // }
// #[test]
// fn f64_record2_literal() {
// assert_evals_to!(
// indoc!(
// r#"
// { x: 3.1, y: 5.1 }
// "#
// ),
// (3.1, 5.1),
// (f64, f64)
// );
// }
// // #[test]
// // fn f64_record3_literal() {
// // assert_evals_to!(
// // indoc!(
// // r#"
// // { x: 3.1, y: 5.1, z: 17.1 }
// // "#
// // ),
// // (3.1, 5.1, 17.1),
// // (f64, f64, f64)
// // );
// // }
// // #[test]
// // fn bool_record4_literal() {
// // assert_evals_to!(
// // indoc!(
// // r#"
// // record : { a : Bool, b : Bool, c : Bool, d : Bool }
// // record = { a: True, b: True, c : True, d : Bool }
// // record
// // "#
// // ),
// // (true, false, false, true),
// // (bool, bool, bool, bool)
// // );
// // }
// #[test]
// fn i64_record1_literal() {
// assert_evals_to!(
// indoc!(
// r#"
// { a: 3 }
// "#
// ),
// 3,
// i64
// );
// }
// // #[test]
// // fn i64_record9_literal() {
// // assert_evals_to!(
// // indoc!(
// // r#"
// // { 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),
// // (i64, i64, i64, i64, i64, i64, i64, i64, i64)
// // );
// // }
// // #[test]
// // fn f64_record3_literal() {
// // assert_evals_to!(
// // indoc!(
// // r#"
// // { x: 3.1, y: 5.1, z: 17.1 }
// // "#
// // ),
// // (3.1, 5.1, 17.1),
// // (f64, f64, f64)
// // );
// // }
// #[test]
// fn bool_literal() {
// assert_evals_to!(
// indoc!(
// r#"
// x : Bool
// x = True
// x
// "#
// ),
// true,
// bool
// );
// }
// #[test]
// fn optional_field_when_use_default() {
// assert_evals_to!(
// indoc!(
// r#"
// app "test" provides [ main ] to "./platform"
// f = \r ->
// when r is
// { x: Blue, y ? 3 } -> y
// { x: Red, y ? 5 } -> y
// main =
// a = f { x: Blue, y: 7 }
// b = f { x: Blue }
// c = f { x: Red, y: 11 }
// d = f { x: Red }
// a * b * c * d
// "#
// ),
// 3 * 5 * 7 * 11,
// i64
// );
// }
// #[test]
// fn optional_field_when_use_default_nested() {
// assert_evals_to!(
// indoc!(
// r#"
// f = \r ->
// when r is
// { x: Blue, y ? 3 } -> y
// { x: Red, y ? 5 } -> y
// a = f { x: Blue, y: 7 }
// b = f { x: Blue }
// c = f { x: Red, y: 11 }
// d = f { x: Red }
// a * b * c * d
// "#
// ),
// 3 * 5 * 7 * 11,
// i64
// );
// }
// #[test]
// fn optional_field_when_no_use_default() {
// assert_evals_to!(
// indoc!(
// r#"
// app "test" provides [ main ] to "./platform"
// f = \r ->
// { x ? 10, y } = r
// x + y
// main =
// f { x: 4, y: 9 }
// "#
// ),
// 13,
// i64
// );
// }
// #[test]
// fn optional_field_when_no_use_default_nested() {
// assert_evals_to!(
// indoc!(
// r#"
// f = \r ->
// { x ? 10, y } = r
// x + y
// f { x: 4, y: 9 }
// "#
// ),
// 13,
// i64
// );
// }
// #[test]
// fn optional_field_let_use_default() {
// assert_evals_to!(
// indoc!(
// r#"
// app "test" provides [ main ] to "./platform"
// f = \r ->
// { x ? 10, y } = r
// x + y
// main =
// f { y: 9 }
// "#
// ),
// 19,
// i64
// );
// }
// #[test]
// fn optional_field_let_no_use_default() {
// assert_evals_to!(
// indoc!(
// r#"
// app "test" provides [ main ] to "./platform"
// f = \r ->
// { x ? 10, y } = r
// x + y
// main =
// f { x: 4, y: 9 }
// "#
// ),
// 13,
// i64
// );
// }
// #[test]
// fn optional_field_let_no_use_default_nested() {
// assert_evals_to!(
// indoc!(
// r#"
// f = \r ->
// { x ? 10, y } = r
// x + y
// f { x: 4, y: 9 }
// "#
// ),
// 13,
// i64
// );
// }
// #[test]
// fn optional_field_function_use_default() {
// assert_evals_to!(
// indoc!(
// r#"
// f = \{ x ? 10, y } -> x + y
// f { y: 9 }
// "#
// ),
// 19,
// i64
// );
// }
// #[test]
// #[ignore]
// fn optional_field_function_no_use_default() {
// // blocked on https://github.com/rtfeldman/roc/issues/786
// assert_evals_to!(
// indoc!(
// r#"
// app "test" provides [ main ] to "./platform"
// f = \{ x ? 10, y } -> x + y
// main =
// f { x: 4, y: 9 }
// "#
// ),
// 13,
// i64
// );
// }
// #[test]
// #[ignore]
// fn optional_field_function_no_use_default_nested() {
// // blocked on https://github.com/rtfeldman/roc/issues/786
// assert_evals_to!(
// indoc!(
// r#"
// f = \{ x ? 10, y } -> x + y
// f { x: 4, y: 9 }
// "#
// ),
// 13,
// i64
// );
// }
// #[test]
// fn optional_field_singleton_record() {
// assert_evals_to!(
// indoc!(
// r#"
// when { x : 4 } is
// { x ? 3 } -> x
// "#
// ),
// 4,
// i64
// );
// }
// #[test]
// fn optional_field_empty_record() {
// assert_evals_to!(
// indoc!(
// r#"
// when { } is
// { x ? 3 } -> x
// "#
// ),
// 3,
// i64
// );
// }
// #[test]
// fn return_record_2() {
// assert_evals_to!(
// indoc!(
// r#"
// { x: 3, y: 5 }
// "#
// ),
// [3, 5],
// [i64; 2]
// );
// }
// #[test]
// fn return_record_3() {
// assert_evals_to!(
// indoc!(
// r#"
// { x: 3, y: 5, z: 4 }
// "#
// ),
// (3, 5, 4),
// (i64, i64, i64)
// );
// }
// #[test]
// fn return_record_4() {
// assert_evals_to!(
// indoc!(
// r#"
// { a: 3, b: 5, c: 4, d: 2 }
// "#
// ),
// [3, 5, 4, 2],
// [i64; 4]
// );
// }
// #[test]
// fn return_record_5() {
// assert_evals_to!(
// indoc!(
// r#"
// { a: 3, b: 5, c: 4, d: 2, e: 1 }
// "#
// ),
// [3, 5, 4, 2, 1],
// [i64; 5]
// );
// }
// #[test]
// fn return_record_6() {
// assert_evals_to!(
// indoc!(
// r#"
// { a: 3, b: 5, c: 4, d: 2, e: 1, f: 7 }
// "#
// ),
// [3, 5, 4, 2, 1, 7],
// [i64; 6]
// );
// }
// #[test]
// fn return_record_7() {
// assert_evals_to!(
// indoc!(
// r#"
// { a: 3, b: 5, c: 4, d: 2, e: 1, f: 7, g: 8 }
// "#
// ),
// [3, 5, 4, 2, 1, 7, 8],
// [i64; 7]
// );
// }
// #[test]
// fn return_record_float_int() {
// assert_evals_to!(
// indoc!(
// r#"
// { a: 3.14, b: 0x1 }
// "#
// ),
// (3.14, 0x1),
// (f64, i64)
// );
// }
// #[test]
// fn return_record_int_float() {
// assert_evals_to!(
// indoc!(
// r#"
// { a: 0x1, b: 3.14 }
// "#
// ),
// (0x1, 3.14),
// (i64, f64)
// );
// }
// #[test]
// fn return_record_float_float() {
// assert_evals_to!(
// indoc!(
// r#"
// { a: 6.28, b: 3.14 }
// "#
// ),
// (6.28, 3.14),
// (f64, f64)
// );
// }
// #[test]
// fn return_record_float_float_float() {
// assert_evals_to!(
// indoc!(
// r#"
// { a: 6.28, b: 3.14, c: 0.1 }
// "#
// ),
// (6.28, 3.14, 0.1),
// (f64, f64, f64)
// );
// }
// #[test]
// fn return_nested_record() {
// assert_evals_to!(
// indoc!(
// r#"
// { flag: 0x0, payload: { a: 6.28, b: 3.14, c: 0.1 } }
// "#
// ),
// (0x0, (6.28, 3.14, 0.1)),
// (i64, (f64, f64, f64))
// );
// }
// #[test]
// fn accessor() {
// assert_evals_to!(
// indoc!(
// r#"
// .foo { foo: 4 } + .foo { bar: 6.28, foo: 3 }
// "#
// ),
// 7,
// i64
// );
// }
// #[test]
// fn accessor_single_element_record() {
// assert_evals_to!(
// indoc!(
// r#"
// .foo { foo: 4 }
// "#
// ),
// 4,
// i64
// );
// }
// #[test]
// fn update_record() {
// assert_evals_to!(
// indoc!(
// r#"
// rec = { foo: 42, bar: 6 }
// { rec & foo: rec.foo + 1 }
// "#
// ),
// (6, 43),
// (i64, i64)
// );
// }
#[test]
fn update_single_element_record() {
assert_evals_to!(
indoc!(
r#"
rec = { foo: 42}
{ rec & foo: rec.foo + 1 }
"#
),
43,
i64
);
}
// #[test]
// fn booleans_in_record() {
// assert_evals_to!(
// indoc!("{ x: 1 == 1, y: 1 == 1 }"),
// (true, true),
// (bool, bool)
// );
// assert_evals_to!(
// indoc!("{ x: 1 != 1, y: 1 == 1 }"),
// (false, true),
// (bool, bool)
// );
// assert_evals_to!(
// indoc!("{ x: 1 == 1, y: 1 != 1 }"),
// (true, false),
// (bool, bool)
// );
// assert_evals_to!(
// indoc!("{ x: 1 != 1, y: 1 != 1 }"),
// (false, false),
// (bool, bool)
// );
// }
// #[test]
// fn alignment_in_record() {
// assert_evals_to!(
// indoc!("{ c: 32, b: if True then Red else if True then Green else Blue, a: 1 == 1 }"),
// (32i64, true, 2u8),
// (i64, bool, u8)
// );
// }
// #[test]
// fn blue_and_present() {
// assert_evals_to!(
// indoc!(
// r#"
// f = \r ->
// when r is
// { x: Blue, y ? 3 } -> y
// { x: Red, y ? 5 } -> y
// f { x: Blue, y: 7 }
// "#
// ),
// 7,
// i64
// );
// }
// #[test]
// fn blue_and_absent() {
// assert_evals_to!(
// indoc!(
// r#"
// f = \r ->
// when r is
// { x: Blue, y ? 3 } -> y
// { x: Red, y ? 5 } -> y
// f { x: Blue }
// "#
// ),
// 3,
// i64
// );
// }

View file

@ -1,950 +0,0 @@
#![cfg(all(test, any(target_os = "linux", target_os = "macos"), any(target_arch = "x86_64"/*, target_arch = "aarch64"*/)))]
//use indoc::indoc;
use crate::assert_evals_to;
// use roc_std::{RocList, RocStr};
// #[test]
// fn str_split_bigger_delimiter_small_str() {
// assert_evals_to!(
// indoc!(
// r#"
// List.len (Str.split "hello" "JJJJ there")
// "#
// ),
// 1,
// i64
// );
// assert_evals_to!(
// indoc!(
// r#"
// when List.first (Str.split "JJJ" "JJJJ there") is
// Ok str ->
// Str.countGraphemes str
// _ ->
// -1
// "#
// ),
// 3,
// i64
// );
// }
// #[test]
// fn str_split_str_concat_repeated() {
// assert_evals_to!(
// indoc!(
// r#"
// when List.first (Str.split "JJJJJ" "JJJJ there") is
// Ok str ->
// str
// |> Str.concat str
// |> Str.concat str
// |> Str.concat str
// |> Str.concat str
// _ ->
// "Not Str!"
// "#
// ),
// RocStr::from_slice(b"JJJJJJJJJJJJJJJJJJJJJJJJJ"),
// RocStr
// );
// }
// #[test]
// fn str_split_small_str_bigger_delimiter() {
// assert_evals_to!(
// indoc!(
// r#"
// when
// List.first
// (Str.split "JJJ" "0123456789abcdefghi")
// is
// Ok str -> str
// _ -> ""
// "#
// ),
// RocStr::from_slice(b"JJJ"),
// RocStr
// );
// }
// #[test]
// fn str_split_big_str_small_delimiter() {
// assert_evals_to!(
// indoc!(
// r#"
// Str.split "01234567789abcdefghi?01234567789abcdefghi" "?"
// "#
// ),
// RocList::from_slice(&[
// RocStr::from_slice(b"01234567789abcdefghi"),
// RocStr::from_slice(b"01234567789abcdefghi")
// ]),
// RocList<RocStr>
// );
// assert_evals_to!(
// indoc!(
// r#"
// Str.split "01234567789abcdefghi 3ch 01234567789abcdefghi" "3ch"
// "#
// ),
// RocList::from_slice(&[
// RocStr::from_slice(b"01234567789abcdefghi "),
// RocStr::from_slice(b" 01234567789abcdefghi")
// ]),
// RocList<RocStr>
// );
// }
// #[test]
// fn str_split_small_str_small_delimiter() {
// assert_evals_to!(
// indoc!(
// r#"
// Str.split "J!J!J" "!"
// "#
// ),
// RocList::from_slice(&[
// RocStr::from_slice(b"J"),
// RocStr::from_slice(b"J"),
// RocStr::from_slice(b"J")
// ]),
// RocList<RocStr>
// );
// }
// #[test]
// fn str_split_bigger_delimiter_big_strs() {
// assert_evals_to!(
// indoc!(
// r#"
// Str.split
// "string to split is shorter"
// "than the delimiter which happens to be very very long"
// "#
// ),
// RocList::from_slice(&[RocStr::from_slice(b"string to split is shorter")]),
// RocList<RocStr>
// );
// }
// #[test]
// fn str_split_empty_strs() {
// assert_evals_to!(
// indoc!(
// r#"
// Str.split "" ""
// "#
// ),
// RocList::from_slice(&[RocStr::from_slice(b"")]),
// RocList<RocStr>
// );
// }
// #[test]
// fn str_split_minimal_example() {
// assert_evals_to!(
// indoc!(
// r#"
// Str.split "a," ","
// "#
// ),
// RocList::from_slice(&[RocStr::from_slice(b"a"), RocStr::from_slice(b"")]),
// RocList<RocStr>
// )
// }
// #[test]
// fn str_split_small_str_big_delimiter() {
// assert_evals_to!(
// indoc!(
// r#"
// Str.split
// "1---- ---- ---- ---- ----2---- ---- ---- ---- ----"
// "---- ---- ---- ---- ----"
// |> List.len
// "#
// ),
// 3,
// i64
// );
// assert_evals_to!(
// indoc!(
// r#"
// Str.split
// "1---- ---- ---- ---- ----2---- ---- ---- ---- ----"
// "---- ---- ---- ---- ----"
// "#
// ),
// RocList::from_slice(&[
// RocStr::from_slice(b"1"),
// RocStr::from_slice(b"2"),
// RocStr::from_slice(b"")
// ]),
// RocList<RocStr>
// );
// }
// #[test]
// fn str_split_small_str_20_char_delimiter() {
// assert_evals_to!(
// indoc!(
// r#"
// Str.split
// "3|-- -- -- -- -- -- |4|-- -- -- -- -- -- |"
// "|-- -- -- -- -- -- |"
// "#
// ),
// RocList::from_slice(&[
// RocStr::from_slice(b"3"),
// RocStr::from_slice(b"4"),
// RocStr::from_slice(b"")
// ]),
// RocList<RocStr>
// );
// }
// #[test]
// fn str_concat_big_to_big() {
// assert_evals_to!(
// indoc!(
// r#"
// Str.concat
// "First string that is fairly long. Longer strings make for different errors. "
// "Second string that is also fairly long. Two long strings test things that might not appear with short strings."
// "#
// ),
// RocStr::from_slice(b"First string that is fairly long. Longer strings make for different errors. Second string that is also fairly long. Two long strings test things that might not appear with short strings."),
// RocStr
// );
// }
#[test]
fn small_str_literal() {
assert_evals_to!(
"\"JJJJJJJJJJJJJJJ\"",
[
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0b1000_1111
],
[u8; 16]
);
}
// #[test]
// fn small_str_zeroed_literal() {
// // Verifies that we zero out unused bytes in the string.
// // This is important so that string equality tests don't randomly
// // fail due to unused memory being there!
// assert_evals_to!(
// "\"J\"",
// [
// 0x4a,
// 0x00,
// 0x00,
// 0x00,
// 0x00,
// 0x00,
// 0x00,
// 0x00,
// 0x00,
// 0x00,
// 0x00,
// 0x00,
// 0x00,
// 0x00,
// 0x00,
// 0b1000_0001
// ],
// [u8; 16]
// );
// }
#[test]
fn small_str_concat_empty_first_arg() {
assert_evals_to!(
r#"Str.concat "" "JJJJJJJJJJJJJJJ""#,
[
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0b1000_1111
],
[u8; 16]
);
}
#[test]
fn small_str_concat_empty_second_arg() {
assert_evals_to!(
r#"Str.concat "JJJJJJJJJJJJJJJ" """#,
[
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0b1000_1111
],
[u8; 16]
);
}
// #[test]
// fn small_str_concat_small_to_big() {
// assert_evals_to!(
// r#"Str.concat "abc" " this is longer than 15 chars""#,
// RocStr::from_slice(b"abc this is longer than 15 chars"),
// RocStr
// );
// }
#[test]
fn small_str_concat_small_to_small_staying_small() {
assert_evals_to!(
r#"Str.concat "J" "JJJJJJJJJJJJJJ""#,
[
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0x4a,
0b1000_1111
],
[u8; 16]
);
}
// #[test]
// fn small_str_concat_small_to_small_overflow_to_big() {
// assert_evals_to!(
// r#"Str.concat "abcdefghijklm" "nopqrstuvwxyz""#,
// RocStr::from_slice(b"abcdefghijklmnopqrstuvwxyz"),
// RocStr
// );
// }
// #[test]
// fn str_concat_empty() {
// assert_evals_to!(r#"Str.concat "" """#, RocStr::default(), RocStr);
// }
// #[test]
// fn small_str_is_empty() {
// assert_evals_to!(r#"Str.isEmpty "abc""#, false, bool);
// }
// #[test]
// fn big_str_is_empty() {
// assert_evals_to!(
// r#"Str.isEmpty "this is more than 15 chars long""#,
// false,
// bool
// );
// }
// #[test]
// fn empty_str_is_empty() {
// assert_evals_to!(r#"Str.isEmpty """#, true, bool);
// }
// #[test]
// fn str_starts_with() {
// assert_evals_to!(r#"Str.startsWith "hello world" "hell""#, true, bool);
// assert_evals_to!(r#"Str.startsWith "hello world" """#, true, bool);
// assert_evals_to!(r#"Str.startsWith "nope" "hello world""#, false, bool);
// assert_evals_to!(r#"Str.startsWith "hell" "hello world""#, false, bool);
// assert_evals_to!(r#"Str.startsWith "" "hello world""#, false, bool);
// }
// #[test]
// fn str_starts_with_code_point() {
// assert_evals_to!(
// &format!(r#"Str.startsWithCodePt "foobar" {}"#, 'f' as u32),
// true,
// bool
// );
// assert_evals_to!(
// &format!(r#"Str.startsWithCodePt "zoobar" {}"#, 'f' as u32),
// false,
// bool
// );
// }
// #[test]
// fn str_ends_with() {
// assert_evals_to!(r#"Str.endsWith "hello world" "world""#, true, bool);
// assert_evals_to!(r#"Str.endsWith "nope" "hello world""#, false, bool);
// assert_evals_to!(r#"Str.endsWith "" "hello world""#, false, bool);
// }
// #[test]
// fn str_count_graphemes_small_str() {
// assert_evals_to!(r#"Str.countGraphemes "å🤔""#, 2, usize);
// }
// #[test]
// fn str_count_graphemes_three_js() {
// assert_evals_to!(r#"Str.countGraphemes "JJJ""#, 3, usize);
// }
// #[test]
// fn str_count_graphemes_big_str() {
// assert_evals_to!(
// r#"Str.countGraphemes "6🤔å🤔e¥🤔çppkd🙃1jdal🦯asdfa∆ltråø˚waia8918.,🏅jjc""#,
// 45,
// usize
// );
// }
// #[test]
// fn str_starts_with_same_big_str() {
// assert_evals_to!(
// r#"Str.startsWith "123456789123456789" "123456789123456789""#,
// true,
// bool
// );
// }
// #[test]
// fn str_starts_with_different_big_str() {
// assert_evals_to!(
// r#"Str.startsWith "12345678912345678910" "123456789123456789""#,
// true,
// bool
// );
// }
// #[test]
// fn str_starts_with_same_small_str() {
// assert_evals_to!(r#"Str.startsWith "1234" "1234""#, true, bool);
// }
// #[test]
// fn str_starts_with_different_small_str() {
// assert_evals_to!(r#"Str.startsWith "1234" "12""#, true, bool);
// }
// #[test]
// fn str_starts_with_false_small_str() {
// assert_evals_to!(r#"Str.startsWith "1234" "23""#, false, bool);
// }
// #[test]
// fn str_from_int() {
// assert_evals_to!(
// r#"Str.fromInt 1234"#,
// roc_std::RocStr::from_slice("1234".as_bytes()),
// roc_std::RocStr
// );
// assert_evals_to!(
// r#"Str.fromInt 0"#,
// roc_std::RocStr::from_slice("0".as_bytes()),
// roc_std::RocStr
// );
// assert_evals_to!(
// r#"Str.fromInt -1"#,
// roc_std::RocStr::from_slice("-1".as_bytes()),
// roc_std::RocStr
// );
// let max = format!("{}", i64::MAX);
// assert_evals_to!(
// r#"Str.fromInt Num.maxInt"#,
// RocStr::from_slice(max.as_bytes()),
// RocStr
// );
// let min = format!("{}", i64::MIN);
// assert_evals_to!(
// r#"Str.fromInt Num.minInt"#,
// RocStr::from_slice(min.as_bytes()),
// RocStr
// );
// }
// #[test]
// fn str_from_utf8_pass_single_ascii() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 97 ] is
// Ok val -> val
// Err _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("a".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_from_utf8_pass_many_ascii() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 97, 98, 99, 0x7E ] is
// Ok val -> val
// Err _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("abc~".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_from_utf8_pass_single_unicode() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 0xE2, 0x88, 0x86 ] is
// Ok val -> val
// Err _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("∆".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_from_utf8_pass_many_unicode() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 0xE2, 0x88, 0x86, 0xC5, 0x93, 0xC2, 0xAC ] is
// Ok val -> val
// Err _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("∆œ¬".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_from_utf8_pass_single_grapheme() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 0xF0, 0x9F, 0x92, 0x96 ] is
// Ok val -> val
// Err _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("💖".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_from_utf8_pass_many_grapheme() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 0xF0, 0x9F, 0x92, 0x96, 0xF0, 0x9F, 0xA4, 0xA0, 0xF0, 0x9F, 0x9A, 0x80 ] is
// Ok val -> val
// Err _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("💖🤠🚀".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_from_utf8_pass_all() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 0xF0, 0x9F, 0x92, 0x96, 98, 0xE2, 0x88, 0x86 ] is
// Ok val -> val
// Err _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("💖b∆".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_from_utf8_fail_invalid_start_byte() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 97, 98, 0x80, 99 ] is
// Err (BadUtf8 InvalidStartByte byteIndex) ->
// if byteIndex == 2 then
// "a"
// else
// "b"
// _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("a".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_from_utf8_fail_unexpected_end_of_sequence() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 97, 98, 99, 0xC2 ] is
// Err (BadUtf8 UnexpectedEndOfSequence byteIndex) ->
// if byteIndex == 3 then
// "a"
// else
// "b"
// _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("a".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_from_utf8_fail_expected_continuation() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 97, 98, 99, 0xC2, 0x00 ] is
// Err (BadUtf8 ExpectedContinuation byteIndex) ->
// if byteIndex == 3 then
// "a"
// else
// "b"
// _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("a".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_from_utf8_fail_overlong_encoding() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 97, 0xF0, 0x80, 0x80, 0x80 ] is
// Err (BadUtf8 OverlongEncoding byteIndex) ->
// if byteIndex == 1 then
// "a"
// else
// "b"
// _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("a".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_from_utf8_fail_codepoint_too_large() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 97, 0xF4, 0x90, 0x80, 0x80 ] is
// Err (BadUtf8 CodepointTooLarge byteIndex) ->
// if byteIndex == 1 then
// "a"
// else
// "b"
// _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("a".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_from_utf8_fail_surrogate_half() {
// assert_evals_to!(
// indoc!(
// r#"
// when Str.fromUtf8 [ 97, 98, 0xED, 0xA0, 0x80 ] is
// Err (BadUtf8 EncodesSurrogateHalf byteIndex) ->
// if byteIndex == 2 then
// "a"
// else
// "b"
// _ -> ""
// "#
// ),
// roc_std::RocStr::from_slice("a".as_bytes()),
// roc_std::RocStr
// );
// }
// #[test]
// fn str_equality() {
// assert_evals_to!(r#""a" == "a""#, true, bool);
// assert_evals_to!(
// r#""loremipsumdolarsitamet" == "loremipsumdolarsitamet""#,
// true,
// bool
// );
// assert_evals_to!(r#""a" != "b""#, true, bool);
// assert_evals_to!(r#""a" == "b""#, false, bool);
// }
// #[test]
// fn str_clone() {
// use roc_std::RocStr;
// let long = RocStr::from_slice("loremipsumdolarsitamet".as_bytes());
// let short = RocStr::from_slice("x".as_bytes());
// let empty = RocStr::from_slice("".as_bytes());
// debug_assert_eq!(long.clone(), long);
// debug_assert_eq!(short.clone(), short);
// debug_assert_eq!(empty.clone(), empty);
// }
// #[test]
// fn nested_recursive_literal() {
// assert_evals_to!(
// indoc!(
// r#"
// Expr : [ Add Expr Expr, Val I64, Var I64 ]
// expr : Expr
// expr = Add (Add (Val 3) (Val 1)) (Add (Val 1) (Var 1))
// printExpr : Expr -> Str
// printExpr = \e ->
// when e is
// Add a b ->
// "Add ("
// |> Str.concat (printExpr a)
// |> Str.concat ") ("
// |> Str.concat (printExpr b)
// |> Str.concat ")"
// Val v -> "Val " |> Str.concat (Str.fromInt v)
// Var v -> "Var " |> Str.concat (Str.fromInt v)
// printExpr expr
// "#
// ),
// RocStr::from_slice(b"Add (Add (Val 3) (Val 1)) (Add (Val 1) (Var 1))"),
// RocStr
// );
// }
// #[test]
// fn str_join_comma_small() {
// assert_evals_to!(
// r#"Str.joinWith ["1", "2"] ", " "#,
// RocStr::from("1, 2"),
// RocStr
// );
// }
// #[test]
// fn str_join_comma_big() {
// assert_evals_to!(
// r#"Str.joinWith ["10000000", "2000000", "30000000"] ", " "#,
// RocStr::from("10000000, 2000000, 30000000"),
// RocStr
// );
// }
// #[test]
// fn str_join_comma_single() {
// assert_evals_to!(r#"Str.joinWith ["1"] ", " "#, RocStr::from("1"), RocStr);
// }
// #[test]
// fn str_from_float() {
// assert_evals_to!(r#"Str.fromFloat 3.14"#, RocStr::from("3.14"), RocStr);
// }
// #[test]
// fn str_to_utf8() {
// assert_evals_to!(
// r#"Str.toUtf8 "hello""#,
// RocList::from_slice(&[104, 101, 108, 108, 111]),
// RocList<u8>
// );
// assert_evals_to!(
// r#"Str.toUtf8 "this is a long string""#,
// RocList::from_slice(&[
// 116, 104, 105, 115, 32, 105, 115, 32, 97, 32, 108, 111, 110, 103, 32, 115, 116,
// 114, 105, 110, 103
// ]),
// RocList<u8>
// );
// }
// #[test]
// fn str_from_utf8_range() {
// assert_evals_to!(
// indoc!(
// r#"
// bytes = Str.toUtf8 "hello"
// when Str.fromUtf8Range bytes { count: 5, start: 0 } is
// Ok utf8String -> utf8String
// _ -> ""
// "#
// ),
// RocStr::from("hello"),
// RocStr
// );
// }
// #[test]
// fn str_from_utf8_range_slice() {
// assert_evals_to!(
// indoc!(
// r#"
// bytes = Str.toUtf8 "hello"
// when Str.fromUtf8Range bytes { count: 4, start: 1 } is
// Ok utf8String -> utf8String
// _ -> ""
// "#
// ),
// RocStr::from("ello"),
// RocStr
// );
// }
// #[test]
// fn str_from_utf8_range_slice_not_end() {
// assert_evals_to!(
// indoc!(
// r#"
// bytes = Str.toUtf8 "hello"
// when Str.fromUtf8Range bytes { count: 3, start: 1 } is
// Ok utf8String -> utf8String
// _ -> ""
// "#
// ),
// RocStr::from("ell"),
// RocStr
// );
// }
// #[test]
// fn str_from_utf8_range_order_does_not_matter() {
// assert_evals_to!(
// indoc!(
// r#"
// bytes = Str.toUtf8 "hello"
// when Str.fromUtf8Range bytes { start: 1, count: 3 } is
// Ok utf8String -> utf8String
// _ -> ""
// "#
// ),
// RocStr::from("ell"),
// RocStr
// );
// }
// #[test]
// fn str_from_utf8_range_out_of_bounds_start_value() {
// assert_evals_to!(
// indoc!(
// r#"
// bytes = Str.toUtf8 "hello"
// when Str.fromUtf8Range bytes { start: 7, count: 3 } is
// Ok _ -> ""
// Err (BadUtf8 _ _) -> ""
// Err OutOfBounds -> "out of bounds"
// "#
// ),
// RocStr::from("out of bounds"),
// RocStr
// );
// }
// #[test]
// fn str_from_utf8_range_count_too_high() {
// assert_evals_to!(
// indoc!(
// r#"
// bytes = Str.toUtf8 "hello"
// when Str.fromUtf8Range bytes { start: 0, count: 6 } is
// Ok _ -> ""
// Err (BadUtf8 _ _) -> ""
// Err OutOfBounds -> "out of bounds"
// "#
// ),
// RocStr::from("out of bounds"),
// RocStr
// );
// }
// #[test]
// fn str_from_utf8_range_count_too_high_for_start() {
// assert_evals_to!(
// indoc!(
// r#"
// bytes = Str.toUtf8 "hello"
// when Str.fromUtf8Range bytes { start: 4, count: 3 } is
// Ok _ -> ""
// Err (BadUtf8 _ _) -> ""
// Err OutOfBounds -> "out of bounds"
// "#
// ),
// RocStr::from("out of bounds"),
// RocStr
// );
// }

View file

@ -1,44 +0,0 @@
extern crate bumpalo;
#[macro_use]
pub mod eval;
/// Used in the with_larger_debug_stack() function, for tests that otherwise
/// run out of stack space in debug builds (but don't in --release builds)
#[allow(dead_code)]
const EXPANDED_STACK_SIZE: usize = 8 * 1024 * 1024;
/// Without this, some tests pass in `cargo test --release` but fail without
/// the --release flag because they run out of stack space. This increases
/// stack size for debug builds only, while leaving the stack space at the default
/// amount for release builds.
#[allow(dead_code)]
#[cfg(debug_assertions)]
pub fn with_larger_debug_stack<F>(run_test: F)
where
F: FnOnce(),
F: Send,
F: 'static,
{
std::thread::Builder::new()
.stack_size(EXPANDED_STACK_SIZE)
.spawn(run_test)
.expect("Error while spawning expanded dev stack size thread")
.join()
.expect("Error while joining expanded dev stack size thread")
}
/// In --release builds, don't increase the stack size. Run the test normally.
/// This way, we find out if any of our tests are blowing the stack even after
/// optimizations in release builds.
#[allow(dead_code)]
#[cfg(not(debug_assertions))]
#[inline(always)]
pub fn with_larger_debug_stack<F>(run_test: F)
where
F: FnOnce() -> (),
F: Send,
F: 'static,
{
run_test()
}

View file

@ -1,4 +0,0 @@
pub mod dev_num;
pub mod dev_records;
pub mod dev_str;
mod helpers;

View file

@ -5,8 +5,14 @@ authors = ["The Roc Contributors"]
license = "UPL-1.0" license = "UPL-1.0"
edition = "2018" edition = "2018"
[dependencies] [[test]]
name = "test_gen"
path = "src/tests.rs"
[dev-dependencies]
roc_gen_llvm = { path = "../gen_llvm" } roc_gen_llvm = { path = "../gen_llvm" }
roc_gen_dev = { path = "../gen_dev" }
roc_gen_wasm = { path = "../gen_wasm" }
roc_collections = { path = "../collections" } roc_collections = { path = "../collections" }
roc_region = { path = "../region" } roc_region = { path = "../region" }
roc_module = { path = "../module" } roc_module = { path = "../module" }
@ -23,7 +29,6 @@ roc_can = { path = "../can" }
roc_parse = { path = "../parse" } roc_parse = { path = "../parse" }
roc_build = { path = "../build" } roc_build = { path = "../build" }
roc_std = { path = "../../roc_std" } roc_std = { path = "../../roc_std" }
test_wasm = { path = "../test_wasm" }
im = "15.0.0" im = "15.0.0"
im-rc = "15.0.0" im-rc = "15.0.0"
bumpalo = { version = "3.8.0", features = ["collections"] } bumpalo = { version = "3.8.0", features = ["collections"] }
@ -35,11 +40,11 @@ libloading = "0.7.1"
wasmer = { version = "2.0.0", default-features = false, features = ["default-cranelift", "default-universal"] } wasmer = { version = "2.0.0", default-features = false, features = ["default-cranelift", "default-universal"] }
wasmer-wasi = "2.0.0" wasmer-wasi = "2.0.0"
tempfile = "3.2.0" tempfile = "3.2.0"
[dev-dependencies]
bumpalo = { version = "3.8.0", features = ["collections"] }
indoc = "1.0.3" indoc = "1.0.3"
[features] [features]
default = [] default = ["gen-llvm"]
gen-llvm = []
gen-dev = []
gen-wasm = []
wasm-cli-run = [] wasm-cli-run = []

View file

@ -0,0 +1,28 @@
# Running our CodeGen tests
Our code generation tests are all in this crate. Feature flags are used to run the tests with a specific backend. For convenience, some aliases are added in `.cargo/config`:
```toml
[alias]
test-gen-llvm = "test -p test_gen"
test-gen-dev = "test -p test_gen --no-default-features --features gen-dev"
test-gen-wasm = "test -p test_gen --no-default-features --features gen-wasm"
```
So we can run:
```
cargo test-gen-llvm
```
To run the gen tests with the LLVM backend. To filter tests, append a filter like so:
```
> cargo test-gen-wasm wasm_str::small
Finished test [unoptimized + debuginfo] target(s) in 0.13s
Running src/tests.rs (target/debug/deps/test_gen-b4ad63a9dd50f050)
running 2 tests
test wasm_str::small_str_literal ... ok
test wasm_str::small_str_zeroed_literal ... ok
```

View file

@ -1,196 +1,218 @@
#[cfg(test)] #![cfg(not(feature = "gen-wasm"))]
mod gen_compare {
use crate::assert_evals_to;
// use crate::assert_wasm_evals_to as assert_evals_to;
use indoc::indoc;
#[test] #[cfg(feature = "gen-llvm")]
fn eq_i64() { use crate::helpers::llvm::assert_evals_to;
assert_evals_to!(
indoc!( #[cfg(feature = "gen-dev")]
r#" use crate::helpers::dev::assert_evals_to;
// #[cfg(feature = "gen-wasm")]
// use crate::helpers::wasm::assert_evals_to;
// use crate::assert_wasm_evals_to as assert_evals_to;
use indoc::indoc;
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn eq_i64() {
assert_evals_to!(
indoc!(
r#"
i : I64 i : I64
i = 1 i = 1
i == i i == i
"# "#
), ),
true, true,
bool bool
); );
} }
#[test] #[test]
fn neq_i64() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn neq_i64() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
i : I64 i : I64
i = 1 i = 1
i != i i != i
"# "#
), ),
false, false,
bool bool
); );
} }
#[test] #[test]
fn eq_u64() { #[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
assert_evals_to!( fn eq_u64() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
i : U64 i : U64
i = 1 i = 1
i == i i == i
"# "#
), ),
true, true,
bool bool
); );
} }
#[test] #[test]
fn neq_u64() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn neq_u64() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
i : U64 i : U64
i = 1 i = 1
i != i i != i
"# "#
), ),
false, false,
bool bool
); );
} }
#[test] #[test]
fn eq_f64() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn eq_f64() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
i : F64 i : F64
i = 1 i = 1
i == i i == i
"# "#
), ),
true, true,
bool bool
); );
} }
#[test] #[test]
fn neq_f64() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn neq_f64() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
i : F64 i : F64
i = 1 i = 1
i != i i != i
"# "#
), ),
false, false,
bool bool
); );
} }
#[test] #[test]
fn eq_bool_tag() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn eq_bool_tag() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
true : Bool true : Bool
true = True true = True
true == True true == True
"# "#
), ),
true, true,
bool bool
); );
} }
#[test] #[test]
fn neq_bool_tag() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn neq_bool_tag() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
true : Bool true : Bool
true = True true = True
true == False true == False
"# "#
), ),
false, false,
bool bool
); );
} }
#[test] #[test]
fn empty_record() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!("{} == {}", true, bool); fn empty_record() {
assert_evals_to!("{} != {}", false, bool); assert_evals_to!("{} == {}", true, bool);
} assert_evals_to!("{} != {}", false, bool);
}
#[test] #[test]
fn unit() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!("Unit == Unit", true, bool); fn unit() {
assert_evals_to!("Unit != Unit", false, bool); assert_evals_to!("Unit == Unit", true, bool);
} assert_evals_to!("Unit != Unit", false, bool);
}
#[test] #[test]
fn newtype() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!("Identity 42 == Identity 42", true, bool); fn newtype() {
assert_evals_to!("Identity 42 != Identity 42", false, bool); assert_evals_to!("Identity 42 == Identity 42", true, bool);
} assert_evals_to!("Identity 42 != Identity 42", false, bool);
}
#[test] #[test]
fn small_str() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!("\"aaa\" == \"aaa\"", true, bool); fn small_str() {
assert_evals_to!("\"aaa\" == \"bbb\"", false, bool); assert_evals_to!("\"aaa\" == \"aaa\"", true, bool);
assert_evals_to!("\"aaa\" != \"aaa\"", false, bool); assert_evals_to!("\"aaa\" == \"bbb\"", false, bool);
} assert_evals_to!("\"aaa\" != \"aaa\"", false, bool);
}
#[test] #[test]
fn large_str() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn large_str() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
x = "Unicode can represent text values which span multiple languages" x = "Unicode can represent text values which span multiple languages"
y = "Unicode can represent text values which span multiple languages" y = "Unicode can represent text values which span multiple languages"
x == y x == y
"# "#
), ),
true, true,
bool bool
); );
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r#"
x = "Unicode can represent text values which span multiple languages" x = "Unicode can represent text values which span multiple languages"
y = "Here are some valid Roc strings" y = "Here are some valid Roc strings"
x != y x != y
"# "#
), ),
true, true,
bool bool
); );
} }
#[test] #[test]
fn eq_result_tag_true() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn eq_result_tag_true() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
x : Result I64 I64 x : Result I64 I64
x = Ok 1 x = Ok 1
@ -199,17 +221,18 @@ mod gen_compare {
x == y x == y
"# "#
), ),
true, true,
bool bool
); );
} }
#[test] #[test]
fn eq_result_tag_false() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn eq_result_tag_false() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
x : Result I64 I64 x : Result I64 I64
x = Ok 1 x = Ok 1
@ -218,17 +241,18 @@ mod gen_compare {
x == y x == y
"# "#
), ),
false, false,
bool bool
); );
} }
#[test] #[test]
fn eq_expr() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn eq_expr() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
Expr : [ Add Expr Expr, Mul Expr Expr, Val I64, Var I64 ] Expr : [ Add Expr Expr, Mul Expr Expr, Val I64, Var I64 ]
x : Expr x : Expr
@ -239,17 +263,18 @@ mod gen_compare {
x == y x == y
"# "#
), ),
true, true,
bool bool
); );
} }
#[test] #[test]
fn eq_linked_list() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn eq_linked_list() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
LinkedList a : [ Nil, Cons a (LinkedList a) ] LinkedList a : [ Nil, Cons a (LinkedList a) ]
x : LinkedList I64 x : LinkedList I64
@ -260,14 +285,14 @@ mod gen_compare {
x == y x == y
"# "#
), ),
true, true,
bool bool
); );
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r#"
LinkedList a : [ Nil, Cons a (LinkedList a) ] LinkedList a : [ Nil, Cons a (LinkedList a) ]
x : LinkedList I64 x : LinkedList I64
@ -278,14 +303,14 @@ mod gen_compare {
x == y x == y
"# "#
), ),
true, true,
bool bool
); );
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r#"
LinkedList a : [ Nil, Cons a (LinkedList a) ] LinkedList a : [ Nil, Cons a (LinkedList a) ]
x : LinkedList I64 x : LinkedList I64
@ -296,17 +321,18 @@ mod gen_compare {
x == y x == y
"# "#
), ),
true, true,
bool bool
); );
} }
#[test] #[test]
fn eq_linked_list_false() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn eq_linked_list_false() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
LinkedList a : [ Nil, Cons a (LinkedList a) ] LinkedList a : [ Nil, Cons a (LinkedList a) ]
x : LinkedList I64 x : LinkedList I64
@ -317,17 +343,18 @@ mod gen_compare {
y == x y == x
"# "#
), ),
false, false,
bool bool
); );
} }
#[test] #[test]
fn eq_nullable_expr() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn eq_nullable_expr() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
Expr : [ Add Expr Expr, Mul Expr Expr, Val I64, Empty ] Expr : [ Add Expr Expr, Mul Expr Expr, Val I64, Empty ]
x : Expr x : Expr
@ -338,17 +365,18 @@ mod gen_compare {
x != y x != y
"# "#
), ),
true, true,
bool bool
); );
} }
#[test] #[test]
fn eq_rosetree() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn eq_rosetree() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
Rose a : [ Rose (List (Rose a)) ] Rose a : [ Rose (List (Rose a)) ]
x : Rose I64 x : Rose I64
@ -359,14 +387,14 @@ mod gen_compare {
x == y x == y
"# "#
), ),
true, true,
bool bool
); );
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r#"
Rose a : [ Rose (List (Rose a)) ] Rose a : [ Rose (List (Rose a)) ]
x : Rose I64 x : Rose I64
@ -377,20 +405,21 @@ mod gen_compare {
x != y x != y
"# "#
), ),
false, false,
bool bool
); );
} }
#[test] #[test]
#[ignore] #[cfg(any(feature = "gen-llvm"))]
fn rosetree_with_tag() { #[ignore]
// currently stack overflows in type checking fn rosetree_with_tag() {
// currently stack overflows in type checking
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
r#" r#"
Rose a : [ Rose (Result (List (Rose a)) I64) ] Rose a : [ Rose (Result (List (Rose a)) I64) ]
x : Rose I64 x : Rose I64
@ -401,53 +430,60 @@ mod gen_compare {
x == y x == y
"# "#
), ),
true, true,
bool bool
); );
} }
#[test] #[test]
fn list_eq_empty() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!("[] == []", true, bool); fn list_eq_empty() {
assert_evals_to!("[] != []", false, bool); assert_evals_to!("[] == []", true, bool);
} assert_evals_to!("[] != []", false, bool);
}
#[test] #[test]
fn list_eq_by_length() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!("[1] == []", false, bool); fn list_eq_by_length() {
assert_evals_to!("[] == [1]", false, bool); assert_evals_to!("[1] == []", false, bool);
} assert_evals_to!("[] == [1]", false, bool);
}
#[test] #[test]
fn list_eq_compare_pointwise() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!("[1] == [1]", true, bool); fn list_eq_compare_pointwise() {
assert_evals_to!("[2] == [1]", false, bool); assert_evals_to!("[1] == [1]", true, bool);
} assert_evals_to!("[2] == [1]", false, bool);
}
#[test] #[test]
fn list_eq_nested() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!("[[1]] == [[1]]", true, bool); fn list_eq_nested() {
assert_evals_to!("[[2]] == [[1]]", false, bool); assert_evals_to!("[[1]] == [[1]]", true, bool);
} assert_evals_to!("[[2]] == [[1]]", false, bool);
}
#[test] #[test]
fn list_neq_compare_pointwise() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!("[1] != [1]", false, bool); fn list_neq_compare_pointwise() {
assert_evals_to!("[2] != [1]", true, bool); assert_evals_to!("[1] != [1]", false, bool);
} assert_evals_to!("[2] != [1]", true, bool);
}
#[test] #[test]
fn list_neq_nested() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!("[[1]] != [[1]]", false, bool); fn list_neq_nested() {
assert_evals_to!("[[2]] != [[1]]", true, bool); assert_evals_to!("[[1]] != [[1]]", false, bool);
} assert_evals_to!("[[2]] != [[1]]", true, bool);
}
#[test] #[test]
fn compare_union_same_content() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn compare_union_same_content() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
Foo : [ A I64, B I64 ] Foo : [ A I64, B I64 ]
a : Foo a : Foo
@ -458,17 +494,18 @@ mod gen_compare {
a == b a == b
"# "#
), ),
false, false,
bool bool
); );
} }
#[test] #[test]
fn compare_recursive_union_same_content() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn compare_recursive_union_same_content() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
Expr : [ Add Expr Expr, Mul Expr Expr, Val1 I64, Val2 I64 ] Expr : [ Add Expr Expr, Mul Expr Expr, Val1 I64, Val2 I64 ]
v1 : Expr v1 : Expr
@ -479,17 +516,18 @@ mod gen_compare {
v1 == v2 v1 == v2
"# "#
), ),
false, false,
bool bool
); );
} }
#[test] #[test]
fn compare_nullable_recursive_union_same_content() { #[cfg(any(feature = "gen-llvm"))]
assert_evals_to!( fn compare_nullable_recursive_union_same_content() {
indoc!( assert_evals_to!(
r#" indoc!(
r#"
Expr : [ Add Expr Expr, Mul Expr Expr, Val1 I64, Val2 I64, Empty ] Expr : [ Add Expr Expr, Mul Expr Expr, Val1 I64, Val2 I64, Empty ]
v1 : Expr v1 : Expr
@ -500,9 +538,8 @@ mod gen_compare {
v1 == v2 v1 == v2
"# "#
), ),
false, false,
bool bool
); );
}
} }

View file

@ -1,10 +1,19 @@
#![cfg(test)] #![cfg(feature = "gen-llvm")]
#[cfg(feature = "gen-llvm")]
use crate::helpers::llvm::assert_evals_to;
// #[cfg(feature = "gen-dev")]
// use crate::helpers::dev::assert_evals_to;
// #[cfg(feature = "gen-wasm")]
// use crate::helpers::wasm::assert_evals_to;
use crate::assert_evals_to;
use indoc::indoc; use indoc::indoc;
use roc_std::{RocList, RocStr}; use roc_std::{RocList, RocStr};
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn dict_empty_len() { fn dict_empty_len() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -18,6 +27,7 @@ fn dict_empty_len() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn dict_insert_empty() { fn dict_insert_empty() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -32,6 +42,7 @@ fn dict_insert_empty() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn dict_empty_contains() { fn dict_empty_contains() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -48,6 +59,7 @@ fn dict_empty_contains() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn dict_nonempty_contains() { fn dict_nonempty_contains() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -64,6 +76,7 @@ fn dict_nonempty_contains() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn dict_empty_remove() { fn dict_empty_remove() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -82,6 +95,7 @@ fn dict_empty_remove() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn dict_nonempty_remove() { fn dict_nonempty_remove() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -100,6 +114,7 @@ fn dict_nonempty_remove() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn dict_nonempty_get() { fn dict_nonempty_get() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -142,6 +157,7 @@ fn dict_nonempty_get() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn keys() { fn keys() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -163,6 +179,7 @@ fn keys() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn values() { fn values() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -184,6 +201,7 @@ fn values() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn from_list_with_fold() { fn from_list_with_fold() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -226,6 +244,7 @@ fn from_list_with_fold() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn small_str_keys() { fn small_str_keys() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -247,6 +266,7 @@ fn small_str_keys() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn big_str_keys() { fn big_str_keys() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -272,6 +292,7 @@ fn big_str_keys() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn big_str_values() { fn big_str_values() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -296,6 +317,7 @@ fn big_str_values() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn unit_values() { fn unit_values() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -317,6 +339,7 @@ fn unit_values() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn single() { fn single() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -334,6 +357,7 @@ fn single() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn union() { fn union() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -351,6 +375,7 @@ fn union() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn union_prefer_first() { fn union_prefer_first() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -368,6 +393,7 @@ fn union_prefer_first() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn intersection() { fn intersection() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -398,6 +424,7 @@ fn intersection() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn intersection_prefer_first() { fn intersection_prefer_first() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -428,6 +455,7 @@ fn intersection_prefer_first() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn difference() { fn difference() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -458,6 +486,7 @@ fn difference() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn difference_prefer_first() { fn difference_prefer_first() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -488,6 +517,7 @@ fn difference_prefer_first() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn walk_sum_keys() { fn walk_sum_keys() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(

View file

@ -1,218 +0,0 @@
#![cfg(test)]
use crate::assert_evals_to;
// use crate::assert_wasm_evals_to as assert_evals_to;
use indoc::indoc;
#[test]
fn basic_hash() {
assert_evals_to!(
indoc!(
r#"
Dict.hashTestOnly 0 0
"#
),
9718519427346233646,
u64
);
}
#[test]
fn hash_str_with_seed() {
assert_evals_to!("Dict.hashTestOnly 1 \"a\"", 0xbed235177f41d328, u64);
assert_evals_to!("Dict.hashTestOnly 2 \"abc\"", 0xbe348debe59b27c3, u64);
}
#[test]
fn hash_record() {
assert_evals_to!("Dict.hashTestOnly 1 { x: \"a\" } ", 0xbed235177f41d328, u64);
assert_evals_to!(
"Dict.hashTestOnly 1 { x: 42, y: 3.14 } ",
5348189196103430707,
u64
);
}
#[test]
fn hash_result() {
assert_evals_to!(
"Dict.hashTestOnly 0 (List.get [ 0x1 ] 0) ",
2878521786781103245,
u64
);
}
#[test]
fn hash_linked_list() {
assert_evals_to!(
indoc!(
r#"
LinkedList a : [ Nil, Cons a (LinkedList a) ]
input : LinkedList I64
input = Nil
Dict.hashTestOnly 0 input
"#
),
0,
u64
);
assert_evals_to!(
indoc!(
r#"
LinkedList a : [ Nil, Cons a (LinkedList a) ]
input : LinkedList I64
input = Cons 4 (Cons 3 Nil)
Dict.hashTestOnly 0 input
"#
),
8287696503006938486,
u64
);
}
#[test]
fn hash_expr() {
assert_evals_to!(
indoc!(
r#"
Expr : [ Add Expr Expr, Mul Expr Expr, Val I64, Var I64 ]
x : Expr
x = Val 1
add : Expr
add = Add x x
Dict.hashTestOnly 0 add
"#
),
10825806964604997723,
u64
);
}
#[test]
fn hash_nullable_expr() {
assert_evals_to!(
indoc!(
r#"
Expr : [ Add Expr Expr, Mul Expr Expr, Val I64, Empty ]
x : Expr
x = Val 1
add : Expr
add = Add x x
Dict.hashTestOnly 0 add
"#
),
1907558799788307114,
u64
);
}
#[test]
fn hash_rosetree() {
assert_evals_to!(
indoc!(
r#"
Rose a : [ Rose (List (Rose a)) ]
x : Rose I64
x = Rose []
Dict.hashTestOnly 0 x
"#
),
0,
u64
);
}
#[test]
fn hash_union_same_content() {
assert_evals_to!(
indoc!(
r#"
Foo : [ A I64, B I64 ]
a : Foo
a = A 42
b : Foo
b = B 42
{ a: Dict.hashTestOnly 0 a, b : Dict.hashTestOnly 0 b }
"#
),
true,
(i64, i64),
|(a, b)| a != b
);
}
#[test]
fn hash_recursive_union_same_content() {
assert_evals_to!(
indoc!(
r#"
Expr : [ Add Expr Expr, Mul Expr Expr, Val1 I64, Val2 I64 ]
v1 : Expr
v1 = Val1 42
v2 : Expr
v2 = Val2 42
{ a: Dict.hashTestOnly 0 v1, b : Dict.hashTestOnly 0 v2 }
"#
),
true,
(i64, i64),
|(a, b)| a != b
);
}
#[test]
fn hash_nullable_recursive_union_same_content() {
assert_evals_to!(
indoc!(
r#"
Expr : [ Add Expr Expr, Mul Expr Expr, Val1 I64, Val2 I64, Empty ]
v1 : Expr
v1 = Val1 42
v2 : Expr
v2 = Val2 42
{ a: Dict.hashTestOnly 0 v1, b : Dict.hashTestOnly 0 v2 }
"#
),
true,
(i64, i64),
|(a, b)| a != b
);
}
#[test]
fn hash_list() {
assert_evals_to!(
indoc!(
r#"
x : List Str
x = [ "foo", "bar", "baz" ]
Dict.hashTestOnly 0 x
"#
),
10731521034618280801,
u64
);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,22 +1,42 @@
#![cfg(test)] #[cfg(feature = "gen-llvm")]
use crate::helpers::llvm::assert_evals_to;
#[cfg(feature = "gen-llvm")]
use crate::helpers::llvm::assert_llvm_evals_to;
#[cfg(feature = "gen-llvm")]
use crate::helpers::llvm::assert_non_opt_evals_to;
#[cfg(feature = "gen-dev")]
use crate::helpers::dev::assert_evals_to;
// #[cfg(feature = "gen-dev")]
// use crate::helpers::dev::assert_evals_to as assert_llvm_evals_to;
// #[cfg(feature = "gen-dev")]
// use crate::helpers::dev::assert_evals_to as assert_non_opt_evals_to;
#[cfg(feature = "gen-wasm")]
use crate::helpers::wasm::assert_evals_to;
// #[cfg(feature = "gen-wasm")]
// use crate::helpers::wasm::assert_evals_to as assert_llvm_evals_to;
// #[cfg(feature = "gen-wasm")]
// use crate::helpers::wasm::assert_evals_to as assert_non_opt_evals_to;
use crate::assert_evals_to;
use crate::assert_llvm_evals_to;
use crate::assert_non_opt_evals_to;
use indoc::indoc; use indoc::indoc;
#[allow(unused_imports)]
use roc_std::RocStr; use roc_std::RocStr;
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn basic_int() { fn basic_int() {
assert_evals_to!("123", 123, i64); assert_evals_to!("123", 123, i64);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn basic_float() { fn basic_float() {
assert_evals_to!("1234.0", 1234.0, f64); assert_evals_to!("1234.0", 1234.0, f64);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn branch_first_float() { fn branch_first_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -32,6 +52,7 @@ fn branch_first_float() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn branch_second_float() { fn branch_second_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -47,6 +68,7 @@ fn branch_second_float() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn branch_third_float() { fn branch_third_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -63,6 +85,7 @@ fn branch_third_float() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn branch_first_int() { fn branch_first_int() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -78,6 +101,7 @@ fn branch_first_int() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn branch_second_int() { fn branch_second_int() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -93,6 +117,7 @@ fn branch_second_int() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn branch_third_int() { fn branch_third_int() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -109,6 +134,7 @@ fn branch_third_int() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn branch_store_variable() { fn branch_store_variable() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -124,6 +150,7 @@ fn branch_store_variable() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn when_one_element_tag() { fn when_one_element_tag() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -141,6 +168,7 @@ fn when_one_element_tag() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn when_two_element_tag_first() { fn when_two_element_tag_first() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -159,6 +187,7 @@ fn when_two_element_tag_first() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn when_two_element_tag_second() { fn when_two_element_tag_second() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -177,6 +206,7 @@ fn when_two_element_tag_second() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn gen_when_one_branch() { fn gen_when_one_branch() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -191,6 +221,7 @@ fn gen_when_one_branch() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn gen_large_when_int() { fn gen_large_when_int() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -213,6 +244,7 @@ fn gen_large_when_int() {
} }
// #[test] // #[test]
// #[cfg(any(feature = "gen-llvm"))]
// fn gen_large_when_float() { // fn gen_large_when_float() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -235,6 +267,7 @@ fn gen_large_when_int() {
// } // }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn or_pattern() { fn or_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -250,6 +283,7 @@ fn or_pattern() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn apply_identity() { fn apply_identity() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -265,6 +299,7 @@ fn apply_identity() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn apply_unnamed_identity() { fn apply_unnamed_identity() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -281,6 +316,7 @@ fn apply_unnamed_identity() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn return_unnamed_fn() { fn return_unnamed_fn() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -301,6 +337,7 @@ fn return_unnamed_fn() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn gen_when_fn() { fn gen_when_fn() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -320,6 +357,7 @@ fn gen_when_fn() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn gen_basic_def() { fn gen_basic_def() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -347,6 +385,7 @@ fn gen_basic_def() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn gen_multiple_defs() { fn gen_multiple_defs() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -380,6 +419,7 @@ fn gen_multiple_defs() {
// These tests caught a bug in how Defs are converted to the mono IR // These tests caught a bug in how Defs are converted to the mono IR
// but they have UnusedDef or UnusedArgument problems, and don't run any more // but they have UnusedDef or UnusedArgument problems, and don't run any more
// #[test] // #[test]
// #[cfg(any(feature = "gen-llvm"))]
// fn gen_chained_defs() { // fn gen_chained_defs() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -399,6 +439,7 @@ fn gen_multiple_defs() {
// } // }
// //
// #[test] // #[test]
// #[cfg(any(feature = "gen-llvm"))]
// fn gen_nested_defs_old() { // fn gen_nested_defs_old() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -440,6 +481,7 @@ fn gen_multiple_defs() {
// } // }
// //
// #[test] // #[test]
// #[cfg(any(feature = "gen-llvm"))]
// fn let_x_in_x() { // fn let_x_in_x() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -462,6 +504,7 @@ fn gen_multiple_defs() {
// } // }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn factorial() { fn factorial() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -483,6 +526,7 @@ fn factorial() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn peano1() { fn peano1() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -503,6 +547,7 @@ fn peano1() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn peano2() { fn peano2() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -524,6 +569,7 @@ fn peano2() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn top_level_constant() { fn top_level_constant() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -542,6 +588,7 @@ fn top_level_constant() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_len_0() { fn linked_list_len_0() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -569,6 +616,7 @@ fn linked_list_len_0() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_len_twice_0() { fn linked_list_len_twice_0() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -596,6 +644,7 @@ fn linked_list_len_twice_0() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_len_1() { fn linked_list_len_1() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -623,6 +672,7 @@ fn linked_list_len_1() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_len_twice_1() { fn linked_list_len_twice_1() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -650,6 +700,7 @@ fn linked_list_len_twice_1() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_len_3() { fn linked_list_len_3() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -678,6 +729,7 @@ fn linked_list_len_3() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_sum_num_a() { fn linked_list_sum_num_a() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -706,6 +758,7 @@ fn linked_list_sum_num_a() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_sum_int() { fn linked_list_sum_int() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -733,6 +786,7 @@ fn linked_list_sum_int() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_map() { fn linked_list_map() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -766,6 +820,7 @@ fn linked_list_map() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn when_nested_maybe() { fn when_nested_maybe() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -822,6 +877,7 @@ fn when_nested_maybe() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn when_peano() { fn when_peano() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -879,6 +935,7 @@ fn when_peano() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[should_panic(expected = "Roc failed with message: ")] #[should_panic(expected = "Roc failed with message: ")]
fn overflow_frees_list() { fn overflow_frees_list() {
assert_evals_to!( assert_evals_to!(
@ -903,6 +960,7 @@ fn overflow_frees_list() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[should_panic(expected = "Roc failed with message: ")] #[should_panic(expected = "Roc failed with message: ")]
fn undefined_variable() { fn undefined_variable() {
assert_evals_to!( assert_evals_to!(
@ -920,6 +978,7 @@ fn undefined_variable() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[should_panic(expected = "Roc failed with message: ")] #[should_panic(expected = "Roc failed with message: ")]
fn annotation_without_body() { fn annotation_without_body() {
assert_evals_to!( assert_evals_to!(
@ -937,6 +996,7 @@ fn annotation_without_body() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn simple_closure() { fn simple_closure() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -958,6 +1018,7 @@ fn simple_closure() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn nested_closure() { fn nested_closure() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -981,6 +1042,7 @@ fn nested_closure() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn closure_in_list() { fn closure_in_list() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -1006,6 +1068,7 @@ fn closure_in_list() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn specialize_closure() { fn specialize_closure() {
use roc_std::RocList; use roc_std::RocList;
@ -1037,6 +1100,7 @@ fn specialize_closure() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn io_poc_effect() { fn io_poc_effect() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1067,6 +1131,7 @@ fn io_poc_effect() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn io_poc_desugared() { fn io_poc_desugared() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -1094,6 +1159,7 @@ fn io_poc_desugared() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn return_wrapped_function_pointer() { fn return_wrapped_function_pointer() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1116,6 +1182,7 @@ fn return_wrapped_function_pointer() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn return_wrapped_function_pointer_b() { fn return_wrapped_function_pointer_b() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1137,6 +1204,7 @@ fn return_wrapped_function_pointer_b() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn return_wrapped_closure() { fn return_wrapped_closure() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1162,6 +1230,7 @@ fn return_wrapped_closure() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_is_singleton() { fn linked_list_is_singleton() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1196,6 +1265,7 @@ fn linked_list_is_singleton() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_is_empty_1() { fn linked_list_is_empty_1() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1230,6 +1300,7 @@ fn linked_list_is_empty_1() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_is_empty_2() { fn linked_list_is_empty_2() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1261,6 +1332,7 @@ fn linked_list_is_empty_2() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_singleton() { fn linked_list_singleton() {
// verifies only that valid llvm is produced // verifies only that valid llvm is produced
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
@ -1281,6 +1353,7 @@ fn linked_list_singleton() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn recursive_function_with_rigid() { fn recursive_function_with_rigid() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1307,6 +1380,7 @@ fn recursive_function_with_rigid() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn rbtree_insert() { fn rbtree_insert() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1394,6 +1468,7 @@ fn rbtree_insert() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn rbtree_balance_3() { fn rbtree_balance_3() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1418,6 +1493,7 @@ fn rbtree_balance_3() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[ignore] #[ignore]
fn rbtree_layout_issue() { fn rbtree_layout_issue() {
// there is a flex var in here somewhere that blows up layout creation // there is a flex var in here somewhere that blows up layout creation
@ -1459,6 +1535,7 @@ fn rbtree_layout_issue() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[ignore] #[ignore]
fn rbtree_balance_mono_problem() { fn rbtree_balance_mono_problem() {
// because of how the function is written, only `Red` is used and so in the function's // because of how the function is written, only `Red` is used and so in the function's
@ -1512,6 +1589,7 @@ fn rbtree_balance_mono_problem() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn rbtree_balance_full() { fn rbtree_balance_full() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1563,6 +1641,7 @@ fn rbtree_balance_full() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn nested_pattern_match_two_ways() { fn nested_pattern_match_two_ways() {
// exposed an issue in the ordering of pattern match checks when ran with `--release` mode // exposed an issue in the ordering of pattern match checks when ran with `--release` mode
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
@ -1616,6 +1695,7 @@ fn nested_pattern_match_two_ways() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_guarded_double_pattern_match() { fn linked_list_guarded_double_pattern_match() {
// the important part here is that the first case (with the nested Cons) does not match // the important part here is that the first case (with the nested Cons) does not match
// TODO this also has undefined behavior // TODO this also has undefined behavior
@ -1647,6 +1727,7 @@ fn linked_list_guarded_double_pattern_match() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn linked_list_double_pattern_match() { fn linked_list_double_pattern_match() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1672,6 +1753,7 @@ fn linked_list_double_pattern_match() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn binary_tree_double_pattern_match() { fn binary_tree_double_pattern_match() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1697,6 +1779,7 @@ fn binary_tree_double_pattern_match() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn unified_empty_closure_bool() { fn unified_empty_closure_bool() {
// none of the Closure tags will have a payload // none of the Closure tags will have a payload
// this was not handled correctly in the past // this was not handled correctly in the past
@ -1721,6 +1804,7 @@ fn unified_empty_closure_bool() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn unified_empty_closure_byte() { fn unified_empty_closure_byte() {
// none of the Closure tags will have a payload // none of the Closure tags will have a payload
// this was not handled correctly in the past // this was not handled correctly in the past
@ -1746,6 +1830,7 @@ fn unified_empty_closure_byte() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn task_always_twice() { fn task_always_twice() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1790,6 +1875,7 @@ fn task_always_twice() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn wildcard_rigid() { fn wildcard_rigid() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
indoc!( indoc!(
@ -1819,6 +1905,7 @@ fn wildcard_rigid() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[ignore] #[ignore]
fn todo_bad_error_message() { fn todo_bad_error_message() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
@ -1866,6 +1953,7 @@ fn todo_bad_error_message() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn hof_conditional() { 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!(
@ -1882,6 +1970,7 @@ fn hof_conditional() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[should_panic( #[should_panic(
expected = "Roc failed with message: \"Shadowing { original_region: |L 3-3, C 4-5|, shadow: |L 6-6, C 8-9| Ident" expected = "Roc failed with message: \"Shadowing { original_region: |L 3-3, C 4-5|, shadow: |L 6-6, C 8-9| Ident"
)] )]
@ -1901,6 +1990,7 @@ fn pattern_shadowing() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[should_panic(expected = "TODO non-exhaustive pattern")] #[should_panic(expected = "TODO non-exhaustive pattern")]
fn non_exhaustive_pattern_let() { fn non_exhaustive_pattern_let() {
assert_evals_to!( assert_evals_to!(
@ -1920,6 +2010,7 @@ fn non_exhaustive_pattern_let() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[ignore] #[ignore]
#[should_panic(expected = "")] #[should_panic(expected = "")]
fn unsupported_pattern_str_interp() { fn unsupported_pattern_str_interp() {
@ -1937,6 +2028,7 @@ fn unsupported_pattern_str_interp() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[ignore] #[ignore]
fn fingertree_basic() { fn fingertree_basic() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
@ -1978,6 +2070,7 @@ fn fingertree_basic() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn case_or_pattern() { fn case_or_pattern() {
// the `0` branch body should only be generated once in the future // the `0` branch body should only be generated once in the future
// it is currently duplicated // it is currently duplicated
@ -1998,6 +2091,7 @@ fn case_or_pattern() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[ignore] #[ignore]
fn rosetree_basic() { fn rosetree_basic() {
assert_non_opt_evals_to!( assert_non_opt_evals_to!(
@ -2025,6 +2119,7 @@ fn rosetree_basic() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn case_jump() { fn case_jump() {
// the decision tree will generate a jump to the `1` branch here // the decision tree will generate a jump to the `1` branch here
assert_evals_to!( assert_evals_to!(
@ -2050,6 +2145,7 @@ fn case_jump() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn nullable_eval_cfold() { fn nullable_eval_cfold() {
// the decision tree will generate a jump to the `1` branch here // the decision tree will generate a jump to the `1` branch here
assert_evals_to!( assert_evals_to!(
@ -2086,6 +2182,7 @@ fn nullable_eval_cfold() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn nested_switch() { fn nested_switch() {
// exposed bug with passing the right symbol/layout down into switch branch generation // exposed bug with passing the right symbol/layout down into switch branch generation
assert_evals_to!( assert_evals_to!(
@ -2128,6 +2225,7 @@ fn nested_switch() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn count_deriv_x() { fn count_deriv_x() {
// exposed bug with basing the block_of_memory on a specific (smaller) tag layout // exposed bug with basing the block_of_memory on a specific (smaller) tag layout
assert_evals_to!( assert_evals_to!(
@ -2154,6 +2252,7 @@ fn count_deriv_x() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn deriv_pow() { fn deriv_pow() {
// exposed bug with ordering of variable declarations before switch // exposed bug with ordering of variable declarations before switch
assert_evals_to!( assert_evals_to!(
@ -2190,6 +2289,7 @@ fn deriv_pow() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn multiple_increment() { fn multiple_increment() {
// the `leaf` value will be incremented multiple times at once // the `leaf` value will be incremented multiple times at once
assert_evals_to!( assert_evals_to!(
@ -2223,6 +2323,7 @@ fn multiple_increment() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn switch_fuse_rc_non_exhaustive() { fn switch_fuse_rc_non_exhaustive() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2252,6 +2353,7 @@ fn switch_fuse_rc_non_exhaustive() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn switch_fuse_rc_exhaustive() { fn switch_fuse_rc_exhaustive() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2280,6 +2382,7 @@ fn switch_fuse_rc_exhaustive() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn build_then_apply_closure() { fn build_then_apply_closure() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2299,6 +2402,7 @@ fn build_then_apply_closure() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn expanded_result() { fn expanded_result() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2329,6 +2433,7 @@ fn expanded_result() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[ignore] #[ignore]
fn backpassing_result() { fn backpassing_result() {
assert_evals_to!( assert_evals_to!(
@ -2362,6 +2467,7 @@ fn backpassing_result() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
#[should_panic( #[should_panic(
expected = "Shadowing { original_region: |L 3-3, C 4-5|, shadow: |L 5-5, C 6-7| Ident" expected = "Shadowing { original_region: |L 3-3, C 4-5|, shadow: |L 5-5, C 6-7| Ident"
)] )]
@ -2380,6 +2486,7 @@ fn function_malformed_pattern() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[should_panic(expected = "Hit an erroneous type when creating a layout for")] #[should_panic(expected = "Hit an erroneous type when creating a layout for")]
fn call_invalid_layout() { fn call_invalid_layout() {
assert_llvm_evals_to!( assert_llvm_evals_to!(
@ -2399,6 +2506,7 @@ fn call_invalid_layout() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[should_panic(expected = "An expectation failed!")] #[should_panic(expected = "An expectation failed!")]
fn expect_fail() { fn expect_fail() {
assert_evals_to!( assert_evals_to!(
@ -2415,6 +2523,7 @@ fn expect_fail() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn increment_or_double_closure() { fn increment_or_double_closure() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2452,6 +2561,7 @@ fn increment_or_double_closure() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn module_thunk_is_function() { fn module_thunk_is_function() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2468,6 +2578,7 @@ fn module_thunk_is_function() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[should_panic(expected = "Roc failed with message: ")] #[should_panic(expected = "Roc failed with message: ")]
fn hit_unresolved_type_variable() { fn hit_unresolved_type_variable() {
assert_evals_to!( assert_evals_to!(
@ -2491,6 +2602,7 @@ fn hit_unresolved_type_variable() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn pattern_match_empty_record() { fn pattern_match_empty_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2510,6 +2622,7 @@ fn pattern_match_empty_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn pattern_match_unit_tag() { fn pattern_match_unit_tag() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2534,6 +2647,7 @@ fn pattern_match_unit_tag() {
// see for why this is disabled on wasm32 https://github.com/rtfeldman/roc/issues/1687 // see for why this is disabled on wasm32 https://github.com/rtfeldman/roc/issues/1687
#[cfg(not(feature = "wasm-cli-run"))] #[cfg(not(feature = "wasm-cli-run"))]
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn mirror_llvm_alignment_padding() { fn mirror_llvm_alignment_padding() {
// see https://github.com/rtfeldman/roc/issues/1569 // see https://github.com/rtfeldman/roc/issues/1569
assert_evals_to!( assert_evals_to!(
@ -2556,6 +2670,7 @@ fn mirror_llvm_alignment_padding() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn lambda_set_bool() { fn lambda_set_bool() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2580,6 +2695,7 @@ fn lambda_set_bool() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn lambda_set_byte() { fn lambda_set_byte() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2605,6 +2721,7 @@ fn lambda_set_byte() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn lambda_set_struct_byte() { fn lambda_set_struct_byte() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2632,6 +2749,7 @@ fn lambda_set_struct_byte() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn lambda_set_enum_byte_byte() { fn lambda_set_enum_byte_byte() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2662,6 +2780,7 @@ fn lambda_set_enum_byte_byte() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn list_walk_until() { fn list_walk_until() {
// see https://github.com/rtfeldman/roc/issues/1576 // see https://github.com/rtfeldman/roc/issues/1576
assert_evals_to!( assert_evals_to!(
@ -2687,6 +2806,7 @@ fn list_walk_until() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn int_literal_not_specialized_with_annotation() { fn int_literal_not_specialized_with_annotation() {
// see https://github.com/rtfeldman/roc/issues/1600 // see https://github.com/rtfeldman/roc/issues/1600
assert_evals_to!( assert_evals_to!(
@ -2714,6 +2834,7 @@ fn int_literal_not_specialized_with_annotation() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn int_literal_not_specialized_no_annotation() { fn int_literal_not_specialized_no_annotation() {
// see https://github.com/rtfeldman/roc/issues/1600 // see https://github.com/rtfeldman/roc/issues/1600
assert_evals_to!( assert_evals_to!(
@ -2740,6 +2861,7 @@ fn int_literal_not_specialized_no_annotation() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn unresolved_tvar_when_capture_is_unused() { fn unresolved_tvar_when_capture_is_unused() {
// see https://github.com/rtfeldman/roc/issues/1585 // see https://github.com/rtfeldman/roc/issues/1585
assert_evals_to!( assert_evals_to!(
@ -2766,6 +2888,7 @@ fn unresolved_tvar_when_capture_is_unused() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[should_panic(expected = "Roc failed with message: ")] #[should_panic(expected = "Roc failed with message: ")]
fn value_not_exposed_hits_panic() { fn value_not_exposed_hits_panic() {
assert_evals_to!( assert_evals_to!(
@ -2784,6 +2907,7 @@ fn value_not_exposed_hits_panic() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn mix_function_and_closure() { fn mix_function_and_closure() {
// see https://github.com/rtfeldman/roc/pull/1706 // see https://github.com/rtfeldman/roc/pull/1706
assert_evals_to!( assert_evals_to!(
@ -2809,6 +2933,7 @@ fn mix_function_and_closure() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn mix_function_and_closure_level_of_indirection() { fn mix_function_and_closure_level_of_indirection() {
// see https://github.com/rtfeldman/roc/pull/1706 // see https://github.com/rtfeldman/roc/pull/1706
assert_evals_to!( assert_evals_to!(
@ -2833,6 +2958,7 @@ fn mix_function_and_closure_level_of_indirection() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn do_pass_bool_byte_closure_layout() { fn do_pass_bool_byte_closure_layout() {
// see https://github.com/rtfeldman/roc/pull/1706 // see https://github.com/rtfeldman/roc/pull/1706
// the distinction is actually important, dropping that info means some functions just get // the distinction is actually important, dropping that info means some functions just get
@ -2908,6 +3034,7 @@ fn do_pass_bool_byte_closure_layout() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn nested_rigid_list() { fn nested_rigid_list() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2932,6 +3059,7 @@ fn nested_rigid_list() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn nested_rigid_alias() { fn nested_rigid_alias() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2958,6 +3086,7 @@ fn nested_rigid_alias() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn nested_rigid_tag_union() { fn nested_rigid_tag_union() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -2982,6 +3111,7 @@ fn nested_rigid_tag_union() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn call_that_needs_closure_parameter() { fn call_that_needs_closure_parameter() {
// here both p2 is lifted to the top-level, which means that `list` must be // here both p2 is lifted to the top-level, which means that `list` must be
// passed to it from `manyAux`. // passed to it from `manyAux`.

View file

@ -1,10 +1,17 @@
#![cfg(test)] #[cfg(feature = "gen-llvm")]
use crate::helpers::llvm::assert_evals_to;
#[cfg(feature = "gen-dev")]
use crate::helpers::dev::assert_evals_to;
#[cfg(feature = "gen-wasm")]
use crate::helpers::wasm::assert_evals_to;
use crate::assert_evals_to;
// use crate::assert_wasm_evals_to as assert_evals_to; // use crate::assert_wasm_evals_to as assert_evals_to;
use indoc::indoc; use indoc::indoc;
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn basic_record() { fn basic_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -38,6 +45,7 @@ fn basic_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn f64_record() { fn f64_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -77,6 +85,7 @@ fn f64_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn fn_record() { fn fn_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -128,6 +137,7 @@ fn fn_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn def_record() { fn def_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -167,6 +177,7 @@ fn def_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn when_on_record() { fn when_on_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -181,6 +192,7 @@ fn when_on_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn when_record_with_guard_pattern() { fn when_record_with_guard_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -195,6 +207,7 @@ fn when_record_with_guard_pattern() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn let_with_record_pattern() { fn let_with_record_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -210,6 +223,7 @@ fn let_with_record_pattern() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn record_guard_pattern() { fn record_guard_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -225,6 +239,7 @@ fn record_guard_pattern() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn twice_record_access() { fn twice_record_access() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -239,6 +254,7 @@ fn twice_record_access() {
); );
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-dev"))]
fn empty_record() { fn empty_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -253,6 +269,7 @@ fn empty_record() {
); );
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn i64_record2_literal() { fn i64_record2_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -266,6 +283,7 @@ fn i64_record2_literal() {
} }
// #[test] // #[test]
// #[cfg(any(feature = "gen-llvm"))]
// fn i64_record3_literal() { // fn i64_record3_literal() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -277,8 +295,8 @@ fn i64_record2_literal() {
// (i64, i64, i64) // (i64, i64, i64)
// ); // );
// } // }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn f64_record2_literal() { fn f64_record2_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -292,6 +310,7 @@ fn f64_record2_literal() {
} }
// #[test] // #[test]
// #[cfg(any(feature = "gen-llvm"))]
// fn f64_record3_literal() { // fn f64_record3_literal() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -305,6 +324,7 @@ fn f64_record2_literal() {
// } // }
// #[test] // #[test]
// #[cfg(any(feature = "gen-llvm"))]
// fn bool_record4_literal() { // fn bool_record4_literal() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -319,8 +339,8 @@ fn f64_record2_literal() {
// (bool, bool, bool, bool) // (bool, bool, bool, bool)
// ); // );
// } // }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn i64_record1_literal() { fn i64_record1_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -334,6 +354,7 @@ fn i64_record1_literal() {
} }
// #[test] // #[test]
// #[cfg(any(feature = "gen-llvm"))]
// fn i64_record9_literal() { // fn i64_record9_literal() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -347,6 +368,7 @@ fn i64_record1_literal() {
// } // }
// #[test] // #[test]
// #[cfg(any(feature = "gen-llvm"))]
// fn f64_record3_literal() { // fn f64_record3_literal() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -358,8 +380,8 @@ fn i64_record1_literal() {
// (f64, f64, f64) // (f64, f64, f64)
// ); // );
// } // }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn bool_literal() { fn bool_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -376,6 +398,7 @@ fn bool_literal() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn return_record() { fn return_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -392,6 +415,7 @@ fn return_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn optional_field_when_use_default() { fn optional_field_when_use_default() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -419,6 +443,7 @@ fn optional_field_when_use_default() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn optional_field_when_use_default_nested() { fn optional_field_when_use_default_nested() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -442,6 +467,7 @@ fn optional_field_when_use_default_nested() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn optional_field_when_no_use_default() { fn optional_field_when_no_use_default() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -462,6 +488,7 @@ fn optional_field_when_no_use_default() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn optional_field_when_no_use_default_nested() { fn optional_field_when_no_use_default_nested() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -479,6 +506,7 @@ fn optional_field_when_no_use_default_nested() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn optional_field_let_use_default() { fn optional_field_let_use_default() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -499,6 +527,7 @@ fn optional_field_let_use_default() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn optional_field_let_no_use_default() { fn optional_field_let_no_use_default() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -519,6 +548,7 @@ fn optional_field_let_no_use_default() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn optional_field_let_no_use_default_nested() { fn optional_field_let_no_use_default_nested() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -536,6 +566,7 @@ fn optional_field_let_no_use_default_nested() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn optional_field_function_use_default() { fn optional_field_function_use_default() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -552,6 +583,7 @@ fn optional_field_function_use_default() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[ignore] #[ignore]
fn optional_field_function_no_use_default() { fn optional_field_function_no_use_default() {
// blocked on https://github.com/rtfeldman/roc/issues/786 // blocked on https://github.com/rtfeldman/roc/issues/786
@ -572,6 +604,7 @@ fn optional_field_function_no_use_default() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[ignore] #[ignore]
fn optional_field_function_no_use_default_nested() { fn optional_field_function_no_use_default_nested() {
// blocked on https://github.com/rtfeldman/roc/issues/786 // blocked on https://github.com/rtfeldman/roc/issues/786
@ -590,6 +623,7 @@ fn optional_field_function_no_use_default_nested() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn optional_field_singleton_record() { fn optional_field_singleton_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -604,6 +638,7 @@ fn optional_field_singleton_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn optional_field_empty_record() { fn optional_field_empty_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -618,6 +653,7 @@ fn optional_field_empty_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn return_record_2() { fn return_record_2() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -631,6 +667,7 @@ fn return_record_2() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn return_record_3() { fn return_record_3() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -644,6 +681,7 @@ fn return_record_3() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn return_record_4() { fn return_record_4() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -657,6 +695,7 @@ fn return_record_4() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn return_record_5() { fn return_record_5() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -670,6 +709,7 @@ fn return_record_5() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn return_record_6() { fn return_record_6() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -683,6 +723,7 @@ fn return_record_6() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn return_record_7() { fn return_record_7() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -696,6 +737,7 @@ fn return_record_7() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn return_record_float_int() { fn return_record_float_int() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -709,6 +751,7 @@ fn return_record_float_int() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn return_record_int_float() { fn return_record_int_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -722,6 +765,7 @@ fn return_record_int_float() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn return_record_float_float() { fn return_record_float_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -735,6 +779,7 @@ fn return_record_float_float() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn return_record_float_float_float() { fn return_record_float_float_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -748,6 +793,7 @@ fn return_record_float_float_float() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn return_nested_record() { fn return_nested_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -761,11 +807,13 @@ fn return_nested_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn accessor_twice() { fn accessor_twice() {
assert_evals_to!(".foo { foo: 4 } + .foo { bar: 6.28, foo: 3 } ", 7, i64); assert_evals_to!(".foo { foo: 4 } + .foo { bar: 6.28, foo: 3 } ", 7, i64);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn accessor_multi_element_record() { fn accessor_multi_element_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -779,6 +827,7 @@ fn accessor_multi_element_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn accessor_single_element_record() { fn accessor_single_element_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -792,6 +841,7 @@ fn accessor_single_element_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn update_record() { fn update_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -807,6 +857,7 @@ fn update_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn update_single_element_record() { fn update_single_element_record() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -822,6 +873,7 @@ fn update_single_element_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn booleans_in_record() { fn booleans_in_record() {
assert_evals_to!( assert_evals_to!(
indoc!("{ x: 1 == 1, y: 1 == 1 }"), indoc!("{ x: 1 == 1, y: 1 == 1 }"),
@ -846,6 +898,7 @@ fn booleans_in_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn alignment_in_record() { fn alignment_in_record() {
assert_evals_to!( assert_evals_to!(
indoc!("{ c: 32, b: if True then Red else if True then Green else Blue, a: 1 == 1 }"), indoc!("{ c: 32, b: if True then Red else if True then Green else Blue, a: 1 == 1 }"),
@ -855,6 +908,7 @@ fn alignment_in_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn blue_and_present() { fn blue_and_present() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -873,6 +927,7 @@ fn blue_and_present() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn blue_and_absent() { fn blue_and_absent() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -891,6 +946,7 @@ fn blue_and_absent() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn update_the_only_field() { fn update_the_only_field() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(

View file

@ -1,9 +1,18 @@
#![cfg(test)] #![cfg(feature = "gen-llvm")]
#[cfg(feature = "gen-llvm")]
use crate::helpers::llvm::assert_evals_to;
// #[cfg(feature = "gen-dev")]
// use crate::helpers::dev::assert_evals_to;
// #[cfg(feature = "gen-wasm")]
// use crate::helpers::wasm::assert_evals_to;
use crate::assert_evals_to;
use indoc::indoc; use indoc::indoc;
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn with_default() { fn with_default() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -33,6 +42,7 @@ fn with_default() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn result_map() { fn result_map() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -66,6 +76,7 @@ fn result_map() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn result_map_err() { fn result_map_err() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -99,6 +110,7 @@ fn result_map_err() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn err_type_var() { fn err_type_var() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -113,6 +125,7 @@ fn err_type_var() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn err_type_var_annotation() { fn err_type_var_annotation() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -130,6 +143,7 @@ fn err_type_var_annotation() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn err_empty_tag_union() { fn err_empty_tag_union() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(

View file

@ -1,10 +1,19 @@
#![cfg(test)] #![cfg(feature = "gen-llvm")]
#[cfg(feature = "gen-llvm")]
use crate::helpers::llvm::assert_evals_to;
// #[cfg(feature = "gen-dev")]
// use crate::helpers::dev::assert_evals_to;
// #[cfg(feature = "gen-wasm")]
// use crate::helpers::wasm::assert_evals_to;
use crate::assert_evals_to;
use indoc::indoc; use indoc::indoc;
use roc_std::RocList; use roc_std::RocList;
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn empty_len() { fn empty_len() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -18,6 +27,7 @@ fn empty_len() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn single_len() { fn single_len() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -31,6 +41,7 @@ fn single_len() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn single_to_list() { fn single_to_list() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -64,6 +75,7 @@ fn single_to_list() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn insert() { fn insert() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -81,6 +93,7 @@ fn insert() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn remove() { fn remove() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -99,6 +112,7 @@ fn remove() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn union() { fn union() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -119,6 +133,7 @@ fn union() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn difference() { fn difference() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -139,6 +154,7 @@ fn difference() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn intersection() { fn intersection() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -159,6 +175,7 @@ fn intersection() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn walk_sum() { fn walk_sum() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -172,6 +189,7 @@ fn walk_sum() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn contains() { fn contains() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -195,6 +213,7 @@ fn contains() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn from_list() { fn from_list() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(

View file

@ -1,11 +1,22 @@
#![cfg(test)] #![cfg(not(feature = "gen-wasm"))]
use crate::assert_evals_to; #[cfg(feature = "gen-llvm")]
use crate::assert_llvm_evals_to; use crate::helpers::llvm::assert_evals_to;
#[cfg(feature = "gen-llvm")]
use crate::helpers::llvm::assert_llvm_evals_to;
#[cfg(feature = "gen-dev")]
use crate::helpers::dev::assert_evals_to;
#[cfg(feature = "gen-dev")]
use crate::helpers::dev::assert_evals_to as assert_llvm_evals_to;
#[allow(unused_imports)]
use indoc::indoc; use indoc::indoc;
#[allow(unused_imports)]
use roc_std::{RocList, RocStr}; use roc_std::{RocList, RocStr};
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_split_bigger_delimiter_small_str() { fn str_split_bigger_delimiter_small_str() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -35,6 +46,7 @@ fn str_split_bigger_delimiter_small_str() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_split_str_concat_repeated() { fn str_split_str_concat_repeated() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -58,6 +70,7 @@ fn str_split_str_concat_repeated() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_split_small_str_bigger_delimiter() { fn str_split_small_str_bigger_delimiter() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -76,6 +89,7 @@ fn str_split_small_str_bigger_delimiter() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_split_big_str_small_delimiter() { fn str_split_big_str_small_delimiter() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -105,6 +119,7 @@ fn str_split_big_str_small_delimiter() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_split_small_str_small_delimiter() { fn str_split_small_str_small_delimiter() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -122,6 +137,7 @@ fn str_split_small_str_small_delimiter() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_split_bigger_delimiter_big_strs() { fn str_split_bigger_delimiter_big_strs() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -137,6 +153,7 @@ fn str_split_bigger_delimiter_big_strs() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_split_empty_strs() { fn str_split_empty_strs() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -150,6 +167,7 @@ fn str_split_empty_strs() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_split_minimal_example() { fn str_split_minimal_example() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -163,6 +181,7 @@ fn str_split_minimal_example() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_split_small_str_big_delimiter() { fn str_split_small_str_big_delimiter() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -195,6 +214,7 @@ fn str_split_small_str_big_delimiter() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_split_small_str_20_char_delimiter() { fn str_split_small_str_20_char_delimiter() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -214,6 +234,7 @@ fn str_split_small_str_20_char_delimiter() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_concat_big_to_big() { fn str_concat_big_to_big() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -229,6 +250,7 @@ fn str_concat_big_to_big() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn small_str_literal() { fn small_str_literal() {
assert_llvm_evals_to!( assert_llvm_evals_to!(
"\"JJJJJJJJJJJJJJJ\"", "\"JJJJJJJJJJJJJJJ\"",
@ -255,6 +277,7 @@ fn small_str_literal() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn small_str_zeroed_literal() { fn small_str_zeroed_literal() {
// Verifies that we zero out unused bytes in the string. // Verifies that we zero out unused bytes in the string.
// This is important so that string equality tests don't randomly // This is important so that string equality tests don't randomly
@ -284,6 +307,7 @@ fn small_str_zeroed_literal() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn small_str_concat_empty_first_arg() { fn small_str_concat_empty_first_arg() {
assert_llvm_evals_to!( assert_llvm_evals_to!(
r#"Str.concat "" "JJJJJJJJJJJJJJJ""#, r#"Str.concat "" "JJJJJJJJJJJJJJJ""#,
@ -310,6 +334,7 @@ fn small_str_concat_empty_first_arg() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn small_str_concat_empty_second_arg() { fn small_str_concat_empty_second_arg() {
assert_llvm_evals_to!( assert_llvm_evals_to!(
r#"Str.concat "JJJJJJJJJJJJJJJ" """#, r#"Str.concat "JJJJJJJJJJJJJJJ" """#,
@ -336,6 +361,7 @@ fn small_str_concat_empty_second_arg() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn small_str_concat_small_to_big() { fn small_str_concat_small_to_big() {
assert_evals_to!( assert_evals_to!(
r#"Str.concat "abc" " this is longer than 15 chars""#, r#"Str.concat "abc" " this is longer than 15 chars""#,
@ -345,6 +371,7 @@ fn small_str_concat_small_to_big() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn small_str_concat_small_to_small_staying_small() { fn small_str_concat_small_to_small_staying_small() {
assert_llvm_evals_to!( assert_llvm_evals_to!(
r#"Str.concat "J" "JJJJJJJJJJJJJJ""#, r#"Str.concat "J" "JJJJJJJJJJJJJJ""#,
@ -371,6 +398,7 @@ fn small_str_concat_small_to_small_staying_small() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn small_str_concat_small_to_small_overflow_to_big() { fn small_str_concat_small_to_small_overflow_to_big() {
assert_evals_to!( assert_evals_to!(
r#"Str.concat "abcdefghijklm" "nopqrstuvwxyz""#, r#"Str.concat "abcdefghijklm" "nopqrstuvwxyz""#,
@ -380,16 +408,19 @@ fn small_str_concat_small_to_small_overflow_to_big() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn str_concat_empty() { fn str_concat_empty() {
assert_evals_to!(r#"Str.concat "" """#, RocStr::default(), RocStr); assert_evals_to!(r#"Str.concat "" """#, RocStr::default(), RocStr);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn small_str_is_empty() { fn small_str_is_empty() {
assert_evals_to!(r#"Str.isEmpty "abc""#, false, bool); assert_evals_to!(r#"Str.isEmpty "abc""#, false, bool);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn big_str_is_empty() { fn big_str_is_empty() {
assert_evals_to!( assert_evals_to!(
r#"Str.isEmpty "this is more than 15 chars long""#, r#"Str.isEmpty "this is more than 15 chars long""#,
@ -399,11 +430,13 @@ fn big_str_is_empty() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn empty_str_is_empty() { fn empty_str_is_empty() {
assert_evals_to!(r#"Str.isEmpty """#, true, bool); assert_evals_to!(r#"Str.isEmpty """#, true, bool);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_starts_with() { fn str_starts_with() {
assert_evals_to!(r#"Str.startsWith "hello world" "hell""#, true, bool); assert_evals_to!(r#"Str.startsWith "hello world" "hell""#, true, bool);
assert_evals_to!(r#"Str.startsWith "hello world" """#, true, bool); assert_evals_to!(r#"Str.startsWith "hello world" """#, true, bool);
@ -413,6 +446,7 @@ fn str_starts_with() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_starts_with_code_point() { fn str_starts_with_code_point() {
assert_evals_to!( assert_evals_to!(
&format!(r#"Str.startsWithCodePt "foobar" {}"#, 'f' as u32), &format!(r#"Str.startsWithCodePt "foobar" {}"#, 'f' as u32),
@ -427,6 +461,7 @@ fn str_starts_with_code_point() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_ends_with() { fn str_ends_with() {
assert_evals_to!(r#"Str.endsWith "hello world" "world""#, true, bool); assert_evals_to!(r#"Str.endsWith "hello world" "world""#, true, bool);
assert_evals_to!(r#"Str.endsWith "nope" "hello world""#, false, bool); assert_evals_to!(r#"Str.endsWith "nope" "hello world""#, false, bool);
@ -434,16 +469,19 @@ fn str_ends_with() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_count_graphemes_small_str() { fn str_count_graphemes_small_str() {
assert_evals_to!(r#"Str.countGraphemes "å🤔""#, 2, usize); assert_evals_to!(r#"Str.countGraphemes "å🤔""#, 2, usize);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_count_graphemes_three_js() { fn str_count_graphemes_three_js() {
assert_evals_to!(r#"Str.countGraphemes "JJJ""#, 3, usize); assert_evals_to!(r#"Str.countGraphemes "JJJ""#, 3, usize);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_count_graphemes_big_str() { fn str_count_graphemes_big_str() {
assert_evals_to!( assert_evals_to!(
r#"Str.countGraphemes "6🤔å🤔e¥🤔çppkd🙃1jdal🦯asdfa∆ltråø˚waia8918.,🏅jjc""#, r#"Str.countGraphemes "6🤔å🤔e¥🤔çppkd🙃1jdal🦯asdfa∆ltråø˚waia8918.,🏅jjc""#,
@ -453,6 +491,7 @@ fn str_count_graphemes_big_str() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_starts_with_same_big_str() { fn str_starts_with_same_big_str() {
assert_evals_to!( assert_evals_to!(
r#"Str.startsWith "123456789123456789" "123456789123456789""#, r#"Str.startsWith "123456789123456789" "123456789123456789""#,
@ -462,6 +501,7 @@ fn str_starts_with_same_big_str() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_starts_with_different_big_str() { fn str_starts_with_different_big_str() {
assert_evals_to!( assert_evals_to!(
r#"Str.startsWith "12345678912345678910" "123456789123456789""#, r#"Str.startsWith "12345678912345678910" "123456789123456789""#,
@ -471,20 +511,24 @@ fn str_starts_with_different_big_str() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_starts_with_same_small_str() { fn str_starts_with_same_small_str() {
assert_evals_to!(r#"Str.startsWith "1234" "1234""#, true, bool); assert_evals_to!(r#"Str.startsWith "1234" "1234""#, true, bool);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_starts_with_different_small_str() { fn str_starts_with_different_small_str() {
assert_evals_to!(r#"Str.startsWith "1234" "12""#, true, bool); assert_evals_to!(r#"Str.startsWith "1234" "12""#, true, bool);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_starts_with_false_small_str() { fn str_starts_with_false_small_str() {
assert_evals_to!(r#"Str.startsWith "1234" "23""#, false, bool); assert_evals_to!(r#"Str.startsWith "1234" "23""#, false, bool);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_int() { fn str_from_int() {
assert_evals_to!( assert_evals_to!(
r#"Str.fromInt 1234"#, r#"Str.fromInt 1234"#,
@ -518,6 +562,7 @@ fn str_from_int() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_pass_single_ascii() { fn str_from_utf8_pass_single_ascii() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -533,6 +578,7 @@ fn str_from_utf8_pass_single_ascii() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_pass_many_ascii() { fn str_from_utf8_pass_many_ascii() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -548,6 +594,7 @@ fn str_from_utf8_pass_many_ascii() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_pass_single_unicode() { fn str_from_utf8_pass_single_unicode() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -563,6 +610,7 @@ fn str_from_utf8_pass_single_unicode() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_pass_many_unicode() { fn str_from_utf8_pass_many_unicode() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -578,6 +626,7 @@ fn str_from_utf8_pass_many_unicode() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_pass_single_grapheme() { fn str_from_utf8_pass_single_grapheme() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -593,6 +642,7 @@ fn str_from_utf8_pass_single_grapheme() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_pass_many_grapheme() { fn str_from_utf8_pass_many_grapheme() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -608,6 +658,7 @@ fn str_from_utf8_pass_many_grapheme() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_pass_all() { fn str_from_utf8_pass_all() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -623,6 +674,7 @@ fn str_from_utf8_pass_all() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_fail_invalid_start_byte() { fn str_from_utf8_fail_invalid_start_byte() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -642,6 +694,7 @@ fn str_from_utf8_fail_invalid_start_byte() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_fail_unexpected_end_of_sequence() { fn str_from_utf8_fail_unexpected_end_of_sequence() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -661,6 +714,7 @@ fn str_from_utf8_fail_unexpected_end_of_sequence() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_fail_expected_continuation() { fn str_from_utf8_fail_expected_continuation() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -680,6 +734,7 @@ fn str_from_utf8_fail_expected_continuation() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_fail_overlong_encoding() { fn str_from_utf8_fail_overlong_encoding() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -699,6 +754,7 @@ fn str_from_utf8_fail_overlong_encoding() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_fail_codepoint_too_large() { fn str_from_utf8_fail_codepoint_too_large() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -718,6 +774,7 @@ fn str_from_utf8_fail_codepoint_too_large() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_fail_surrogate_half() { fn str_from_utf8_fail_surrogate_half() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -737,6 +794,7 @@ fn str_from_utf8_fail_surrogate_half() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_equality() { fn str_equality() {
assert_evals_to!(r#""a" == "a""#, true, bool); assert_evals_to!(r#""a" == "a""#, true, bool);
assert_evals_to!( assert_evals_to!(
@ -761,6 +819,7 @@ fn str_clone() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn nested_recursive_literal() { fn nested_recursive_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -791,6 +850,7 @@ fn nested_recursive_literal() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_join_comma_small() { fn str_join_comma_small() {
assert_evals_to!( assert_evals_to!(
r#"Str.joinWith ["1", "2"] ", " "#, r#"Str.joinWith ["1", "2"] ", " "#,
@ -800,6 +860,7 @@ fn str_join_comma_small() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_join_comma_big() { fn str_join_comma_big() {
assert_evals_to!( assert_evals_to!(
r#"Str.joinWith ["10000000", "2000000", "30000000"] ", " "#, r#"Str.joinWith ["10000000", "2000000", "30000000"] ", " "#,
@ -809,16 +870,19 @@ fn str_join_comma_big() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_join_comma_single() { fn str_join_comma_single() {
assert_evals_to!(r#"Str.joinWith ["1"] ", " "#, RocStr::from("1"), RocStr); assert_evals_to!(r#"Str.joinWith ["1"] ", " "#, RocStr::from("1"), RocStr);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_float() { fn str_from_float() {
assert_evals_to!(r#"Str.fromFloat 3.14"#, RocStr::from("3.14"), RocStr); assert_evals_to!(r#"Str.fromFloat 3.14"#, RocStr::from("3.14"), RocStr);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_to_utf8() { fn str_to_utf8() {
assert_evals_to!( assert_evals_to!(
r#"Str.toUtf8 "hello""#, r#"Str.toUtf8 "hello""#,
@ -836,6 +900,7 @@ fn str_to_utf8() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_range() { fn str_from_utf8_range() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -852,6 +917,7 @@ fn str_from_utf8_range() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_range_slice() { fn str_from_utf8_range_slice() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -868,6 +934,7 @@ fn str_from_utf8_range_slice() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_range_slice_not_end() { fn str_from_utf8_range_slice_not_end() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -884,6 +951,7 @@ fn str_from_utf8_range_slice_not_end() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_range_order_does_not_matter() { fn str_from_utf8_range_order_does_not_matter() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -900,6 +968,7 @@ fn str_from_utf8_range_order_does_not_matter() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_range_out_of_bounds_start_value() { fn str_from_utf8_range_out_of_bounds_start_value() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -917,6 +986,7 @@ fn str_from_utf8_range_out_of_bounds_start_value() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_range_count_too_high() { fn str_from_utf8_range_count_too_high() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -934,6 +1004,7 @@ fn str_from_utf8_range_count_too_high() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_from_utf8_range_count_too_high_for_start() { fn str_from_utf8_range_count_too_high_for_start() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -951,6 +1022,7 @@ fn str_from_utf8_range_count_too_high_for_start() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_repeat_small() { fn str_repeat_small() {
assert_evals_to!( assert_evals_to!(
indoc!(r#"Str.repeat "Roc" 3"#), indoc!(r#"Str.repeat "Roc" 3"#),
@ -960,6 +1032,7 @@ fn str_repeat_small() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_repeat_big() { fn str_repeat_big() {
assert_evals_to!( assert_evals_to!(
indoc!(r#"Str.repeat "more than 16 characters" 2"#), indoc!(r#"Str.repeat "more than 16 characters" 2"#),
@ -969,26 +1042,31 @@ fn str_repeat_big() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_repeat_empty_string() { fn str_repeat_empty_string() {
assert_evals_to!(indoc!(r#"Str.repeat "" 3"#), RocStr::from(""), RocStr); assert_evals_to!(indoc!(r#"Str.repeat "" 3"#), RocStr::from(""), RocStr);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_repeat_zero_times() { fn str_repeat_zero_times() {
assert_evals_to!(indoc!(r#"Str.repeat "Roc" 0"#), RocStr::from(""), RocStr); assert_evals_to!(indoc!(r#"Str.repeat "Roc" 0"#), RocStr::from(""), RocStr);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_trim_empty_string() { fn str_trim_empty_string() {
assert_evals_to!(indoc!(r#"Str.trim """#), RocStr::from(""), RocStr); assert_evals_to!(indoc!(r#"Str.trim """#), RocStr::from(""), RocStr);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_trim_small_blank_string() { fn str_trim_small_blank_string() {
assert_evals_to!(indoc!(r#"Str.trim " ""#), RocStr::from(""), RocStr); assert_evals_to!(indoc!(r#"Str.trim " ""#), RocStr::from(""), RocStr);
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_trim_small_to_small() { fn str_trim_small_to_small() {
assert_evals_to!( assert_evals_to!(
indoc!(r#"Str.trim " hello world ""#), indoc!(r#"Str.trim " hello world ""#),
@ -998,6 +1076,7 @@ fn str_trim_small_to_small() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_trim_large_to_large_unique() { fn str_trim_large_to_large_unique() {
assert_evals_to!( assert_evals_to!(
indoc!(r#"Str.trim (Str.concat " " "hello world from a large string ")"#), indoc!(r#"Str.trim (Str.concat " " "hello world from a large string ")"#),
@ -1007,6 +1086,7 @@ fn str_trim_large_to_large_unique() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_trim_large_to_small_unique() { fn str_trim_large_to_small_unique() {
assert_evals_to!( assert_evals_to!(
indoc!(r#"Str.trim (Str.concat " " "hello world ")"#), indoc!(r#"Str.trim (Str.concat " " "hello world ")"#),
@ -1016,6 +1096,7 @@ fn str_trim_large_to_small_unique() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_trim_large_to_large_shared() { fn str_trim_large_to_large_shared() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -1035,6 +1116,7 @@ fn str_trim_large_to_large_shared() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_trim_large_to_small_shared() { fn str_trim_large_to_small_shared() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -1054,6 +1136,7 @@ fn str_trim_large_to_small_shared() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn str_trim_small_to_small_shared() { fn str_trim_small_to_small_shared() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(

View file

@ -1,11 +1,20 @@
#![cfg(test)] #![cfg(feature = "gen-llvm")]
#[cfg(feature = "gen-llvm")]
use crate::helpers::llvm::assert_evals_to;
// #[cfg(feature = "gen-dev")]
// use crate::helpers::dev::assert_evals_to;
// #[cfg(feature = "gen-wasm")]
// use crate::helpers::wasm::assert_evals_to;
use crate::assert_evals_to;
// use crate::assert_wasm_evals_to as assert_evals_to; // use crate::assert_wasm_evals_to as assert_evals_to;
use indoc::indoc; use indoc::indoc;
use roc_std::{RocList, RocStr}; use roc_std::{RocList, RocStr};
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn width_and_alignment_u8_u8() { fn width_and_alignment_u8_u8() {
use roc_mono::layout::Builtin; use roc_mono::layout::Builtin;
use roc_mono::layout::Layout; use roc_mono::layout::Layout;
@ -23,6 +32,7 @@ fn width_and_alignment_u8_u8() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn applied_tag_nothing_ir() { fn applied_tag_nothing_ir() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -42,6 +52,7 @@ fn applied_tag_nothing_ir() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn applied_tag_nothing() { fn applied_tag_nothing() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -61,6 +72,7 @@ fn applied_tag_nothing() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn applied_tag_just() { fn applied_tag_just() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -79,6 +91,7 @@ fn applied_tag_just() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn applied_tag_just_ir() { fn applied_tag_just_ir() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -97,6 +110,7 @@ fn applied_tag_just_ir() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn applied_tag_just_enum() { fn applied_tag_just_enum() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -120,6 +134,7 @@ fn applied_tag_just_enum() {
} }
// #[test] // #[test]
#[cfg(any(feature = "gen-llvm"))]
// fn raw_result() { // fn raw_result() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -134,8 +149,8 @@ fn applied_tag_just_enum() {
// i8 // i8
// ); // );
// } // }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn true_is_true() { fn true_is_true() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -152,6 +167,7 @@ fn true_is_true() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn false_is_false() { fn false_is_false() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -168,6 +184,7 @@ fn false_is_false() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn basic_enum() { fn basic_enum() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -189,6 +206,7 @@ fn basic_enum() {
} }
// #[test] // #[test]
#[cfg(any(feature = "gen-llvm"))]
// fn linked_list_empty() { // fn linked_list_empty() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -207,6 +225,7 @@ fn basic_enum() {
// } // }
// //
// #[test] // #[test]
#[cfg(any(feature = "gen-llvm"))]
// fn linked_list_singleton() { // fn linked_list_singleton() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -225,6 +244,7 @@ fn basic_enum() {
// } // }
// //
// #[test] // #[test]
#[cfg(any(feature = "gen-llvm"))]
// fn linked_list_is_empty() { // fn linked_list_is_empty() {
// assert_evals_to!( // assert_evals_to!(
// indoc!( // indoc!(
@ -244,8 +264,8 @@ fn basic_enum() {
// bool // bool
// ); // );
// } // }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn even_odd() { fn even_odd() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -271,6 +291,7 @@ fn even_odd() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn gen_literal_true() { fn gen_literal_true() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -284,6 +305,7 @@ fn gen_literal_true() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn gen_if_float() { fn gen_if_float() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -296,6 +318,7 @@ fn gen_if_float() {
); );
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn when_on_nothing() { fn when_on_nothing() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -314,6 +337,7 @@ fn when_on_nothing() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn when_on_just() { fn when_on_just() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -332,6 +356,7 @@ fn when_on_just() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn when_on_result() { fn when_on_result() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -350,6 +375,7 @@ fn when_on_result() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn when_on_these() { fn when_on_these() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -371,6 +397,7 @@ fn when_on_these() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn match_on_two_values() { fn match_on_two_values() {
// this will produce a Chain internally // this will produce a Chain internally
assert_evals_to!( assert_evals_to!(
@ -387,6 +414,7 @@ fn match_on_two_values() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn pair_with_guard_pattern() { fn pair_with_guard_pattern() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -403,6 +431,7 @@ fn pair_with_guard_pattern() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn result_with_guard_pattern() { fn result_with_guard_pattern() {
// This test revealed an issue with hashing Test values // This test revealed an issue with hashing Test values
assert_evals_to!( assert_evals_to!(
@ -423,6 +452,7 @@ fn result_with_guard_pattern() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn maybe_is_just() { fn maybe_is_just() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -447,6 +477,7 @@ fn maybe_is_just() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn maybe_is_just_nested() { fn maybe_is_just_nested() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -468,6 +499,7 @@ fn maybe_is_just_nested() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn nested_pattern_match() { fn nested_pattern_match() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -488,6 +520,7 @@ fn nested_pattern_match() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn if_guard_vanilla() { fn if_guard_vanilla() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -503,6 +536,7 @@ fn if_guard_vanilla() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[ignore] #[ignore]
fn when_on_single_value_tag() { fn when_on_single_value_tag() {
// this fails because the switched-on symbol is not defined // this fails because the switched-on symbol is not defined
@ -520,6 +554,7 @@ fn when_on_single_value_tag() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn if_guard_multiple() { fn if_guard_multiple() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -540,6 +575,7 @@ fn if_guard_multiple() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn if_guard_constructor_switch() { fn if_guard_constructor_switch() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -583,6 +619,7 @@ fn if_guard_constructor_switch() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn if_guard_constructor_chain() { fn if_guard_constructor_chain() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -599,6 +636,7 @@ fn if_guard_constructor_chain() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn if_guard_pattern_false() { fn if_guard_pattern_false() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -617,6 +655,7 @@ fn if_guard_pattern_false() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn if_guard_switch() { fn if_guard_switch() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -635,6 +674,7 @@ fn if_guard_switch() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn if_guard_pattern_true() { fn if_guard_pattern_true() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -653,6 +693,7 @@ fn if_guard_pattern_true() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn if_guard_exhaustiveness() { fn if_guard_exhaustiveness() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -671,6 +712,7 @@ fn if_guard_exhaustiveness() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn when_on_enum() { fn when_on_enum() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -692,6 +734,7 @@ fn when_on_enum() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn pattern_matching_unit() { fn pattern_matching_unit() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -750,6 +793,7 @@ fn pattern_matching_unit() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn one_element_tag() { fn one_element_tag() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -766,6 +810,7 @@ fn one_element_tag() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn nested_tag_union() { fn nested_tag_union() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -786,6 +831,7 @@ fn nested_tag_union() {
); );
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn unit_type() { fn unit_type() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -804,6 +850,7 @@ fn unit_type() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn nested_record_load() { fn nested_record_load() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -821,6 +868,7 @@ fn nested_record_load() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn join_point_if() { fn join_point_if() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -837,6 +885,7 @@ fn join_point_if() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn join_point_when() { fn join_point_when() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -862,6 +911,7 @@ fn join_point_when() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn join_point_with_cond_expr() { fn join_point_with_cond_expr() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -900,6 +950,7 @@ fn join_point_with_cond_expr() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn alignment_in_single_tag_construction() { fn alignment_in_single_tag_construction() {
assert_evals_to!(indoc!("Three (1 == 1) 32"), (32i64, true), (i64, bool)); assert_evals_to!(indoc!("Three (1 == 1) 32"), (32i64, true), (i64, bool));
@ -911,6 +962,7 @@ fn alignment_in_single_tag_construction() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn alignment_in_single_tag_pattern_match() { fn alignment_in_single_tag_pattern_match() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -942,6 +994,7 @@ fn alignment_in_single_tag_pattern_match() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn alignment_in_multi_tag_construction_two() { fn alignment_in_multi_tag_construction_two() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -959,6 +1012,7 @@ fn alignment_in_multi_tag_construction_two() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn alignment_in_multi_tag_construction_three() { fn alignment_in_multi_tag_construction_three() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -975,6 +1029,7 @@ fn alignment_in_multi_tag_construction_three() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn alignment_in_multi_tag_pattern_match() { fn alignment_in_multi_tag_pattern_match() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -1013,6 +1068,7 @@ fn alignment_in_multi_tag_pattern_match() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[ignore] #[ignore]
fn phantom_polymorphic() { fn phantom_polymorphic() {
// see https://github.com/rtfeldman/roc/issues/786 and below // see https://github.com/rtfeldman/roc/issues/786 and below
@ -1038,6 +1094,7 @@ fn phantom_polymorphic() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[ignore] #[ignore]
fn phantom_polymorphic_record() { fn phantom_polymorphic_record() {
// see https://github.com/rtfeldman/roc/issues/786 // see https://github.com/rtfeldman/roc/issues/786
@ -1065,6 +1122,7 @@ fn phantom_polymorphic_record() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn result_never() { fn result_never() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -1086,6 +1144,7 @@ fn result_never() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn nested_recursive_literal() { fn nested_recursive_literal() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -1105,6 +1164,7 @@ fn nested_recursive_literal() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn newtype_wrapper() { fn newtype_wrapper() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -1128,6 +1188,7 @@ fn newtype_wrapper() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn applied_tag_function() { fn applied_tag_function() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -1147,6 +1208,7 @@ fn applied_tag_function() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn applied_tag_function_result() { fn applied_tag_function_result() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -1166,6 +1228,7 @@ fn applied_tag_function_result() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
fn applied_tag_function_linked_list() { fn applied_tag_function_linked_list() {
assert_evals_to!( assert_evals_to!(
indoc!( indoc!(
@ -1186,6 +1249,7 @@ fn applied_tag_function_linked_list() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-llvm"))]
#[should_panic(expected = "")] #[should_panic(expected = "")]
fn tag_must_be_its_own_type() { fn tag_must_be_its_own_type() {
assert_evals_to!( assert_evals_to!(

View file

@ -210,7 +210,7 @@ pub fn helper(
(main_fn_name, delayed_errors, lib) (main_fn_name, delayed_errors, lib)
} }
#[macro_export] #[allow(unused_macros)]
macro_rules! assert_evals_to { macro_rules! assert_evals_to {
($src:expr, $expected:expr, $ty:ty) => {{ ($src:expr, $expected:expr, $ty:ty) => {{
assert_evals_to!($src, $expected, $ty, (|val| val)); assert_evals_to!($src, $expected, $ty, (|val| val));
@ -237,7 +237,7 @@ macro_rules! assert_evals_to {
let arena = Bump::new(); let arena = Bump::new();
let (main_fn_name, errors, lib) = let (main_fn_name, errors, lib) =
$crate::helpers::eval::helper(&arena, $src, stdlib, $leak, $lazy_literals); $crate::helpers::dev::helper(&arena, $src, stdlib, $leak, $lazy_literals);
let transform = |success| { let transform = |success| {
let expected = $expected; let expected = $expected;
@ -247,3 +247,6 @@ macro_rules! assert_evals_to {
run_jit_function_raw!(lib, main_fn_name, $ty, transform, errors) run_jit_function_raw!(lib, main_fn_name, $ty, transform, errors)
}; };
} }
#[allow(unused_imports)]
pub(crate) use assert_evals_to;

View file

@ -1,3 +1,4 @@
use crate::helpers::from_wasm32_memory::FromWasm32Memory;
use inkwell::module::Module; use inkwell::module::Module;
use libloading::Library; use libloading::Library;
use roc_build::link::module_to_dylib; use roc_build::link::module_to_dylib;
@ -10,7 +11,6 @@ use roc_module::symbol::Symbol;
use roc_mono::ir::OptLevel; use roc_mono::ir::OptLevel;
use roc_types::subs::VarStore; use roc_types::subs::VarStore;
use target_lexicon::Triple; use target_lexicon::Triple;
use test_wasm::helpers::from_wasm32_memory::FromWasm32Memory;
fn promote_expr_to_module(src: &str) -> String { fn promote_expr_to_module(src: &str) -> String {
let mut buffer = String::from("app \"test\" provides [ main ] to \"./platform\"\n\nmain =\n"); let mut buffer = String::from("app \"test\" provides [ main ] to \"./platform\"\n\nmain =\n");
@ -469,7 +469,7 @@ where
let stdlib = arena.alloc(roc_builtins::std::standard_stdlib()); let stdlib = arena.alloc(roc_builtins::std::standard_stdlib());
let is_gen_test = true; let is_gen_test = true;
let instance = crate::helpers::eval::helper_wasm( let instance = crate::helpers::llvm::helper_wasm(
&arena, &arena,
src, src,
stdlib, stdlib,
@ -480,7 +480,7 @@ where
let memory = instance.exports.get_memory("memory").unwrap(); let memory = instance.exports.get_memory("memory").unwrap();
crate::helpers::eval::MEMORY.with(|f| { crate::helpers::llvm::MEMORY.with(|f| {
*f.borrow_mut() = Some(unsafe { std::mem::transmute(memory) }); *f.borrow_mut() = Some(unsafe { std::mem::transmute(memory) });
}); });
@ -494,7 +494,7 @@ where
_ => panic!(), _ => panic!(),
}; };
let output = <T as crate::helpers::eval::FromWasm32Memory>::decode( let output = <T as crate::helpers::llvm::FromWasm32Memory>::decode(
memory, memory,
// skip the RocCallResult tag id // skip the RocCallResult tag id
address as u32 + 8, address as u32 + 8,
@ -505,10 +505,10 @@ where
} }
} }
#[macro_export] #[allow(unused_macros)]
macro_rules! assert_wasm_evals_to { macro_rules! assert_wasm_evals_to {
($src:expr, $expected:expr, $ty:ty, $transform:expr, $ignore_problems:expr) => { ($src:expr, $expected:expr, $ty:ty, $transform:expr, $ignore_problems:expr) => {
match $crate::helpers::eval::assert_wasm_evals_to_help::<$ty>($src, $ignore_problems) { match $crate::helpers::llvm::assert_wasm_evals_to_help::<$ty>($src, $ignore_problems) {
Err(msg) => panic!("Wasm test failed: {:?}", msg), Err(msg) => panic!("Wasm test failed: {:?}", msg),
Ok(actual) => { Ok(actual) => {
#[allow(clippy::bool_assert_comparison)] #[allow(clippy::bool_assert_comparison)]
@ -518,15 +518,21 @@ macro_rules! assert_wasm_evals_to {
}; };
($src:expr, $expected:expr, $ty:ty) => { ($src:expr, $expected:expr, $ty:ty) => {
$crate::assert_wasm_evals_to!($src, $expected, $ty, $crate::helpers::eval::identity, false); $crate::helpers::llvm::assert_wasm_evals_to!(
$src,
$expected,
$ty,
$crate::helpers::llvm::identity,
false
);
}; };
($src:expr, $expected:expr, $ty:ty, $transform:expr) => { ($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
$crate::assert_wasm_evals_to!($src, $expected, $ty, $transform, false); $crate::helpers::llvm::assert_wasm_evals_to!($src, $expected, $ty, $transform, false);
}; };
} }
#[macro_export] #[allow(unused_macros)]
macro_rules! assert_llvm_evals_to { macro_rules! assert_llvm_evals_to {
($src:expr, $expected:expr, $ty:ty, $transform:expr, $ignore_problems:expr) => { ($src:expr, $expected:expr, $ty:ty, $transform:expr, $ignore_problems:expr) => {
use bumpalo::Bump; use bumpalo::Bump;
@ -540,7 +546,7 @@ macro_rules! assert_llvm_evals_to {
let stdlib = arena.alloc(roc_builtins::std::standard_stdlib()); let stdlib = arena.alloc(roc_builtins::std::standard_stdlib());
let is_gen_test = true; let is_gen_test = true;
let (main_fn_name, errors, lib) = $crate::helpers::eval::helper( let (main_fn_name, errors, lib) = $crate::helpers::llvm::helper(
&arena, &arena,
$src, $src,
stdlib, stdlib,
@ -559,26 +565,32 @@ macro_rules! assert_llvm_evals_to {
}; };
($src:expr, $expected:expr, $ty:ty) => { ($src:expr, $expected:expr, $ty:ty) => {
$crate::assert_llvm_evals_to!($src, $expected, $ty, $crate::helpers::eval::identity, false); $crate::helpers::llvm::assert_llvm_evals_to!(
$src,
$expected,
$ty,
$crate::helpers::llvm::identity,
false
);
}; };
($src:expr, $expected:expr, $ty:ty, $transform:expr) => { ($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
$crate::assert_llvm_evals_to!($src, $expected, $ty, $transform, false); $crate::helpers::llvm::assert_llvm_evals_to!($src, $expected, $ty, $transform, false);
}; };
} }
#[macro_export] #[allow(unused_macros)]
macro_rules! assert_evals_to { macro_rules! assert_evals_to {
($src:expr, $expected:expr, $ty:ty) => {{ ($src:expr, $expected:expr, $ty:ty) => {{
assert_evals_to!($src, $expected, $ty, $crate::helpers::eval::identity); assert_evals_to!($src, $expected, $ty, $crate::helpers::llvm::identity);
}}; }};
($src:expr, $expected:expr, $ty:ty, $transform:expr) => { ($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
// Same as above, except with an additional transformation argument. // Same as above, except with an additional transformation argument.
{ {
#[cfg(feature = "wasm-cli-run")] #[cfg(feature = "wasm-cli-run")]
$crate::assert_wasm_evals_to!($src, $expected, $ty, $transform, false); $crate::helpers::llvm::assert_wasm_evals_to!($src, $expected, $ty, $transform, false);
$crate::assert_llvm_evals_to!($src, $expected, $ty, $transform, false); $crate::helpers::llvm::assert_llvm_evals_to!($src, $expected, $ty, $transform, false);
} }
}; };
} }
@ -588,18 +600,32 @@ pub fn identity<T>(value: T) -> T {
value value
} }
#[macro_export] #[allow(unused_macros)]
macro_rules! assert_non_opt_evals_to { macro_rules! assert_non_opt_evals_to {
($src:expr, $expected:expr, $ty:ty) => {{ ($src:expr, $expected:expr, $ty:ty) => {{
$crate::assert_llvm_evals_to!($src, $expected, $ty, $crate::helpers::eval::identity); $crate::helpers::llvm::assert_llvm_evals_to!(
$src,
$expected,
$ty,
$crate::helpers::llvm::identity
);
}}; }};
($src:expr, $expected:expr, $ty:ty, $transform:expr) => { ($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
// Same as above, except with an additional transformation argument. // Same as above, except with an additional transformation argument.
{ {
$crate::assert_llvm_evals_to!($src, $expected, $ty, $transform, false); $crate::helpers::llvm::assert_llvm_evals_to!($src, $expected, $ty, $transform, false);
} }
}; };
($src:expr, $expected:expr, $ty:ty, $transform:expr) => {{ ($src:expr, $expected:expr, $ty:ty, $transform:expr) => {{
$crate::assert_llvm_evals_to!($src, $expected, $ty, $transform); $crate::helpers::llvm::assert_llvm_evals_to!($src, $expected, $ty, $transform);
}}; }};
} }
#[allow(unused_imports)]
pub(crate) use assert_evals_to;
#[allow(unused_imports)]
pub(crate) use assert_llvm_evals_to;
#[allow(unused_imports)]
pub(crate) use assert_non_opt_evals_to;
#[allow(unused_imports)]
pub(crate) use assert_wasm_evals_to;

View file

@ -1,7 +1,14 @@
extern crate bumpalo; extern crate bumpalo;
#[macro_use] #[cfg(feature = "gen-dev")]
pub mod eval; pub mod dev;
pub mod from_wasm32_memory;
#[cfg(feature = "gen-llvm")]
pub mod llvm;
#[cfg(feature = "gen-wasm")]
pub mod wasm;
#[cfg(feature = "gen-wasm")]
pub mod wasm32_test_result;
/// Used in the with_larger_debug_stack() function, for tests that otherwise /// Used in the with_larger_debug_stack() function, for tests that otherwise
/// run out of stack space in debug builds (but don't in --release builds) /// run out of stack space in debug builds (but don't in --release builds)

View file

@ -169,7 +169,7 @@ where
// NOTE the stdlib must be in the arena; just taking a reference will segfault // NOTE the stdlib must be in the arena; just taking a reference will segfault
let stdlib = arena.alloc(roc_builtins::std::standard_stdlib()); let stdlib = arena.alloc(roc_builtins::std::standard_stdlib());
let instance = crate::helpers::eval::helper_wasm(&arena, src, stdlib, &expected); let instance = crate::helpers::wasm::helper_wasm(&arena, src, stdlib, &expected);
let memory = instance.exports.get_memory("__linear_memory").unwrap(); let memory = instance.exports.get_memory("__linear_memory").unwrap();
@ -190,10 +190,10 @@ where
} }
} }
#[macro_export] #[allow(unused_macros)]
macro_rules! assert_wasm_evals_to { macro_rules! assert_wasm_evals_to {
($src:expr, $expected:expr, $ty:ty, $transform:expr) => { ($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
match $crate::helpers::eval::assert_wasm_evals_to_help::<$ty>($src, $expected) { match $crate::helpers::wasm::assert_wasm_evals_to_help::<$ty>($src, $expected) {
Err(msg) => panic!("{:?}", msg), Err(msg) => panic!("{:?}", msg),
Ok(actual) => { Ok(actual) => {
assert_eq!($transform(actual), $expected) assert_eq!($transform(actual), $expected)
@ -202,23 +202,28 @@ macro_rules! assert_wasm_evals_to {
}; };
($src:expr, $expected:expr, $ty:ty) => { ($src:expr, $expected:expr, $ty:ty) => {
$crate::assert_wasm_evals_to!($src, $expected, $ty, $crate::helpers::eval::identity); $crate::helpers::wasm::assert_wasm_evals_to!(
$src,
$expected,
$ty,
$crate::helpers::wasm::identity
);
}; };
($src:expr, $expected:expr, $ty:ty, $transform:expr) => { ($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
$crate::assert_wasm_evals_to!($src, $expected, $ty, $transform); $crate::helpers::wasm::assert_wasm_evals_to!($src, $expected, $ty, $transform);
}; };
} }
#[macro_export] #[allow(unused_macros)]
macro_rules! assert_evals_to { macro_rules! assert_evals_to {
($src:expr, $expected:expr, $ty:ty) => {{ ($src:expr, $expected:expr, $ty:ty) => {{
assert_evals_to!($src, $expected, $ty, $crate::helpers::eval::identity); assert_evals_to!($src, $expected, $ty, $crate::helpers::wasm::identity);
}}; }};
($src:expr, $expected:expr, $ty:ty, $transform:expr) => { ($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
// Same as above, except with an additional transformation argument. // Same as above, except with an additional transformation argument.
{ {
$crate::assert_wasm_evals_to!($src, $expected, $ty, $transform); $crate::helpers::wasm::assert_wasm_evals_to!($src, $expected, $ty, $transform);
} }
}; };
} }
@ -227,3 +232,8 @@ macro_rules! assert_evals_to {
pub fn identity<T>(value: T) -> T { pub fn identity<T>(value: T) -> T {
value value
} }
#[allow(unused_imports)]
pub(crate) use assert_evals_to;
#[allow(unused_imports)]
pub(crate) use assert_wasm_evals_to;

View file

@ -112,6 +112,7 @@ wasm_test_result_primitive!(u32, i32_store, Align::Bytes4);
wasm_test_result_primitive!(i32, i32_store, Align::Bytes4); wasm_test_result_primitive!(i32, i32_store, Align::Bytes4);
wasm_test_result_primitive!(u64, i64_store, Align::Bytes8); wasm_test_result_primitive!(u64, i64_store, Align::Bytes8);
wasm_test_result_primitive!(i64, i64_store, Align::Bytes8); wasm_test_result_primitive!(i64, i64_store, Align::Bytes8);
wasm_test_result_primitive!(usize, i32_store, Align::Bytes4);
wasm_test_result_primitive!(f32, f32_store, Align::Bytes8); wasm_test_result_primitive!(f32, f32_store, Align::Bytes8);
wasm_test_result_primitive!(f64, f64_store, Align::Bytes8); wasm_test_result_primitive!(f64, f64_store, Align::Bytes8);

View file

@ -1,18 +0,0 @@
#![warn(clippy::dbg_macro)]
// See github.com/rtfeldman/roc/issues/800 for discussion of the large_enum_variant check.
#![allow(clippy::large_enum_variant)]
// we actually want to compare against the literal float bits
#![allow(clippy::float_cmp)]
pub mod gen_compare;
pub mod gen_dict;
pub mod gen_hash;
pub mod gen_list;
pub mod gen_num;
pub mod gen_primitives;
pub mod gen_records;
pub mod gen_result;
pub mod gen_set;
pub mod gen_str;
pub mod gen_tags;
mod helpers;

View file

@ -0,0 +1,57 @@
#![warn(clippy::dbg_macro)]
// See github.com/rtfeldman/roc/issues/800 for discussion of the large_enum_variant check.
#![allow(clippy::large_enum_variant)]
// we actually want to compare against the literal float bits
#![allow(clippy::float_cmp)]
pub mod gen_compare;
pub mod gen_dict;
pub mod gen_list;
pub mod gen_num;
pub mod gen_primitives;
pub mod gen_records;
pub mod gen_set;
pub mod gen_str;
pub mod gen_tags;
mod helpers;
pub mod wasm_str;
use core::ffi::c_void;
#[no_mangle]
pub unsafe fn roc_alloc(size: usize, _alignment: u32) -> *mut c_void {
libc::malloc(size)
}
#[no_mangle]
pub unsafe fn roc_realloc(
c_ptr: *mut c_void,
new_size: usize,
_old_size: usize,
_alignment: u32,
) -> *mut c_void {
libc::realloc(c_ptr, new_size)
}
#[no_mangle]
pub unsafe fn roc_dealloc(c_ptr: *mut c_void, _alignment: u32) {
libc::free(c_ptr)
}
#[no_mangle]
pub unsafe fn roc_panic(c_ptr: *mut c_void, tag_id: u32) {
use roc_gen_llvm::llvm::build::PanicTagId;
use std::convert::TryFrom;
use std::ffi::CStr;
use std::os::raw::c_char;
match PanicTagId::try_from(tag_id) {
Ok(PanicTagId::NullTerminatedString) => {
let slice = CStr::from_ptr(c_ptr as *const c_char);
let string = slice.to_str().unwrap();
eprintln!("Roc hit a panic: {}", string);
std::process::exit(1);
}
Err(_) => unreachable!(),
}
}

View file

@ -1,6 +1,16 @@
#![cfg(test)] // Wasm pointers are only 32bit. This effects RocStr.
// These are versions of the str tests assuming 32bit pointers.
#![cfg(not(feature = "gen-dev"))]
use crate::assert_evals_to; // TODO: We need to make these tests work with the llvm wasm backend.
// #[cfg(feature = "gen-llvm")]
// use crate::helpers::llvm::assert_wasm_evals_to as assert_evals_to;
#[cfg(feature = "gen-wasm")]
use crate::helpers::wasm::assert_evals_to;
#[allow(unused_imports)]
use indoc::indoc; use indoc::indoc;
// use roc_std::RocStr; // use roc_std::RocStr;
@ -228,6 +238,7 @@ use indoc::indoc;
// } // }
#[test] #[test]
#[cfg(any(feature = "gen-wasm"))]
fn small_str_literal() { fn small_str_literal() {
assert_evals_to!( assert_evals_to!(
"\"JJJJJJJ\"", "\"JJJJJJJ\"",
@ -237,6 +248,7 @@ fn small_str_literal() {
} }
#[test] #[test]
#[cfg(any(feature = "gen-wasm"))]
fn small_str_zeroed_literal() { fn small_str_zeroed_literal() {
// Verifies that we zero out unused bytes in the string. // Verifies that we zero out unused bytes in the string.
// This is important so that string equality tests don't randomly // This is important so that string equality tests don't randomly

View file

@ -5,6 +5,10 @@ authors = ["The Roc Contributors"]
license = "UPL-1.0" license = "UPL-1.0"
edition = "2018" edition = "2018"
[[test]]
name = "test_mono"
path = "src/tests.rs"
[dev-dependencies] [dev-dependencies]
roc_collections = { path = "../collections" } roc_collections = { path = "../collections" }
roc_module = { path = "../module" } roc_module = { path = "../module" }

47
compiler/test_mono_macros/Cargo.lock generated Normal file
View file

@ -0,0 +1,47 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "proc-macro2"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "test_mono_macros"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"

View file

@ -1,22 +0,0 @@
[package]
name = "test_wasm"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
# roc_module = { path = "../module" }
# roc_mono = { path = "../mono" }
wasmer = { version = "2.0.0", default-features = false, features = ["default-cranelift", "default-universal"] }
wasmer-wasi = "2.0.0"
bumpalo = { version = "3.8.0", features = ["collections"] }
indoc = "1.0.3"
roc_collections = { path = "../collections" }
roc_std = { path = "../../roc_std" }
roc_gen_wasm = { path = "../gen_wasm" }
roc_can = { path = "../can" }
roc_builtins = { path = "../builtins" }
roc_load = { path = "../load" }

View file

@ -1,44 +0,0 @@
#[macro_use]
pub mod eval;
pub mod from_wasm32_memory;
pub mod wasm32_test_result;
/// Used in the with_larger_debug_stack() function, for tests that otherwise
/// run out of stack space in debug builds (but don't in --release builds)
#[allow(dead_code)]
const EXPANDED_STACK_SIZE: usize = 8 * 1024 * 1024;
/// Without this, some tests pass in `cargo test --release` but fail without
/// the --release flag because they run out of stack space. This increases
/// stack size for debug builds only, while leaving the stack space at the default
/// amount for release builds.
#[allow(dead_code)]
#[cfg(debug_assertions)]
pub fn with_larger_debug_stack<F>(run_test: F)
where
F: FnOnce(),
F: Send,
F: 'static,
{
std::thread::Builder::new()
.stack_size(EXPANDED_STACK_SIZE)
.spawn(run_test)
.expect("Error while spawning expanded dev stack size thread")
.join()
.expect("Error while joining expanded dev stack size thread")
}
/// In --release builds, don't increase the stack size. Run the test normally.
/// This way, we find out if any of our tests are blowing the stack even after
/// optimizations in release builds.
#[allow(dead_code)]
#[cfg(not(debug_assertions))]
#[inline(always)]
pub fn with_larger_debug_stack<F>(run_test: F)
where
F: FnOnce() -> (),
F: Send,
F: 'static,
{
run_test()
}

View file

@ -1,4 +0,0 @@
pub mod helpers;
pub mod wasm_num;
pub mod wasm_records;
pub mod wasm_str;

File diff suppressed because it is too large Load diff

View file

@ -1,911 +0,0 @@
#![cfg(all(test, target_os = "linux", any(target_arch = "x86_64"/*, target_arch = "aarch64"*/)))]
use crate::assert_evals_to;
use indoc::indoc;
// #[test]
// fn basic_record() {
// assert_evals_to!(
// indoc!(
// r#"
// { y: 17, x: 15, z: 19 }.x
// "#
// ),
// 15,
// i64
// );
//
// assert_evals_to!(
// indoc!(
// r#"
// { x: 15, y: 17, z: 19 }.y
// "#
// ),
// 17,
// i64
// );
//
// assert_evals_to!(
// indoc!(
// r#"
// { x: 15, y: 17, z: 19 }.z
// "#
// ),
// 19,
// i64
// );
// }
//
// #[test]
// fn nested_record() {
// assert_evals_to!(
// indoc!(
// r#"
// { x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.x
// "#
// ),
// 15,
// i64
// );
//
// assert_evals_to!(
// indoc!(
// r#"
// { x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.y.a
// "#
// ),
// 12,
// i64
// );
//
// assert_evals_to!(
// indoc!(
// r#"
// { x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.y.b
// "#
// ),
// 15,
// i64
// );
//
// assert_evals_to!(
// indoc!(
// r#"
// { x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.y.c
// "#
// ),
// 2,
// i64
// );
//
// assert_evals_to!(
// indoc!(
// r#"
// { x: 15, y: { a: 12, b: 15, c: 2}, z: 19 }.z
// "#
// ),
// 19,
// i64
// );
// }
//
// #[test]
// fn f64_record() {
// assert_evals_to!(
// indoc!(
// r#"
// rec = { y: 17.2, x: 15.1, z: 19.3 }
//
// rec.x
// "#
// ),
// 15.1,
// f64
// );
//
// assert_evals_to!(
// indoc!(
// r#"
// rec = { y: 17.2, x: 15.1, z: 19.3 }
//
// rec.y
// "#
// ),
// 17.2,
// f64
// );
//
// assert_evals_to!(
// indoc!(
// r#"
// rec = { y: 17.2, x: 15.1, z: 19.3 }
//
// rec.z
// "#
// ),
// 19.3,
// f64
// );
// }
// #[test]
// fn fn_record() {
// assert_evals_to!(
// indoc!(
// r#"
// getRec = \x -> { y: 17, x, z: 19 }
// (getRec 15).x
// "#
// ),
// 15,
// i64
// );
// assert_evals_to!(
// indoc!(
// r#"
// rec = { x: 15, y: 17, z: 19 }
// rec.y
// "#
// ),
// 17,
// i64
// );
// assert_evals_to!(
// indoc!(
// r#"
// rec = { x: 15, y: 17, z: 19 }
// rec.z
// "#
// ),
// 19,
// i64
// );
// assert_evals_to!(
// indoc!(
// r#"
// rec = { x: 15, y: 17, z: 19 }
// rec.z + rec.x
// "#
// ),
// 34,
// i64
// );
// }
// #[test]
// fn def_record() {
// assert_evals_to!(
// indoc!(
// r#"
// rec = { y: 17, x: 15, z: 19 }
//
// rec.x
// "#
// ),
// 15,
// i64
// );
//
// assert_evals_to!(
// indoc!(
// r#"
// rec = { x: 15, y: 17, z: 19 }
//
// rec.y
// "#
// ),
// 17,
// i64
// );
//
// assert_evals_to!(
// indoc!(
// r#"
// rec = { x: 15, y: 17, z: 19 }
//
// rec.z
// "#
// ),
// 19,
// i64
// );
// }
//
// #[test]
// fn when_on_record() {
// assert_evals_to!(
// indoc!(
// r#"
// when { x: 0x2 } is
// { x } -> x + 3
// "#
// ),
// 5,
// i64
// );
// }
//
// #[test]
// fn when_record_with_guard_pattern() {
// assert_evals_to!(
// indoc!(
// r#"
// when { x: 0x2, y: 3.14 } is
// { x: var } -> var + 3
// "#
// ),
// 5,
// i64
// );
// }
//
// #[test]
// fn let_with_record_pattern() {
// assert_evals_to!(
// indoc!(
// r#"
// { x } = { x: 0x2, y: 3.14 }
//
// x
// "#
// ),
// 2,
// i64
// );
// }
//
// #[test]
// fn record_guard_pattern() {
// assert_evals_to!(
// indoc!(
// r#"
// when { x: 0x2, y: 3.14 } is
// { x: 0x4 } -> 5
// { x } -> x + 3
// "#
// ),
// 5,
// i64
// );
// }
//
// #[test]
// fn twice_record_access() {
// assert_evals_to!(
// indoc!(
// r#"
// x = {a: 0x2, b: 0x3 }
//
// x.a + x.b
// "#
// ),
// 5,
// i64
// );
// }
// #[test]
// fn empty_record() {
// assert_evals_to!(
// indoc!(
// r#"
// v = {}
//
// v
// "#
// ),
// (),
// ()
// );
// }
#[test]
fn i64_record1_literal() {
assert_evals_to!(
indoc!(
r#"
{ x: 3 }
"#
),
3,
i64
);
}
#[test]
fn i64_record2_literal() {
assert_evals_to!(
indoc!(
r#"
{ x: 3, y: 5 }
"#
),
(3, 5),
(i64, i64)
);
}
#[test]
fn i64_record3_literal() {
assert_evals_to!(
indoc!(
r#"
{ x: 3, y: 5, z: 17 }
"#
),
(3, 5, 17),
(i64, i64, i64)
);
}
#[test]
fn f64_record2_literal() {
assert_evals_to!(
indoc!(
r#"
{ x: 3.1, y: 5.1 }
"#
),
(3.1, 5.1),
(f64, f64)
);
}
#[test]
fn f64_record3_literal() {
assert_evals_to!(
indoc!(
r#"
{ x: 3.1, y: 5.1, z: 17.1 }
"#
),
(3.1, 5.1, 17.1),
(f64, f64, f64)
);
}
#[test]
fn bool_record4_literal() {
assert_evals_to!(
indoc!(
r#"
record : { a : Bool, b : Bool, c : Bool, d : Bool }
record = { a: True, b: False, c : False, d : True }
record
"#
),
[true, false, false, true],
[bool; 4]
);
}
#[test]
fn i64_record9_literal() {
assert_evals_to!(
indoc!(
r#"
{ 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],
[i64; 9]
);
}
#[test]
fn bool_literal() {
assert_evals_to!(
indoc!(
r#"
x : Bool
x = True
x
"#
),
true,
bool
);
}
// #[test]
// fn optional_field_when_use_default() {
// assert_evals_to!(
// indoc!(
// r#"
// app "test" provides [ main ] to "./platform"
// f = \r ->
// when r is
// { x: Blue, y ? 3 } -> y
// { x: Red, y ? 5 } -> y
// main =
// a = f { x: Blue, y: 7 }
// b = f { x: Blue }
// c = f { x: Red, y: 11 }
// d = f { x: Red }
// a * b * c * d
// "#
// ),
// 3 * 5 * 7 * 11,
// i64
// );
// }
// #[test]
// fn optional_field_when_use_default_nested() {
// assert_evals_to!(
// indoc!(
// r#"
// f = \r ->
// when r is
// { x: Blue, y ? 3 } -> y
// { x: Red, y ? 5 } -> y
// a = f { x: Blue, y: 7 }
// b = f { x: Blue }
// c = f { x: Red, y: 11 }
// d = f { x: Red }
// a * b * c * d
// "#
// ),
// 3 * 5 * 7 * 11,
// i64
// );
// }
// #[test]
// fn optional_field_when_no_use_default() {
// assert_evals_to!(
// indoc!(
// r#"
// app "test" provides [ main ] to "./platform"
// f = \r ->
// { x ? 10, y } = r
// x + y
// main =
// f { x: 4, y: 9 }
// "#
// ),
// 13,
// i64
// );
// }
// #[test]
// fn optional_field_when_no_use_default_nested() {
// assert_evals_to!(
// indoc!(
// r#"
// f = \r ->
// { x ? 10, y } = r
// x + y
// f { x: 4, y: 9 }
// "#
// ),
// 13,
// i64
// );
// }
// #[test]
// fn optional_field_let_use_default() {
// assert_evals_to!(
// indoc!(
// r#"
// app "test" provides [ main ] to "./platform"
// f = \r ->
// { x ? 10, y } = r
// x + y
// main =
// f { y: 9 }
// "#
// ),
// 19,
// i64
// );
// }
// #[test]
// fn optional_field_let_no_use_default() {
// assert_evals_to!(
// indoc!(
// r#"
// app "test" provides [ main ] to "./platform"
// f = \r ->
// { x ? 10, y } = r
// x + y
// main =
// f { x: 4, y: 9 }
// "#
// ),
// 13,
// i64
// );
// }
// #[test]
// fn optional_field_let_no_use_default_nested() {
// assert_evals_to!(
// indoc!(
// r#"
// f = \r ->
// { x ? 10, y } = r
// x + y
// f { x: 4, y: 9 }
// "#
// ),
// 13,
// i64
// );
// }
// #[test]
// fn optional_field_function_use_default() {
// assert_evals_to!(
// indoc!(
// r#"
// f = \{ x ? 10, y } -> x + y
// f { y: 9 }
// "#
// ),
// 19,
// i64
// );
// }
// #[test]
// #[ignore]
// fn optional_field_function_no_use_default() {
// // blocked on https://github.com/rtfeldman/roc/issues/786
// assert_evals_to!(
// indoc!(
// r#"
// app "test" provides [ main ] to "./platform"
// f = \{ x ? 10, y } -> x + y
// main =
// f { x: 4, y: 9 }
// "#
// ),
// 13,
// i64
// );
// }
// #[test]
// #[ignore]
// fn optional_field_function_no_use_default_nested() {
// // blocked on https://github.com/rtfeldman/roc/issues/786
// assert_evals_to!(
// indoc!(
// r#"
// f = \{ x ? 10, y } -> x + y
// f { x: 4, y: 9 }
// "#
// ),
// 13,
// i64
// );
// }
// #[test]
// fn optional_field_singleton_record() {
// assert_evals_to!(
// indoc!(
// r#"
// when { x : 4 } is
// { x ? 3 } -> x
// "#
// ),
// 4,
// i64
// );
// }
// #[test]
// fn optional_field_empty_record() {
// assert_evals_to!(
// indoc!(
// r#"
// when { } is
// { x ? 3 } -> x
// "#
// ),
// 3,
// i64
// );
// }
#[test]
fn return_record_3() {
assert_evals_to!(
indoc!(
r#"
{ x: 3, y: 5, z: 4 }
"#
),
(3, 5, 4),
(i64, i64, i64)
);
}
#[test]
fn return_record_4() {
assert_evals_to!(
indoc!(
r#"
{ a: 3, b: 5, c: 4, d: 2 }
"#
),
[3, 5, 4, 2],
[i64; 4]
);
}
#[test]
fn return_record_5() {
assert_evals_to!(
indoc!(
r#"
{ a: 3, b: 5, c: 4, d: 2, e: 1 }
"#
),
[3, 5, 4, 2, 1],
[i64; 5]
);
}
#[test]
fn return_record_6() {
assert_evals_to!(
indoc!(
r#"
{ a: 3, b: 5, c: 4, d: 2, e: 1, f: 7 }
"#
),
[3, 5, 4, 2, 1, 7],
[i64; 6]
);
}
#[test]
fn return_record_7() {
assert_evals_to!(
indoc!(
r#"
{ a: 3, b: 5, c: 4, d: 2, e: 1, f: 7, g: 8 }
"#
),
[3, 5, 4, 2, 1, 7, 8],
[i64; 7]
);
}
#[test]
fn return_record_float_int() {
assert_evals_to!(
indoc!(
r#"
{ a: 3.14, b: 0x1 }
"#
),
(3.14, 0x1),
(f64, i64)
);
}
#[test]
fn return_record_int_float() {
assert_evals_to!(
indoc!(
r#"
{ a: 0x1, b: 3.14 }
"#
),
(0x1, 3.14),
(i64, f64)
);
}
#[test]
fn return_record_float_float() {
assert_evals_to!(
indoc!(
r#"
{ a: 6.28, b: 3.14 }
"#
),
(6.28, 3.14),
(f64, f64)
);
}
#[test]
fn return_record_float_float_float() {
assert_evals_to!(
indoc!(
r#"
{ a: 6.28, b: 3.14, c: 0.1 }
"#
),
(6.28, 3.14, 0.1),
(f64, f64, f64)
);
}
// #[test]
// fn return_nested_record() {
// assert_evals_to!(
// indoc!(
// r#"
// { flag: 0x0, payload: { a: 6.28, b: 3.14, c: 0.1 } }
// "#
// ),
// (0x0, (6.28, 3.14, 0.1)),
// (i64, (f64, f64, f64))
// );
// }
// #[test]
// fn accessor() {
// assert_evals_to!(
// indoc!(
// r#"
// .foo { foo: 4 } + .foo { bar: 6.28, foo: 3 }
// "#
// ),
// 7,
// i64
// );
// }
// #[test]
// fn accessor_single_element_record() {
// assert_evals_to!(
// indoc!(
// r#"
// .foo { foo: 4 }
// "#
// ),
// 4,
// i64
// );
// }
// #[test]
// fn update_record() {
// assert_evals_to!(
// indoc!(
// r#"
// rec = { foo: 42, bar: 6 }
// { rec & foo: rec.foo + 1 }
// "#
// ),
// (6, 43),
// (i64, i64)
// );
// }
// #[test]
// fn update_single_element_record() {
// assert_evals_to!(
// indoc!(
// r#"
// rec = { foo: 42}
// { rec & foo: rec.foo + 1 }
// "#
// ),
// 43,
// i64
// );
// }
// #[test]
// fn booleans_in_record() {
// assert_evals_to!(
// indoc!("{ x: 1 == 1, y: 1 == 1 }"),
// (true, true),
// (bool, bool)
// );
// assert_evals_to!(
// indoc!("{ x: 1 != 1, y: 1 == 1 }"),
// (false, true),
// (bool, bool)
// );
// assert_evals_to!(
// indoc!("{ x: 1 == 1, y: 1 != 1 }"),
// (true, false),
// (bool, bool)
// );
// assert_evals_to!(
// indoc!("{ x: 1 != 1, y: 1 != 1 }"),
// (false, false),
// (bool, bool)
// );
// }
// #[test]
// fn alignment_in_record() {
// assert_evals_to!(
// indoc!("{ c: 32, b: if True then Red else if True then Green else Blue, a: 1 == 1 }"),
// (32i64, true, 2u8),
// (i64, bool, u8)
// );
// }
#[test]
fn stack_memory_return_from_branch() {
// stack memory pointer should end up in the right place after returning from a branch
assert_evals_to!(
indoc!(
r#"
stackMemoryJunk = { x: 999, y: 111 }
if True then
{ x: 123, y: 321 }
else
stackMemoryJunk
"#
),
(123, 321),
(i64, i64)
);
}
// #[test]
// fn blue_and_present() {
// assert_evals_to!(
// indoc!(
// r#"
// f = \r ->
// when r is
// { x: Blue, y ? 3 } -> y
// { x: Red, y ? 5 } -> y
// f { x: Blue, y: 7 }
// "#
// ),
// 7,
// i64
// );
// }
// #[test]
// fn blue_and_absent() {
// assert_evals_to!(
// indoc!(
// r#"
// f = \r ->
// when r is
// { x: Blue, y ? 3 } -> y
// { x: Red, y ? 5 } -> y
// f { x: Blue }
// "#
// ),
// 3,
// i64
// );
// }

View file

@ -38,6 +38,7 @@ bumpalo = { version = "3.8.0", features = ["collections"] }
arraystring = "0.3.0" arraystring = "0.3.0"
libc = "0.2.106" libc = "0.2.106"
page_size = "0.4.2" page_size = "0.4.2"
# once winit 0.26 is out, check if copypasta can be updated simultaneously so they use the same versions for their dependencies. This will save build time.
winit = "0.25.0" winit = "0.25.0"
wgpu = "0.11.0" wgpu = "0.11.0"
wgpu_glyph = "0.15.1" wgpu_glyph = "0.15.1"

View file

@ -1,14 +1,14 @@
{ {
"niv": { "niv": {
"branch": "master", "branch": "master",
"description": "Niv fork using unstable nix packages.", "description": "Easy dependency management for Nix projects.",
"homepage": "https://github.com/Anton-4/niv", "homepage": "https://github.com/nmattia/niv",
"owner": "Anton-4", "owner": "nmattia",
"repo": "niv", "repo": "niv",
"rev": "f292d8d149a0e5d1e7fdd0ef68d5dde75814ef7e", "rev": "5830a4dd348d77e39a0f3c4c762ff2663b602d4c",
"sha256": "0lf52chvqfl5jq09sc2k9vg8faqnd27f3ic5cgzp68jk036bax7r", "sha256": "1d3lsrqvci4qz2hwjrcnd8h5vfkg8aypq3sjd4g3izbc8frwz5sm",
"type": "tarball", "type": "tarball",
"url": "https://github.com/Anton-4/niv/archive/f292d8d149a0e5d1e7fdd0ef68d5dde75814ef7e.tar.gz", "url": "https://github.com/nmattia/niv/archive/5830a4dd348d77e39a0f3c4c762ff2663b602d4c.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}, },
"nixpkgs": { "nixpkgs": {