diff --git a/crates/compiler/builtins/roc/Num.roc b/crates/compiler/builtins/roc/Num.roc index 9a712367da..9280d49003 100644 --- a/crates/compiler/builtins/roc/Num.roc +++ b/crates/compiler/builtins/roc/Num.roc @@ -868,7 +868,7 @@ bitwiseOr : Int a, Int a -> Int a ## >>> 0b0000_0101 |> shiftLeftBy 2 == 0b0000_1100 ## ## In some languages `shiftLeftBy` is implemented as a binary operator `<<`. -shiftLeftBy : Int a, Int a -> Int a +shiftLeftBy : Int a, U8 -> Int a ## Bitwise arithmetic shift of a number by another ## @@ -881,7 +881,7 @@ shiftLeftBy : Int a, Int a -> Int a ## >>> 0b1001_0000 |> shiftRightBy 2 == 0b1110_0100 ## ## In some languages `shiftRightBy` is implemented as a binary operator `>>>`. -shiftRightBy : Int a, Int a -> Int a +shiftRightBy : Int a, U8 -> Int a ## Bitwise logical right shift of a number by another ## @@ -895,7 +895,7 @@ shiftRightBy : Int a, Int a -> Int a ## >>> 0b1001_0000 |> shiftRightBy 2 == 0b0010_0100 ## ## In some languages `shiftRightBy` is implemented as a binary operator `>>`. -shiftRightZfBy : Int a, Int a -> Int a +shiftRightZfBy : Int a, U8 -> Int a ## Round off the given fraction to the nearest integer. round : Frac * -> Int * diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index 6f961c26e3..e3c9f27ff9 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -6448,9 +6448,23 @@ fn run_low_level<'a, 'ctx, 'env>( let (lhs_arg, lhs_layout) = load_symbol_and_layout(scope, &args[0]); let (rhs_arg, rhs_layout) = load_symbol_and_layout(scope, &args[1]); - debug_assert_eq!(lhs_layout, rhs_layout); let int_width = intwidth_from_layout(*lhs_layout); + debug_assert_eq!(rhs_layout, &Layout::Builtin(Builtin::Int(IntWidth::U8))); + let rhs_arg = if rhs_layout != lhs_layout { + // LLVM shift intrinsics expect the left and right sides to have the same type, so + // here we cast up `rhs` to the lhs type. Since the rhs was checked to be a U8, + // this cast isn't lossy. + let rhs_arg = env.builder.build_int_cast( + rhs_arg.into_int_value(), + lhs_arg.get_type().into_int_type(), + "cast_for_shift", + ); + rhs_arg.into() + } else { + rhs_arg + }; + build_int_binop( env, parent, diff --git a/crates/compiler/test_gen/src/gen_num.rs b/crates/compiler/test_gen/src/gen_num.rs index 045ae3dd5d..f014b1a750 100644 --- a/crates/compiler/test_gen/src/gen_num.rs +++ b/crates/compiler/test_gen/src/gen_num.rs @@ -2075,6 +2075,7 @@ fn shift_left_by() { assert_evals_to!("Num.shiftLeftBy 0b0000_0001 0", 0b0000_0001, i64); assert_evals_to!("Num.shiftLeftBy 0b0000_0001 1", 0b0000_0010, i64); assert_evals_to!("Num.shiftLeftBy 0b0000_0011 2", 0b0000_1100, i64); + assert_evals_to!("Num.shiftLeftBy 2u16 2", 8, u16); } #[test] @@ -2104,7 +2105,6 @@ fn shift_right_by() { assert_evals_to!("Num.shiftRightBy -12 1", -6, i64); assert_evals_to!("Num.shiftRightBy 12 8", 0, i64); assert_evals_to!("Num.shiftRightBy -12 8", -1, i64); - assert_evals_to!("Num.shiftRightBy 12 -1", 0, i64); assert_evals_to!("Num.shiftRightBy 0 0", 0, i64); assert_evals_to!("Num.shiftRightBy 0 1", 0, i64); @@ -2120,8 +2120,6 @@ fn shift_right_by() { assert_evals_to!("Num.shiftRightBy 12i8 8", 0, i8); if !is_llvm_release_mode { - assert_evals_to!("Num.shiftRightBy 0 -1", 0, i64); - assert_evals_to!("Num.shiftRightBy -12 -1", -1, i64); assert_evals_to!("Num.shiftRightBy -12i8 8", -1, i8); } } diff --git a/crates/reporting/tests/test_reporting.rs b/crates/reporting/tests/test_reporting.rs index 142e7f2b36..7fc1cba002 100644 --- a/crates/reporting/tests/test_reporting.rs +++ b/crates/reporting/tests/test_reporting.rs @@ -10848,4 +10848,63 @@ All branches in an `if` must have the same type! Tip: Did you mean to use `Bool.false` rather than `False`? "### ); + + test_report!( + shift_by_negative, + indoc!( + r#" + { + a: Num.shiftLeftBy 1 -1, + b: Num.shiftRightBy 1 -1, + c: Num.shiftRightZfBy 1 -1, + } + "# + ), + @r###" + ── TYPE MISMATCH ───────────────────────────────────────── /code/proj/Main.roc ─ + + This 2nd argument to `shiftRightZfBy` has an unexpected type: + + 7│ c: Num.shiftRightZfBy 1 -1, + ^^ + + The argument is a number of type: + + I8, I16, F32, I32, F64, I64, I128, or Dec + + But `shiftRightZfBy` needs its 2nd argument to be: + + U8 + + ── TYPE MISMATCH ───────────────────────────────────────── /code/proj/Main.roc ─ + + This 2nd argument to `shiftRightBy` has an unexpected type: + + 6│ b: Num.shiftRightBy 1 -1, + ^^ + + The argument is a number of type: + + I8, I16, F32, I32, F64, I64, I128, or Dec + + But `shiftRightBy` needs its 2nd argument to be: + + U8 + + ── TYPE MISMATCH ───────────────────────────────────────── /code/proj/Main.roc ─ + + This 2nd argument to `shiftLeftBy` has an unexpected type: + + 5│ a: Num.shiftLeftBy 1 -1, + ^^ + + The argument is a number of type: + + I8, I16, F32, I32, F64, I64, I128, or Dec + + But `shiftLeftBy` needs its 2nd argument to be: + + U8 + "### + ); } diff --git a/examples/breakout/platform/Cargo.lock b/examples/breakout/platform/Cargo.lock index f48422aeb4..4d22e73d60 100644 --- a/examples/breakout/platform/Cargo.lock +++ b/examples/breakout/platform/Cargo.lock @@ -44,15 +44,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - [[package]] name = "alsa" version = "0.5.0" @@ -752,19 +743,6 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" -[[package]] -name = "env_logger" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - [[package]] name = "fake-simd" version = "0.1.2" @@ -1061,7 +1039,6 @@ dependencies = [ "colored", "confy", "copypasta", - "env_logger", "fs_extra", "futures", "glyph_brush", @@ -1088,12 +1065,6 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "ident_case" version = "1.0.1" @@ -2071,8 +2042,6 @@ version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ - "aho-corasick", - "memchr", "regex-syntax", ] diff --git a/examples/gui/platform/Cargo.lock b/examples/gui/platform/Cargo.lock index f48422aeb4..4d22e73d60 100644 --- a/examples/gui/platform/Cargo.lock +++ b/examples/gui/platform/Cargo.lock @@ -44,15 +44,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - [[package]] name = "alsa" version = "0.5.0" @@ -752,19 +743,6 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" -[[package]] -name = "env_logger" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - [[package]] name = "fake-simd" version = "0.1.2" @@ -1061,7 +1039,6 @@ dependencies = [ "colored", "confy", "copypasta", - "env_logger", "fs_extra", "futures", "glyph_brush", @@ -1088,12 +1065,6 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "ident_case" version = "1.0.1" @@ -2071,8 +2042,6 @@ version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ - "aho-corasick", - "memchr", "regex-syntax", ]