Merge branch 'main' into specialize-exprs-bools

This commit is contained in:
Richard Feldman 2024-12-11 23:09:35 -05:00 committed by GitHub
commit aaf82dd417
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 110 additions and 52 deletions

View file

@ -29,11 +29,6 @@ jobs:
- name: roc format check on builtins - name: roc format check on builtins
run: cargo run --locked --release format --check crates/compiler/builtins/roc run: cargo run --locked --release format --check crates/compiler/builtins/roc
- name: run fuzz tests
run: |
cargo +nightly-2024-02-03 install --locked cargo-fuzz
cd crates/compiler/test_syntax/fuzz && cargo +nightly-2024-02-03 fuzz run -j4 fuzz_expr --sanitizer=none -- -dict=dict.txt -max_total_time=60
- name: ensure there are no unused dependencies - name: ensure there are no unused dependencies
run: cargo +nightly-2024-02-03 udeps --all-targets run: cargo +nightly-2024-02-03 udeps --all-targets
@ -67,3 +62,8 @@ jobs:
- name: test website build script - name: test website build script
run: bash www/build.sh run: bash www/build.sh
- name: run fuzz tests - ok to merge if this one fails # for now!
run: |
cargo +nightly-2024-02-03 install --locked cargo-fuzz
cd crates/compiler/test_syntax/fuzz && cargo +nightly-2024-02-03 fuzz run -j4 fuzz_expr --sanitizer=none -- -dict=dict.txt -max_total_time=60

View file

