From cba8cd89a1ade4907754f234a9c1d1b8c03e8dae Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 13 May 2023 19:02:11 +0200 Subject: [PATCH 1/7] cargo-miri: fix forwarding arguments to cargo --- cargo-miri/src/arg.rs | 8 +++--- cargo-miri/src/phases.rs | 52 +++++++++++++++++++------------------ test-cargo-miri/run-test.py | 3 ++- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/cargo-miri/src/arg.rs b/cargo-miri/src/arg.rs index e8bac4625f..d721606035 100644 --- a/cargo-miri/src/arg.rs +++ b/cargo-miri/src/arg.rs @@ -40,7 +40,8 @@ impl<'s, I: Iterator>> Iterator for ArgSplitFlagValue<'_, I> if arg == "--" { // Stop searching at `--`. self.args = None; - return None; + // But yield the `--` so that it does not get lost! + return Some(Err(Cow::Borrowed("--"))); } // These branches cannot be merged if we want to avoid the allocation in the `Borrowed` branch. match &arg { @@ -79,9 +80,8 @@ impl<'a, I: Iterator + 'a> ArgSplitFlagValue<'a, I> { ) -> impl Iterator> + 'a { ArgSplitFlagValue::new(args.map(Cow::Owned), name).map(|x| { match x { - Ok(Cow::Owned(s)) => Ok(s), - Err(Cow::Owned(s)) => Err(s), - _ => panic!("iterator converted owned to borrowed"), + Ok(s) => Ok(s.into_owned()), + Err(s) => Err(s.into_owned()), } }) } diff --git a/cargo-miri/src/phases.rs b/cargo-miri/src/phases.rs index 37f66d0033..465e4a1b2d 100644 --- a/cargo-miri/src/phases.rs +++ b/cargo-miri/src/phases.rs @@ -113,30 +113,17 @@ pub fn phase_cargo_miri(mut args: impl Iterator) { }; let metadata = get_cargo_metadata(); let mut cmd = cargo(); - cmd.arg(cargo_cmd); - - // Forward all arguments before `--` other than `--target-dir` and its value to Cargo. - // (We want to *change* the target-dir value, so we must not forward it.) - let mut target_dir = None; - for arg in ArgSplitFlagValue::from_string_iter(&mut args, "--target-dir") { - match arg { - Ok(value) => { - if target_dir.is_some() { - show_error!("`--target-dir` is provided more than once"); - } - target_dir = Some(value.into()); - } - Err(arg) => { - cmd.arg(arg); - } - } + cmd.arg(&cargo_cmd); + // In nextest we have to also forward the main `verb`. + if cargo_cmd == "nextest" { + cmd.arg( + args.next() + .unwrap_or_else(|| show_error!("`cargo miri nextest` expects a verb (e.g. `run`)")), + ); } - // Detect the target directory if it's not specified via `--target-dir`. - // (`cargo metadata` does not support `--target-dir`, that's why we have to handle this ourselves.) - let target_dir = target_dir.get_or_insert_with(|| metadata.target_directory.clone()); - // Set `--target-dir` to `miri` inside the original target directory. - target_dir.push("miri"); - cmd.arg("--target-dir").arg(target_dir); + // We set the following flags *before* forwarding more arguments. + // This is needed to fix : cargo will stop + // interpreting things as flags when it sees the first positional argument. // Make sure the build target is explicitly set. // This is needed to make the `target.runner` settings do something, @@ -154,8 +141,23 @@ pub fn phase_cargo_miri(mut args: impl Iterator) { cmd.arg("--config") .arg(format!("target.'cfg(all())'.runner=[{cargo_miri_path_for_toml}, 'runner']")); - // Forward all further arguments after `--` to cargo. - cmd.arg("--").args(args); + // Set `--target-dir` to `miri` inside the original target directory. + let mut target_dir = match get_arg_flag_value("--target-dir") { + Some(dir) => PathBuf::from(dir), + None => metadata.target_directory.clone().into_std_path_buf(), + }; + target_dir.push("miri"); + cmd.arg("--target-dir").arg(target_dir); + + // *After* we set all the flags that need setting, forward everything else. Make sure to skip + // `--target-dir` (which would otherwise be set twice). + for arg in + ArgSplitFlagValue::from_string_iter(&mut args, "--target-dir").filter_map(Result::err) + { + cmd.arg(arg); + } + // Forward all further arguments (not consumed by `ArgSplitFlagValue`) to cargo. + cmd.args(args); // Set `RUSTC_WRAPPER` to ourselves. Cargo will prepend that binary to its usual invocation, // i.e., the first argument is `rustc` -- which is what we use in `main` to distinguish diff --git a/test-cargo-miri/run-test.py b/test-cargo-miri/run-test.py index 46b3afa70e..9df90c725e 100755 --- a/test-cargo-miri/run-test.py +++ b/test-cargo-miri/run-test.py @@ -108,8 +108,9 @@ def test_cargo_miri_run(): env={'MIRITESTVAR': "wrongval"}, # changing the env var causes a rebuild (re-runs build.rs), # so keep it set ) + # This also covers passing arguments without `--`: Cargo will forward unused positional arguments to the program. test("`cargo miri run` (with arguments and target)", - cargo_miri("run") + ["--bin", "cargo-miri-test", "--", "hello world", '"hello world"', r'he\\llo\"world'], + cargo_miri("run") + ["--bin", "cargo-miri-test", "hello world", '"hello world"', r'he\\llo\"world'], "run.args.stdout.ref", "run.args.stderr.ref", ) test("`cargo miri r` (subcrate, no isolation)", From 54e1bd0553e5890a03ed5709b032dc49a549d43d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 13 May 2023 18:19:48 +0200 Subject: [PATCH 2/7] support array return types in simd_bitmask --- src/shims/intrinsics/simd.rs | 11 +++++++++-- tests/pass/portable-simd.rs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/shims/intrinsics/simd.rs b/src/shims/intrinsics/simd.rs index 114c66253f..4acb2201ad 100644 --- a/src/shims/intrinsics/simd.rs +++ b/src/shims/intrinsics/simd.rs @@ -563,7 +563,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let (op, op_len) = this.operand_to_simd(op)?; let bitmask_len = op_len.max(8); - assert!(dest.layout.ty.is_integral()); + // Returns either an unsigned integer or array of `u8`. + assert!( + dest.layout.ty.is_integral() + || matches!(dest.layout.ty.kind(), ty::Array(elemty, _) if elemty == &this.tcx.types.u8) + ); assert!(bitmask_len <= 64); assert_eq!(bitmask_len, dest.layout.size.bits()); let op_len = u32::try_from(op_len).unwrap(); @@ -577,7 +581,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { .unwrap(); } } - this.write_int(res, dest)?; + // We have to force the place type to be an int so that we can write `res` into it. + let mut dest = this.force_allocation(dest)?; + dest.layout = this.machine.layouts.uint(dest.layout.size).unwrap(); + this.write_int(res, &dest.into())?; } name => throw_unsup_format!("unimplemented intrinsic: `simd_{name}`"), diff --git a/tests/pass/portable-simd.rs b/tests/pass/portable-simd.rs index 173ac654b0..ee67a65a4f 100644 --- a/tests/pass/portable-simd.rs +++ b/tests/pass/portable-simd.rs @@ -2,6 +2,10 @@ #![feature(portable_simd, platform_intrinsics)] use std::simd::*; +extern "platform-intrinsic" { + pub(crate) fn simd_bitmask(x: T) -> U; +} + fn simd_ops_f32() { let a = f32x4::splat(10.0); let b = f32x4::from_array([1.0, 2.0, 3.0, -4.0]); @@ -208,11 +212,40 @@ fn simd_mask() { assert_eq!(bitmask, 0b1010001101001001); assert_eq!(Mask::::from_bitmask(bitmask), mask); + // Also directly call intrinsic, to test both kinds of return types. + unsafe { + let bitmask1: u16 = simd_bitmask(mask.to_int()); + let bitmask2: [u8; 2] = simd_bitmask(mask.to_int()); + if cfg!(target_endian = "little") { + assert_eq!(bitmask1, 0b1010001101001001); + assert_eq!(bitmask2, [0b01001001, 0b10100011]); + } else { + // All the bitstrings are reversed compared to above, but the array elements are in the + // same order. + assert_eq!(bitmask1, 0b1001001011000101); + assert_eq!(bitmask2, [0b10010010, 0b11000101]); + } + } + + // Mask less than 8 bits long, which is a special case (padding with 0s). let values = [false, false, false, true]; let mask = Mask::::from_array(values); let bitmask = mask.to_bitmask(); assert_eq!(bitmask, 0b1000); assert_eq!(Mask::::from_bitmask(bitmask), mask); + + // Also directly call intrinsic, to test both kinds of return types. + unsafe { + let bitmask1: u8 = simd_bitmask(mask.to_int()); + let bitmask2: [u8; 1] = simd_bitmask(mask.to_int()); + if cfg!(target_endian = "little") { + assert_eq!(bitmask1, 0b1000); + assert_eq!(bitmask2, [0b1000]); + } else { + assert_eq!(bitmask1, 0b0001); + assert_eq!(bitmask2, [0b0001]); + } + } } fn simd_cast() { From 9419750fd3ef9ae38e44e47ad14c0ddad1adb463 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 16 May 2023 10:34:29 +0200 Subject: [PATCH 3/7] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index b450f98614..581d1a715b 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -69fef92ab2f287f072b66fb7b4f62c8bb4acba43 +3ea9ad532474343426e564b997891e459cda89a6 From 26f0f3fc63fcc0b24e6f2174f49dceb9e29d6dff Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 18 May 2023 11:00:59 +0200 Subject: [PATCH 4/7] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 581d1a715b..39346fbd84 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -3ea9ad532474343426e564b997891e459cda89a6 +77c836e1ae582661924d3b6ec4d57a2de120f59f From e0080bf9b6d6f84e531bde57b5c9ed0f9d07660f Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 19 May 2023 13:49:24 -0400 Subject: [PATCH 5/7] Use a signal handler to observe ctrl+c and cleanly drop the measureme profiler --- Cargo.lock | 29 +++++++++++++++++++++++++++++ Cargo.toml | 1 + src/concurrency/thread.rs | 17 +++++++++++++++++ src/machine.rs | 9 +++++++++ 4 files changed, 56 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 737423a2cd..7bedb5d48f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,6 +183,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "ctrlc" +version = "3.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639" +dependencies = [ + "nix", + "windows-sys 0.45.0", +] + [[package]] name = "diff" version = "0.1.13" @@ -421,6 +431,7 @@ name = "miri" version = "0.1.0" dependencies = [ "colored", + "ctrlc", "env_logger", "getrandom", "lazy_static", @@ -437,6 +448,18 @@ dependencies = [ "ui_test", ] +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "static_assertions", +] + [[package]] name = "object" version = "0.30.3" @@ -713,6 +736,12 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "syn" version = "2.0.15" diff --git a/Cargo.toml b/Cargo.toml index 5987b0df8d..683f99ca4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ smallvec = "1.7" # for more information. rustc-workspace-hack = "1.0.0" measureme = "10.0.0" +ctrlc = "3.2.5" [target.'cfg(unix)'.dependencies] libc = "0.2" diff --git a/src/concurrency/thread.rs b/src/concurrency/thread.rs index e9bbae4d50..d85cac7bcb 100644 --- a/src/concurrency/thread.rs +++ b/src/concurrency/thread.rs @@ -3,6 +3,7 @@ use std::cell::RefCell; use std::collections::hash_map::Entry; use std::num::TryFromIntError; +use std::sync::atomic::{AtomicBool, Ordering::Relaxed}; use std::task::Poll; use std::time::{Duration, SystemTime}; @@ -1012,8 +1013,24 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// Run the core interpreter loop. Returns only when an interrupt occurs (an error or program /// termination). fn run_threads(&mut self) -> InterpResult<'tcx, !> { + static SIGNALED: AtomicBool = AtomicBool::new(false); + ctrlc::set_handler(move || { + // Indicate that we have ben signaled to stop. If we were already signaled, exit + // immediately. In our interpreter loop we try to consult this value often, but if for + // whatever reason we don't get to that check or the cleanup we do upon finding that + // this bool has become true takes a long time, the exit here will promptly exit the + // process on the second Ctrl-C. + if SIGNALED.swap(true, Relaxed) { + std::process::exit(1); + } + }) + .unwrap(); let this = self.eval_context_mut(); loop { + if SIGNALED.load(Relaxed) { + this.machine.handle_abnormal_termination(); + std::process::exit(1); + } match this.machine.threads.schedule(&this.machine.clock)? { SchedulingAction::ExecuteStep => { if !this.step()? { diff --git a/src/machine.rs b/src/machine.rs index 32717a0d28..29f518fe58 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -713,6 +713,15 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { let def_id = frame.instance.def_id(); def_id.is_local() || self.local_crates.contains(&def_id.krate) } + + /// Called when the interpreter is going to shut down abnormally, such as due to a Ctrl-C. + pub(crate) fn handle_abnormal_termination(&mut self) { + // All strings in the profile data are stored in a single string table which is not + // written to disk until the profiler is dropped. If the interpreter exits without dropping + // the profiler, it is not possible to interpret the profile data and all measureme tools + // will panic when given the file. + drop(self.profiler.take()); + } } impl VisitTags for MiriMachine<'_, '_> { From 7357217f9f27b54e748b6c6b3d42235e9b68fd0a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 23 May 2023 06:56:21 +0000 Subject: [PATCH 6/7] Preparing for merge from rustc --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index 39346fbd84..0bff100dc1 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -77c836e1ae582661924d3b6ec4d57a2de120f59f +8b4b20836b832e91aa605a2faf5e2a55190202c8 From 2166e34208ac464da5b5324488d874dcf76e74d3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 23 May 2023 07:25:16 +0000 Subject: [PATCH 7/7] Update to latest clippy --- src/shims/backtrace.rs | 2 +- src/shims/foreign_items.rs | 8 ++++---- src/shims/intrinsics/simd.rs | 2 +- src/shims/mod.rs | 2 +- src/shims/time.rs | 2 +- src/shims/tls.rs | 2 +- src/shims/unix/fs.rs | 2 +- src/shims/unix/linux/sync.rs | 2 +- src/shims/windows/foreign_items.rs | 2 +- src/shims/windows/handle.rs | 8 ++++---- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/shims/backtrace.rs b/src/shims/backtrace.rs index 1e4ab2f0f6..323991249d 100644 --- a/src/shims/backtrace.rs +++ b/src/shims/backtrace.rs @@ -102,7 +102,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let ptr_layout = this.layout_of(ptr_ty)?; for (i, ptr) in ptrs.into_iter().enumerate() { - let offset = ptr_layout.size * i.try_into().unwrap(); + let offset = ptr_layout.size.checked_mul(i.try_into().unwrap(), this).unwrap(); let op_place = buf_place.offset(offset, ptr_layout, this)?; diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index 44bca3796f..aa0794c00b 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -166,7 +166,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { dependency_format.1.iter().enumerate().filter_map(|(num, &linkage)| { // We add 1 to the number because that's what rustc also does everywhere it // calls `CrateNum::new`... - #[allow(clippy::integer_arithmetic)] + #[allow(clippy::arithmetic_side_effects)] (linkage != Linkage::NotLinked).then_some(CrateNum::new(num + 1)) }), ) { @@ -707,7 +707,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { .position(|&c| c == val) { let idx = u64::try_from(idx).unwrap(); - #[allow(clippy::integer_arithmetic)] // idx < num, so this never wraps + #[allow(clippy::arithmetic_side_effects)] // idx < num, so this never wraps let new_ptr = ptr.offset(Size::from_bytes(num - idx - 1), this)?; this.write_pointer(new_ptr, dest)?; } else { @@ -916,10 +916,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let a = this.read_scalar(a)?.to_u64()?; let b = this.read_scalar(b)?.to_u64()?; - #[allow(clippy::integer_arithmetic)] + #[allow(clippy::arithmetic_side_effects)] // adding two u64 and a u8 cannot wrap in a u128 let wide_sum = u128::from(c_in) + u128::from(a) + u128::from(b); - #[allow(clippy::integer_arithmetic)] // it's a u128, we can shift by 64 + #[allow(clippy::arithmetic_side_effects)] // it's a u128, we can shift by 64 let (c_out, sum) = ((wide_sum >> 64).truncate::(), wide_sum.truncate::()); let c_out_field = this.place_field(dest, 0)?; diff --git a/src/shims/intrinsics/simd.rs b/src/shims/intrinsics/simd.rs index 4acb2201ad..1995db715e 100644 --- a/src/shims/intrinsics/simd.rs +++ b/src/shims/intrinsics/simd.rs @@ -612,7 +612,7 @@ fn simd_bitmask_index(idx: u32, vec_len: u32, endianness: Endian) -> u32 { assert!(idx < vec_len); match endianness { Endian::Little => idx, - #[allow(clippy::integer_arithmetic)] // idx < vec_len + #[allow(clippy::arithmetic_side_effects)] // idx < vec_len Endian::Big => vec_len - 1 - idx, // reverse order of bits } } diff --git a/src/shims/mod.rs b/src/shims/mod.rs index 918efda377..a423a0786b 100644 --- a/src/shims/mod.rs +++ b/src/shims/mod.rs @@ -1,4 +1,4 @@ -#![warn(clippy::integer_arithmetic)] +#![warn(clippy::arithmetic_side_effects)] mod backtrace; #[cfg(target_os = "linux")] diff --git a/src/shims/time.rs b/src/shims/time.rs index 2f24c00ce1..756dec1bec 100644 --- a/src/shims/time.rs +++ b/src/shims/time.rs @@ -108,7 +108,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Ok(0) } - #[allow(non_snake_case, clippy::integer_arithmetic)] + #[allow(non_snake_case, clippy::arithmetic_side_effects)] fn GetSystemTimeAsFileTime( &mut self, LPFILETIME_op: &OpTy<'tcx, Provenance>, diff --git a/src/shims/tls.rs b/src/shims/tls.rs index 685feeaf89..62bd087e7e 100644 --- a/src/shims/tls.rs +++ b/src/shims/tls.rs @@ -56,7 +56,7 @@ impl<'tcx> Default for TlsData<'tcx> { impl<'tcx> TlsData<'tcx> { /// Generate a new TLS key with the given destructor. /// `max_size` determines the integer size the key has to fit in. - #[allow(clippy::integer_arithmetic)] + #[allow(clippy::arithmetic_side_effects)] pub fn create_tls_key( &mut self, dtor: Option>, diff --git a/src/shims/unix/fs.rs b/src/shims/unix/fs.rs index abec782b4f..d1b09cd7b5 100644 --- a/src/shims/unix/fs.rs +++ b/src/shims/unix/fs.rs @@ -458,7 +458,7 @@ pub struct DirHandler { } impl DirHandler { - #[allow(clippy::integer_arithmetic)] + #[allow(clippy::arithmetic_side_effects)] fn insert_new(&mut self, read_dir: ReadDir) -> u64 { let id = self.next_id; self.next_id += 1; diff --git a/src/shims/unix/linux/sync.rs b/src/shims/unix/linux/sync.rs index ffe3ca69c5..6889c43004 100644 --- a/src/shims/unix/linux/sync.rs +++ b/src/shims/unix/linux/sync.rs @@ -247,7 +247,7 @@ pub fn futex<'tcx>( // before doing the syscall. this.atomic_fence(AtomicFenceOrd::SeqCst)?; let mut n = 0; - #[allow(clippy::integer_arithmetic)] + #[allow(clippy::arithmetic_side_effects)] for _ in 0..val { if let Some(thread) = this.futex_wake(addr_usize, bitset) { this.unblock_thread(thread); diff --git a/src/shims/windows/foreign_items.rs b/src/shims/windows/foreign_items.rs index f72ba5cca7..b8bb7f6245 100644 --- a/src/shims/windows/foreign_items.rs +++ b/src/shims/windows/foreign_items.rs @@ -219,7 +219,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { .copied() .scan(Size::ZERO, |a, x| { let res = Some(*a); - *a += x; + *a = a.checked_add(x, this).unwrap(); res }) .collect(); diff --git a/src/shims/windows/handle.rs b/src/shims/windows/handle.rs index 8bffa9991c..d9ae1b2240 100644 --- a/src/shims/windows/handle.rs +++ b/src/shims/windows/handle.rs @@ -62,7 +62,7 @@ impl Handle { let floor_log2 = variant_count.ilog2(); // we need to add one for non powers of two to compensate for the difference - #[allow(clippy::integer_arithmetic)] // cannot overflow + #[allow(clippy::arithmetic_side_effects)] // cannot overflow if variant_count.is_power_of_two() { floor_log2 } else { floor_log2 + 1 } } @@ -87,7 +87,7 @@ impl Handle { // packs the data into the lower `data_size` bits // and packs the discriminant right above the data - #[allow(clippy::integer_arithmetic)] // cannot overflow + #[allow(clippy::arithmetic_side_effects)] // cannot overflow return discriminant << data_size | data; } @@ -106,11 +106,11 @@ impl Handle { let data_size = u32::BITS.checked_sub(disc_size).unwrap(); // the lower `data_size` bits of this mask are 1 - #[allow(clippy::integer_arithmetic)] // cannot overflow + #[allow(clippy::arithmetic_side_effects)] // cannot overflow let data_mask = 2u32.pow(data_size) - 1; // the discriminant is stored right above the lower `data_size` bits - #[allow(clippy::integer_arithmetic)] // cannot overflow + #[allow(clippy::arithmetic_side_effects)] // cannot overflow let discriminant = handle >> data_size; // the data is stored in the lower `data_size` bits