diff --git a/crates/compiler/builtins/bitcode/src/dec.zig b/crates/compiler/builtins/bitcode/src/dec.zig index d60057843c9..cd9a8515022 100644 --- a/crates/compiler/builtins/bitcode/src/dec.zig +++ b/crates/compiler/builtins/bitcode/src/dec.zig @@ -252,7 +252,6 @@ pub const RocDec = extern struct { if (answer.has_overflowed) { roc_panic("Decimal addition overflowed!", 0); - unreachable; } else { return answer.value; } @@ -283,7 +282,6 @@ pub const RocDec = extern struct { if (answer.has_overflowed) { roc_panic("Decimal subtraction overflowed!", 0); - unreachable; } else { return answer.value; } @@ -347,7 +345,6 @@ pub const RocDec = extern struct { if (answer.has_overflowed) { roc_panic("Decimal multiplication overflowed!", 0); - unreachable; } else { return answer.value; } @@ -369,7 +366,7 @@ pub const RocDec = extern struct { // (n / 0) is an error if (denominator_i128 == 0) { - @panic("TODO runtime exception for dividing by 0!"); + roc_panic("Decimal division by 0!", 0); } // If they're both negative, or if neither is negative, the final answer @@ -397,7 +394,7 @@ pub const RocDec = extern struct { if (denominator_i128 == one_point_zero_i128) { return self; } else { - @panic("TODO runtime exception for overflow when dividing!"); + roc_panic("Decimal division overflow in numerator!", 0); } }; const numerator_u128 = @as(u128, @intCast(numerator_abs_i128)); @@ -410,7 +407,7 @@ pub const RocDec = extern struct { if (numerator_i128 == one_point_zero_i128) { return other; } else { - @panic("TODO runtime exception for overflow when dividing!"); + roc_panic("Decimal division overflow in denominator!", 0); } }; const denominator_u128 = @as(u128, @intCast(denominator_abs_i128)); @@ -422,7 +419,7 @@ pub const RocDec = extern struct { if (answer.hi == 0 and answer.lo <= math.maxInt(i128)) { unsigned_answer = @as(i128, @intCast(answer.lo)); } else { - @panic("TODO runtime exception for overflow when dividing!"); + roc_panic("Decimal division overflow!", 0); } return RocDec{ .num = if (is_answer_negative) -unsigned_answer else unsigned_answer }; @@ -636,7 +633,7 @@ fn mul_and_decimalize(a: u128, b: u128) i128 { const d = answer[0]; if (overflowed == 1) { - @panic("TODO runtime exception for overflow!"); + roc_panic("Decimal multiplication overflow!", 0); } // Final 512bit value is d, c, b, a @@ -1216,7 +1213,7 @@ pub fn fromF64C(arg: f64) callconv(.C) i128 { if (@call(.always_inline, RocDec.fromF64, .{arg})) |dec| { return dec.num; } else { - @panic("TODO runtime exception failing convert f64 to RocDec"); + roc_panic("Decimal conversion from f64 failed!", 0); } } @@ -1225,7 +1222,7 @@ pub fn fromF32C(arg_f32: f32) callconv(.C) i128 { if (@call(.always_inline, RocDec.fromF64, .{arg_f64})) |dec| { return dec.num; } else { - @panic("TODO runtime exception failing convert f64 to RocDec"); + roc_panic("Decimal conversion from f32!", 0); } } @@ -1240,7 +1237,7 @@ pub fn exportFromInt(comptime T: type, comptime name: []const u8) void { const answer = @mulWithOverflow(this, RocDec.one_point_zero_i128); if (answer[1] == 1) { - @panic("TODO runtime exception failing convert integer to RocDec"); + roc_panic("Decimal conversion from Integer failed!", 0); } else { return answer[0]; } @@ -1266,11 +1263,15 @@ pub fn neqC(arg1: RocDec, arg2: RocDec) callconv(.C) bool { } pub fn negateC(arg: RocDec) callconv(.C) i128 { - return if (@call(.always_inline, RocDec.negate, .{arg})) |dec| dec.num else @panic("TODO overflow for negating RocDec"); + return if (@call(.always_inline, RocDec.negate, .{arg})) |dec| dec.num else { + roc_panic("Decimal negation overflow!", 0); + }; } pub fn absC(arg: RocDec) callconv(.C) i128 { - const result = @call(.always_inline, RocDec.abs, .{arg}) catch @panic("TODO overflow for calling absolute value on RocDec"); + const result = @call(.always_inline, RocDec.abs, .{arg}) catch { + roc_panic("Decimal absolute value overflow!", 0); + }; return result.num; } diff --git a/crates/compiler/builtins/bitcode/src/num.zig b/crates/compiler/builtins/bitcode/src/num.zig index c978af99e19..eb7c532dd43 100644 --- a/crates/compiler/builtins/bitcode/src/num.zig +++ b/crates/compiler/builtins/bitcode/src/num.zig @@ -233,7 +233,9 @@ pub fn exportCeiling(comptime F: type, comptime T: type, comptime name: []const pub fn exportDivCeil(comptime T: type, comptime name: []const u8) void { comptime var f = struct { fn func(a: T, b: T) callconv(.C) T { - return math.divCeil(T, a, b) catch @panic("TODO runtime exception for dividing by 0!"); + return math.divCeil(T, a, b) catch { + roc_panic("Integer division by 0!", 0); + }; } }.func; @export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong }); @@ -379,8 +381,7 @@ pub fn exportAddOrPanic(comptime T: type, comptime name: []const u8) void { fn func(self: T, other: T) callconv(.C) T { const result = addWithOverflow(T, self, other); if (result.has_overflowed) { - roc_panic("integer addition overflowed!", 0); - unreachable; + roc_panic("Integer addition overflowed!", 0); } else { return result.value; } @@ -437,8 +438,7 @@ pub fn exportSubOrPanic(comptime T: type, comptime name: []const u8) void { fn func(self: T, other: T) callconv(.C) T { const result = subWithOverflow(T, self, other); if (result.has_overflowed) { - roc_panic("integer subtraction overflowed!", 0); - unreachable; + roc_panic("Integer subtraction overflowed!", 0); } else { return result.value; } @@ -622,8 +622,7 @@ pub fn exportMulOrPanic(comptime T: type, comptime W: type, comptime name: []con fn func(self: T, other: T) callconv(.C) T { const result = @call(.always_inline, mulWithOverflow, .{ T, W, self, other }); if (result.has_overflowed) { - roc_panic("integer multiplication overflowed!", 0); - unreachable; + roc_panic("Integer multiplication overflowed!", 0); } else { return result.value; } diff --git a/crates/compiler/builtins/bitcode/src/panic.zig b/crates/compiler/builtins/bitcode/src/panic.zig index 76ecd69e123..13224a67df1 100644 --- a/crates/compiler/builtins/bitcode/src/panic.zig +++ b/crates/compiler/builtins/bitcode/src/panic.zig @@ -2,14 +2,14 @@ const std = @import("std"); const RocStr = @import("str.zig").RocStr; // Signals to the host that the program has panicked -extern fn roc_panic(msg: *const RocStr, tag_id: u32) callconv(.C) void; +extern fn roc_panic(msg: *const RocStr, tag_id: u32) callconv(.C) noreturn; -pub fn panic_help(msg: []const u8, tag_id: u32) void { +pub fn panic_help(msg: []const u8, tag_id: u32) noreturn { var str = RocStr.init(msg.ptr, msg.len); roc_panic(&str, tag_id); } // must export this explicitly because right now it is not used from zig code -pub fn panic(msg: *const RocStr, alignment: u32) callconv(.C) void { +pub fn panic(msg: *const RocStr, alignment: u32) callconv(.C) noreturn { return roc_panic(msg, alignment); } diff --git a/crates/compiler/gen_llvm/src/llvm/lowlevel.rs b/crates/compiler/gen_llvm/src/llvm/lowlevel.rs index ea9fbdecf35..8590762267f 100644 --- a/crates/compiler/gen_llvm/src/llvm/lowlevel.rs +++ b/crates/compiler/gen_llvm/src/llvm/lowlevel.rs @@ -1535,7 +1535,7 @@ fn build_int_binop<'ctx>( ) .into_struct_value(); - throw_on_overflow(env, parent, result, "integer addition overflowed!") + throw_on_overflow(env, parent, result, "Integer addition overflowed!") } NumAddWrap => bd.new_build_int_add(lhs, rhs, "add_int_wrap").into(), NumAddChecked => { @@ -1566,7 +1566,7 @@ fn build_int_binop<'ctx>( ) .into_struct_value(); - throw_on_overflow(env, parent, result, "integer subtraction overflowed!") + throw_on_overflow(env, parent, result, "Integer subtraction overflowed!") } NumSubWrap => bd.new_build_int_sub(lhs, rhs, "sub_int").into(), NumSubChecked => { @@ -1597,7 +1597,7 @@ fn build_int_binop<'ctx>( ) .into_struct_value(); - throw_on_overflow(env, parent, result, "integer multiplication overflowed!") + throw_on_overflow(env, parent, result, "Integer multiplication overflowed!") } NumMulWrap => bd.new_build_int_mul(lhs, rhs, "mul_int").into(), NumMulSaturated => call_bitcode_fn( @@ -2350,7 +2350,7 @@ fn build_dec_binop<'a, 'ctx>( bitcode::DEC_ADD_WITH_OVERFLOW, lhs, rhs, - "decimal addition overflowed", + "Decimal addition overflowed", ), NumSub => build_dec_binop_throw_on_overflow( env, @@ -2358,7 +2358,7 @@ fn build_dec_binop<'a, 'ctx>( bitcode::DEC_SUB_WITH_OVERFLOW, lhs, rhs, - "decimal subtraction overflowed", + "Decimal subtraction overflowed", ), NumMul => build_dec_binop_throw_on_overflow( env, @@ -2366,7 +2366,7 @@ fn build_dec_binop<'a, 'ctx>( bitcode::DEC_MUL_WITH_OVERFLOW, lhs, rhs, - "decimal multiplication overflowed", + "Decimal multiplication overflowed", ), NumDivFrac => dec_binop_with_unchecked(env, bitcode::DEC_DIV, lhs, rhs), @@ -2659,7 +2659,7 @@ fn int_neg_raise_on_overflow<'ctx>( throw_internal_exception( env, parent, - "integer negation overflowed because its argument is the minimum value", + "Integer negation overflowed because its argument is the minimum value", ); builder.position_at_end(else_block); @@ -2690,7 +2690,7 @@ fn int_abs_raise_on_overflow<'ctx>( throw_internal_exception( env, parent, - "integer absolute overflowed because its argument is the minimum value", + "Integer absolute overflowed because its argument is the minimum value", ); builder.position_at_end(else_block); diff --git a/crates/compiler/gen_wasm/src/low_level.rs b/crates/compiler/gen_wasm/src/low_level.rs index cb66ab10c2e..dfbb8420af7 100644 --- a/crates/compiler/gen_wasm/src/low_level.rs +++ b/crates/compiler/gen_wasm/src/low_level.rs @@ -1382,7 +1382,7 @@ impl<'a> LowLevelCall<'a> { } NumAbs => { const PANIC_MSG: &str = - "integer absolute overflowed because its argument is the minimum value"; + "Integer absolute overflowed because its argument is the minimum value"; self.load_args(backend); @@ -1446,7 +1446,7 @@ impl<'a> LowLevelCall<'a> { } NumNeg => { const PANIC_MSG: &str = - "integer negation overflowed because its argument is the minimum value"; + "Integer negation overflowed because its argument is the minimum value"; self.load_args(backend); match CodeGenNumType::from(self.ret_layout) { diff --git a/crates/compiler/test_gen/src/gen_list.rs b/crates/compiler/test_gen/src/gen_list.rs index db6863b8daf..fc7aa3736df 100644 --- a/crates/compiler/test_gen/src/gen_list.rs +++ b/crates/compiler/test_gen/src/gen_list.rs @@ -2934,7 +2934,7 @@ fn list_map_with_index() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[should_panic(expected = r#"Roc failed with message: "integer addition overflowed!"#)] +#[should_panic(expected = r#"Roc failed with message: "Integer addition overflowed!"#)] fn cleanup_because_exception() { assert_evals_to!( indoc!( diff --git a/crates/compiler/test_gen/src/gen_num.rs b/crates/compiler/test_gen/src/gen_num.rs index c6651b94164..077f81ea97c 100644 --- a/crates/compiler/test_gen/src/gen_num.rs +++ b/crates/compiler/test_gen/src/gen_num.rs @@ -575,7 +575,7 @@ fn various_sized_abs() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] #[should_panic( - expected = r#"Roc failed with message: "integer absolute overflowed because its argument is the minimum value"# + expected = r#"Roc failed with message: "Integer absolute overflowed because its argument is the minimum value"# )] fn abs_min_int_overflow() { assert_evals_to!( @@ -799,6 +799,26 @@ fn gen_div_checked_by_zero_dec() { ); } +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +#[should_panic(expected = r#"Roc failed with message: "Decimal division by 0!"#)] +fn gen_div_dec_by_zero() { + assert_evals_to!("1dec / 0", RocDec::from_str_to_i128_unsafe("-1"), i128); +} + +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +#[should_panic(expected = r#"Roc failed with message: "Integer division by 0!"#)] +fn gen_div_ceil_by_zero() { + assert_evals_to!( + r#" + Num.divCeil 5 0 == 0 + "#, + false, + bool + ); +} + #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))] fn gen_int_eq() { @@ -1581,7 +1601,7 @@ fn int_negate() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] #[should_panic( - expected = r#"Roc failed with message: "integer negation overflowed because its argument is the minimum value"# + expected = r#"Roc failed with message: "Integer negation overflowed because its argument is the minimum value"# )] fn neg_min_int_overflow() { assert_evals_to!( @@ -1809,7 +1829,7 @@ fn atan() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[should_panic(expected = r#"Roc failed with message: "integer addition overflowed!"#)] +#[should_panic(expected = r#"Roc failed with message: "Integer addition overflowed!"#)] fn int_add_overflow() { assert_evals_to!( indoc!( @@ -1884,7 +1904,7 @@ fn float_add_overflow() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[should_panic(expected = r#"Roc failed with message: "integer subtraction overflowed!"#)] +#[should_panic(expected = r#"Roc failed with message: "Integer subtraction overflowed!"#)] fn int_sub_overflow() { assert_evals_to!("-9_223_372_036_854_775_808 - 1", 0, i64); } @@ -1969,7 +1989,7 @@ fn float_sub_checked() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[should_panic(expected = r#"Roc failed with message: "integer multiplication overflowed!"#)] +#[should_panic(expected = r#"Roc failed with message: "Integer multiplication overflowed!"#)] fn int_positive_mul_overflow() { assert_evals_to!( indoc!( @@ -1984,7 +2004,7 @@ fn int_positive_mul_overflow() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[should_panic(expected = r#"Roc failed with message: "integer multiplication overflowed!"#)] +#[should_panic(expected = r#"Roc failed with message: "Integer multiplication overflowed!"#)] fn int_negative_mul_overflow() { assert_evals_to!( indoc!( @@ -3907,21 +3927,21 @@ fn num_abs_diff_float() { #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[should_panic(expected = r#"Roc failed with message: "integer subtraction overflowed!"#)] +#[should_panic(expected = r#"Roc failed with message: "Integer subtraction overflowed!"#)] fn num_abs_max_overflow() { assert_evals_to!(r#"Num.absDiff Num.maxI64 -1"#, 0, i64); } #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] -#[should_panic(expected = r#"Roc failed with message: "integer subtraction overflowed!"#)] +#[should_panic(expected = r#"Roc failed with message: "Integer subtraction overflowed!"#)] fn num_abs_int_min_overflow() { assert_evals_to!(r#"Num.absDiff Num.minI64 0"#, 0, i64); } #[test] #[cfg(feature = "gen-llvm")] -#[should_panic(expected = r#"Roc failed with message: "integer subtraction overflowed!"#)] +#[should_panic(expected = r#"Roc failed with message: "Integer subtraction overflowed!"#)] fn num_abs_large_bits_min_overflow() { assert_evals_to!(r#"Num.absDiff Num.minI128 0"#, 0, i128); } diff --git a/crates/lang_srv/debug_server.sh b/crates/lang_srv/debug_server.sh index 5510f3d8d7d..427c81be671 100755 --- a/crates/lang_srv/debug_server.sh +++ b/crates/lang_srv/debug_server.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/bash SCRIPT_DIR=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd) ${SCRIPT_DIR}/../../target/debug/roc_ls "$@" 2> /tmp/roc_ls.err diff --git a/crates/repl_wasm/README.md b/crates/repl_wasm/README.md index be6731426cc..5f4cd8fb587 100644 --- a/crates/repl_wasm/README.md +++ b/crates/repl_wasm/README.md @@ -14,13 +14,14 @@ crates/repl_wasm/build-www.sh ### 2. Make symlinks to the generated Wasm and JS ```bash -cd www/public +mkdir -p www/public/repl +cd www/public/repl ln -s ../../../crates/repl_wasm/build/roc_repl_wasm_bg.wasm ln -s ../../../crates/repl_wasm/build/roc_repl_wasm.js ``` These symlinks are ignored by Git. -> This is a bit different from the production build, where we copy all the files to `www/build/`. But for development, it's convenient to have just one copy of files like `www/public/repl.js`. You can make changes, reload your browser to see them, and commit them to Git, without getting mixed up between different copies of the same file. +> This is a bit different from the production build, where we copy all the files to `www/build/`. But for development, it's convenient to have just one copy of files like `www/public/repl/repl.js`. You can make changes, reload your browser to see them, and commit them to Git, without getting mixed up between different copies of the same file. ### 3. Run a local HTTP server diff --git a/flake.nix b/flake.nix index b94a9c69e00..8652e8f9630 100644 --- a/flake.nix +++ b/flake.nix @@ -91,6 +91,7 @@ wasm-pack # for repl_wasm jq # used in several bash scripts cargo-nextest # used to give more info for segfaults for gen tests + zls # zig language server ]); aliases = '' @@ -135,7 +136,7 @@ # You can build this package (the roc CLI) with the `nix build` command. packages = { default = rocBuild.roc-cli; - + # all rust crates in workspace.members of Cargo.toml full = rocBuild.roc-full; # only the CLI crate = executable provided in nightly releases diff --git a/www/.gitignore b/www/.gitignore new file mode 100644 index 00000000000..9bc9fa870c6 --- /dev/null +++ b/www/.gitignore @@ -0,0 +1,2 @@ +# ignore a symlink to the wasm repl code +public/repl \ No newline at end of file