@ -873,18 +873,24 @@ pub fn build(
let opt_level = opt_level_from_flags(matches); let opt_level = opt_level_from_flags(matches);
// Note: This allows using `--dev` with `--optimize`. let should_run_expects = matches!(opt_level, OptLevel::Development | OptLevel::Normal) &&
// This means frontend optimizations and dev backend. // TODO: once expect is decoupled from roc launching the executable, remove this part of the conditional.
let code_gen_backend = if matches.get_flag(FLAG_DEV) { matches!(
config,
BuildConfig::BuildAndRun | BuildConfig::BuildAndRunIfNoErrors
);
let code_gen_backend = if matches!(opt_level, OptLevel::Development) {
if matches!(target.architecture(), Architecture::Wasm32) { if matches!(target.architecture(), Architecture::Wasm32) {
CodeGenBackend::Wasm CodeGenBackend::Wasm
} else { } else {
CodeGenBackend::Assembly(AssemblyBackendMode::Binary) CodeGenBackend::Assembly(AssemblyBackendMode::Binary)
} }
} else { } else {
let backend_mode = match opt_level { let backend_mode = if should_run_expects {
OptLevel::Development => LlvmBackendMode::BinaryDev, LlvmBackendMode::BinaryWithExpect
OptLevel::Normal | OptLevel::Size | OptLevel::Optimize => LlvmBackendMode::Binary, } else {
LlvmBackendMode::Binary
}; };
CodeGenBackend::Llvm(backend_mode) CodeGenBackend::Llvm(backend_mode)
@ -1022,7 +1028,7 @@ pub fn build(
roc_run( roc_run(
&arena, &arena,
path, path,
opt_level, should_run_expects,
target, target,
args, args,
bytes, bytes,
@ -1065,7 +1071,7 @@ pub fn build(
roc_run( roc_run(
&arena, &arena,
path, path,
opt_level, should_run_expects,
target, target,
args, args,
bytes, bytes,
@ -1084,7 +1090,7 @@ pub fn build(
fn roc_run<'a, I: IntoIterator<Item = &'a OsStr>>( fn roc_run<'a, I: IntoIterator<Item = &'a OsStr>>(
arena: &Bump, arena: &Bump,
script_path: &Path, script_path: &Path,
opt_level: OptLevel, should_run_expects: bool,
target: Target, target: Target,
args: I, args: I,
binary_bytes: &[u8], binary_bytes: &[u8],
@ -1126,7 +1132,7 @@ fn roc_run<'a, I: IntoIterator<Item = &'a OsStr>>(
_ => roc_run_native( _ => roc_run_native(
arena, arena,
script_path, script_path,
opt_level, should_run_expects,
args, args,
binary_bytes, binary_bytes,
expect_metadata, expect_metadata,
@ -1194,7 +1200,7 @@ fn make_argv_envp<'a, I: IntoIterator<Item = S>, S: AsRef<OsStr>>(
fn roc_run_native<I: IntoIterator<Item = S>, S: AsRef<OsStr>>( fn roc_run_native<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(
arena: &Bump, arena: &Bump,
script_path: &Path, script_path: &Path,
opt_level: OptLevel, should_run_expects: bool,
args: I, args: I,
binary_bytes: &[u8], binary_bytes: &[u8],
expect_metadata: ExpectMetadata, expect_metadata: ExpectMetadata,
@ -1216,11 +1222,10 @@ fn roc_run_native<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(
.chain([std::ptr::null()]) .chain([std::ptr::null()])
.collect_in(arena); .collect_in(arena);
match opt_level { if should_run_expects {
OptLevel::Development => roc_dev_native(arena, executable, argv, envp, expect_metadata), roc_dev_native(arena, executable, argv, envp, expect_metadata);
OptLevel::Normal | OptLevel::Size | OptLevel::Optimize => unsafe { } else {
roc_run_native_fast(executable, &argv, &envp); unsafe { roc_run_native_fast(executable, &argv, &envp) };
},
} }
Ok(1) Ok(1)
@ -1458,7 +1463,7 @@ fn roc_run_executable_file_path(binary_bytes: &[u8]) -> std::io::Result<Executab
fn roc_run_native<I: IntoIterator<Item = S>, S: AsRef<OsStr>>( fn roc_run_native<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(
arena: &Bump, // This should be passed an owned value, not a reference, so we can usefully mem::forget it! arena: &Bump, // This should be passed an owned value, not a reference, so we can usefully mem::forget it!
script_path: &Path, script_path: &Path,
opt_level: OptLevel, should_run_expects: bool,
args: I, args: I,
binary_bytes: &[u8], binary_bytes: &[u8],
_expect_metadata: ExpectMetadata, _expect_metadata: ExpectMetadata,
@ -1483,14 +1488,11 @@ fn roc_run_native<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(
.chain([std::ptr::null()]) .chain([std::ptr::null()])
.collect_in(arena); .collect_in(arena);
match opt_level { if should_run_expects {
OptLevel::Development => { // roc_run_native_debug(executable, &argv, &envp, expectations, interns)
// roc_run_native_debug(executable, &argv, &envp, expectations, interns) internal_error!("running `expect`s does not currently work on windows");
internal_error!("running `expect`s does not currently work on windows") } else {
} roc_run_native_fast(executable, &argv, &envp);
OptLevel::Normal | OptLevel::Size | OptLevel::Optimize => {
roc_run_native_fast(executable, &argv, &envp);
}
} }
} }

View file

@ -513,6 +513,7 @@ fn requires_space_after_unary(item: &Expr<'_>) -> bool {
is_negative, is_negative,
} => *is_negative, } => *is_negative,
Expr::RecordUpdater(..) => true, Expr::RecordUpdater(..) => true,
Expr::RecordAccess(inner, _field) => requires_space_after_unary(inner),
Expr::Apply(inner, _, _) => requires_space_after_unary(&inner.value), Expr::Apply(inner, _, _) => requires_space_after_unary(&inner.value),
Expr::TrySuffix { target: _, expr } => requires_space_after_unary(expr), Expr::TrySuffix { target: _, expr } => requires_space_after_unary(expr),
Expr::SpaceAfter(inner, _) | Expr::SpaceBefore(inner, _) => { Expr::SpaceAfter(inner, _) | Expr::SpaceBefore(inner, _) => {

View file

@ -685,7 +685,7 @@ macro_rules! debug_info_init {
pub enum LlvmBackendMode { pub enum LlvmBackendMode {
/// Assumes primitives (roc_alloc, roc_panic, etc) are provided by the host /// Assumes primitives (roc_alloc, roc_panic, etc) are provided by the host
Binary, Binary,
BinaryDev, BinaryWithExpect,
/// Creates a test wrapper around the main roc function to catch and report panics. /// Creates a test wrapper around the main roc function to catch and report panics.
/// Provides a testing implementation of primitives (roc_alloc, roc_panic, etc) /// Provides a testing implementation of primitives (roc_alloc, roc_panic, etc)
BinaryGlue, BinaryGlue,
@ -698,7 +698,7 @@ impl LlvmBackendMode {
pub(crate) fn has_host(self) -> bool { pub(crate) fn has_host(self) -> bool {
match self { match self {
LlvmBackendMode::Binary => true, LlvmBackendMode::Binary => true,
LlvmBackendMode::BinaryDev => true, LlvmBackendMode::BinaryWithExpect => true,
LlvmBackendMode::BinaryGlue => false, LlvmBackendMode::BinaryGlue => false,
LlvmBackendMode::GenTest => false, LlvmBackendMode::GenTest => false,
LlvmBackendMode::WasmGenTest => true, LlvmBackendMode::WasmGenTest => true,
@ -710,7 +710,7 @@ impl LlvmBackendMode {
fn returns_roc_result(self) -> bool { fn returns_roc_result(self) -> bool {
match self { match self {
LlvmBackendMode::Binary => false, LlvmBackendMode::Binary => false,
LlvmBackendMode::BinaryDev => false, LlvmBackendMode::BinaryWithExpect => false,
LlvmBackendMode::BinaryGlue => true, LlvmBackendMode::BinaryGlue => true,
LlvmBackendMode::GenTest => true, LlvmBackendMode::GenTest => true,
LlvmBackendMode::WasmGenTest => true, LlvmBackendMode::WasmGenTest => true,
@ -721,7 +721,7 @@ impl LlvmBackendMode {
pub(crate) fn runs_expects(self) -> bool { pub(crate) fn runs_expects(self) -> bool {
match self { match self {
LlvmBackendMode::Binary => false, LlvmBackendMode::Binary => false,
LlvmBackendMode::BinaryDev => true, LlvmBackendMode::BinaryWithExpect => true,
LlvmBackendMode::BinaryGlue => false, LlvmBackendMode::BinaryGlue => false,
LlvmBackendMode::GenTest => false, LlvmBackendMode::GenTest => false,
LlvmBackendMode::WasmGenTest => false, LlvmBackendMode::WasmGenTest => false,
@ -3559,12 +3559,10 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
variable: _, variable: _,
remainder, remainder,
} => { } => {
if env.mode.runs_expects() { let location = build_string_literal(env, source_location);
let location = build_string_literal(env, source_location); let source = build_string_literal(env, source);
let source = build_string_literal(env, source); let message = scope.load_symbol(symbol);
let message = scope.load_symbol(symbol); env.call_dbg(env, location, source, message);
env.call_dbg(env, location, source, message);
}
build_exp_stmt( build_exp_stmt(
env, env,
@ -3620,7 +3618,7 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
variables, variables,
); );
if let LlvmBackendMode::BinaryDev = env.mode { if let LlvmBackendMode::BinaryWithExpect = env.mode {
crate::llvm::expect::notify_parent_expect(env, &shared_memory); crate::llvm::expect::notify_parent_expect(env, &shared_memory);
} }
@ -4903,7 +4901,9 @@ fn expose_function_to_host_help_c_abi<'a, 'ctx>(
) )
} }
LlvmBackendMode::Binary | LlvmBackendMode::BinaryDev | LlvmBackendMode::BinaryGlue => {} LlvmBackendMode::Binary
| LlvmBackendMode::BinaryWithExpect
| LlvmBackendMode::BinaryGlue => {}
} }
// a generic version that writes the result into a passed *u8 pointer // a generic version that writes the result into a passed *u8 pointer
@ -4956,13 +4956,13 @@ fn expose_function_to_host_help_c_abi<'a, 'ctx>(
roc_call_result_type(env, roc_function.get_type().get_return_type().unwrap()).into() roc_call_result_type(env, roc_function.get_type().get_return_type().unwrap()).into()
} }
LlvmBackendMode::Binary | LlvmBackendMode::BinaryDev | LlvmBackendMode::BinaryGlue => { LlvmBackendMode::Binary
basic_type_from_layout( | LlvmBackendMode::BinaryWithExpect
env, | LlvmBackendMode::BinaryGlue => basic_type_from_layout(
layout_interner, env,
layout_interner.get_repr(return_layout), layout_interner,
) layout_interner.get_repr(return_layout),
} ),
}; };
let size: BasicValueEnum = return_type.size_of().unwrap().into(); let size: BasicValueEnum = return_type.size_of().unwrap().into();
@ -5759,7 +5759,7 @@ fn build_procedures_help<'a>(
use LlvmBackendMode::*; use LlvmBackendMode::*;
match env.mode { match env.mode {
GenTest | WasmGenTest | CliTest => { /* no host, or exposing types is not supported */ } GenTest | WasmGenTest | CliTest => { /* no host, or exposing types is not supported */ }
Binary | BinaryDev | BinaryGlue => { Binary | BinaryWithExpect | BinaryGlue => {
for (proc_name, alias_name, hels) in host_exposed_lambda_sets.iter() { for (proc_name, alias_name, hels) in host_exposed_lambda_sets.iter() {
let ident_string = proc_name.name().as_unsuffixed_str(&env.interns); let ident_string = proc_name.name().as_unsuffixed_str(&env.interns);
let fn_name: String = format!("{}_{}", ident_string, hels.id.0); let fn_name: String = format!("{}_{}", ident_string, hels.id.0);

View file

@ -29,7 +29,7 @@ pub(crate) struct SharedMemoryPointer<'ctx>(PointerValue<'ctx>);
impl<'ctx> SharedMemoryPointer<'ctx> { impl<'ctx> SharedMemoryPointer<'ctx> {
pub(crate) fn get<'a, 'env>(env: &Env<'a, 'ctx, 'env>) -> Self { pub(crate) fn get<'a, 'env>(env: &Env<'a, 'ctx, 'env>) -> Self {
let start_function = if let LlvmBackendMode::BinaryDev = env.mode { let start_function = if let LlvmBackendMode::BinaryWithExpect = env.mode {
bitcode::UTILS_EXPECT_FAILED_START_SHARED_FILE bitcode::UTILS_EXPECT_FAILED_START_SHARED_FILE
} else { } else {
bitcode::UTILS_EXPECT_FAILED_START_SHARED_BUFFER bitcode::UTILS_EXPECT_FAILED_START_SHARED_BUFFER

View file

@ -257,7 +257,7 @@ fn create_llvm_module<'a>(
}; };
let (main_fn_name, main_fn) = match config.mode { let (main_fn_name, main_fn) = match config.mode {
LlvmBackendMode::Binary => unreachable!(), LlvmBackendMode::Binary => unreachable!(),
LlvmBackendMode::BinaryDev => unreachable!(), LlvmBackendMode::BinaryWithExpect => unreachable!(),
LlvmBackendMode::BinaryGlue => unreachable!(), LlvmBackendMode::BinaryGlue => unreachable!(),
LlvmBackendMode::CliTest => unreachable!(), LlvmBackendMode::CliTest => unreachable!(),
LlvmBackendMode::WasmGenTest => roc_gen_llvm::llvm::build::build_wasm_test_wrapper( LlvmBackendMode::WasmGenTest => roc_gen_llvm::llvm::build::build_wasm_test_wrapper(

View file

@ -0,0 +1,49 @@
@0-8 SpaceAfter(
Defs(
Defs {
tags: [
EitherIndex(2147483648),
],
regions: [
@0-1,
],
space_before: [
Slice<roc_parse::ast::CommentOrNewline> { start: 0, length: 0 },
],
space_after: [
Slice<roc_parse::ast::CommentOrNewline> { start: 0, length: 0 },
],
spaces: [],
type_defs: [],
value_defs: [
Stmt(
@0-1 Num(
"4",
),
),
],
},
@2-8 SpaceBefore(
UnaryOp(
@4-6 SpaceBefore(
RecordAccess(
RecordUpdater(
"z",
),
"t",
),
[
Newline,
],
),
@2-3 Not,
),
[
Newline,
],
),
),
[
Newline,
],
)

View file

@ -514,6 +514,7 @@ mod test_snapshots {
pass/not_multiline_string.expr, pass/not_multiline_string.expr,
pass/not_record_updater.expr, pass/not_record_updater.expr,
pass/not_tag.expr, pass/not_tag.expr,
pass/num_bang_amp_z_dot_t.expr,
pass/number_literal_suffixes.expr, pass/number_literal_suffixes.expr,
pass/old_app_header.full, pass/old_app_header.full,
pass/old_interface_header.header, pass/old_interface_header.header,