Skip to content

Commit 3be73b8

Browse files
authored
Fix clippy warnings for Rust 1.79 (#1151)
This PR fixes new warnings generated by Clippy after upgrading Rust to 1.79. - Only define `ImmixSpaceArg::mixed_age` when the "vo_bit" feature is enabled. This eliminates a dead code warning. - Use the associated constant `<integer_type>::MAX` (and `MIN`, too) instead of the deprecated `max_value()` method and the `::std::<integer_type>::MAX` constant. - Annotate the destination type of some `transmute` calls. - Use the safe `std::ptr::NonNull::from()` converter instead of `transmute`. - Initialize array elements of type `Atomic<MapState>` from constant. - Remove `MutatorContext::barrier_impl`. It is not used by any bindings right now, and it depends on the layout of `&dyn Trait`. Since `Barrier` has `Downcast` as a supertrait, if a binding needs a reference to a concrete `Barrier` implementation, it should just use downcast. The warning against the `transmute` call in `mock_vm.rs` is suppressed because it is almost impossible to annotate. Also fixes compilation problems: - Made benchmarks related to the "mock_test" feature conditionally compiled so that we don't get compilation error when running `cargo clippy --benches` or `cargo clippy --all-targets`.
1 parent 47562b7 commit 3be73b8

19 files changed

+69
-36
lines changed

benches/main.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,25 @@ use criterion::Criterion;
1919
// However, I will just keep these benchmarks here. If we find it not useful, and we do not plan to improve MockVM, we can delete
2020
// them.
2121

22-
mod alloc;
23-
mod sft;
22+
#[cfg(feature = "mock_test")]
23+
mod mock_bench;
2424

25-
fn bench_main(c: &mut Criterion) {
25+
pub fn bench_main(_c: &mut Criterion) {
26+
#[cfg(feature = "mock_test")]
2627
match std::env::var("MMTK_BENCH") {
2728
Ok(bench) => match bench.as_str() {
28-
"alloc" => alloc::bench(c),
29-
"sft" => sft::bench(c),
29+
"alloc" => mock_bench::alloc::bench(_c),
30+
"sft" => mock_bench::sft::bench(_c),
3031
_ => panic!("Unknown benchmark {:?}", bench),
3132
},
3233
Err(_) => panic!("Need to name a benchmark by the env var MMTK_BENCH"),
3334
}
35+
36+
#[cfg(not(feature = "mock_test"))]
37+
{
38+
eprintln!("ERROR: Currently there are no benchmarks when the \"mock_test\" feature is not enabled.");
39+
std::process::exit(1);
40+
}
3441
}
3542

3643
criterion_group!(benches, bench_main);
File renamed without changes.

benches/mock_bench/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod alloc;
2+
pub mod sft;
File renamed without changes.

src/plan/generational/immix/global.rs

+1
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ impl<VM: VMBinding> GenImmix<VM> {
251251
// Any object is moved into the mature space, or is copied inside the mature space. We will unlog it.
252252
unlog_object_when_traced: false,
253253
// In GenImmix, young objects are not allocated in ImmixSpace directly.
254+
#[cfg(feature = "vo_bit")]
254255
mixed_age: false,
255256
},
256257
);

src/plan/immix/global.rs

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ impl<VM: VMBinding> Immix<VM> {
138138
ImmixSpaceArgs {
139139
reset_log_bit_in_major_gc: false,
140140
unlog_object_when_traced: false,
141+
#[cfg(feature = "vo_bit")]
141142
mixed_age: false,
142143
},
143144
)

src/plan/mutator_context.rs

-12
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,6 @@ impl<VM: VMBinding> MutatorContext<VM> for Mutator<VM> {
153153
self.mutator_tls
154154
}
155155

156-
/// Used by specialized barrier slow-path calls to avoid dynamic dispatches.
157-
unsafe fn barrier_impl<B: Barrier<VM>>(&mut self) -> &mut B {
158-
debug_assert!(self.barrier().is::<B>());
159-
let (payload, _vptr) = std::mem::transmute::<_, (*mut B, *mut ())>(self.barrier());
160-
&mut *payload
161-
}
162-
163156
fn barrier(&mut self) -> &mut dyn Barrier<VM> {
164157
&mut *self.barrier
165158
}
@@ -316,11 +309,6 @@ pub trait MutatorContext<VM: VMBinding>: Send + 'static {
316309
fn get_tls(&self) -> VMMutatorThread;
317310
/// Get active barrier trait object
318311
fn barrier(&mut self) -> &mut dyn Barrier<VM>;
319-
/// Force cast the barrier trait object to a concrete implementation.
320-
///
321-
/// # Safety
322-
/// The safety of this function is ensured by a down-cast check.
323-
unsafe fn barrier_impl<B: Barrier<VM>>(&mut self) -> &mut B;
324312
}
325313

326314
/// This is used for plans to indicate the number of allocators reserved for the plan.

src/plan/sticky/immix/global.rs

+1
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ impl<VM: VMBinding> StickyImmix<VM> {
329329
// Along with the option above, we unlog them again during tracing.
330330
reset_log_bit_in_major_gc: true,
331331
// In StickyImmix, both young and old objects are allocated in the ImmixSpace.
332+
#[cfg(feature = "vo_bit")]
332333
mixed_age: true,
333334
},
334335
);

src/policy/immix/immixspace.rs

+2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ pub struct ImmixSpaceArgs {
7777
/// instance contain young objects, their VO bits need to be updated during this GC. Currently
7878
/// only StickyImmix is affected. GenImmix allocates young objects in a separete CopySpace
7979
/// nursery and its VO bits can be cleared in bulk.
80+
// Currently only used when "vo_bit" is enabled. Using #[cfg(...)] to eliminate dead code warning.
81+
#[cfg(feature = "vo_bit")]
8082
pub mixed_age: bool,
8183
}
8284

src/policy/sft_map.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,12 @@ pub(crate) type SFTRawPointer = *const (dyn SFT + Sync + 'static);
103103
/// see if 128 bits atomic instructions are available.
104104
#[cfg(target_pointer_width = "64")]
105105
type AtomicDoubleWord = portable_atomic::AtomicU128;
106+
#[cfg(target_pointer_width = "64")]
107+
type DoubleWord = u128;
106108
#[cfg(target_pointer_width = "32")]
107109
type AtomicDoubleWord = portable_atomic::AtomicU64;
110+
#[cfg(target_pointer_width = "32")]
111+
type DoubleWord = u64;
108112

109113
/// The type we store SFT raw pointer as. It basically just double word sized atomic integer.
110114
/// This type provides an abstraction so we can access SFT easily.
@@ -128,7 +132,7 @@ impl SFTRefStorage {
128132
}
129133

130134
pub fn new(sft: SFTRawPointer) -> Self {
131-
let val = unsafe { std::mem::transmute(sft) };
135+
let val: DoubleWord = unsafe { std::mem::transmute(sft) };
132136
Self(AtomicDoubleWord::new(val))
133137
}
134138

@@ -140,7 +144,7 @@ impl SFTRefStorage {
140144

141145
// Store a raw SFT pointer with the release ordering.
142146
pub fn store(&self, sft: SFTRawPointer) {
143-
let val = unsafe { std::mem::transmute(sft) };
147+
let val: DoubleWord = unsafe { std::mem::transmute(sft) };
144148
self.0.store(val, Ordering::Release)
145149
}
146150
}

src/util/address.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ impl Address {
134134
/// The lowest possible address.
135135
pub const ZERO: Self = Address(0);
136136
/// The highest possible address.
137-
pub const MAX: Self = Address(usize::max_value());
137+
pub const MAX: Self = Address(usize::MAX);
138138

139139
/// creates Address from a pointer
140140
pub fn from_ptr<T>(ptr: *const T) -> Address {
@@ -164,7 +164,6 @@ impl Address {
164164
/// It is unsafe and the user needs to be aware that they are creating an invalid address.
165165
/// The max address should only be used as unininitialized or sentinel values in performance critical code (where you dont want to use `Option<Address>`).
166166
pub unsafe fn max() -> Address {
167-
use std::usize;
168167
Address(usize::MAX)
169168
}
170169

src/util/constants.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ mod java_specific_constants {
7878
pub const LOG_BITS_IN_LONG: u8 = LOG_BITS_IN_BYTE + LOG_BYTES_IN_LONG;
7979
pub const BITS_IN_LONG: usize = 1 << LOG_BITS_IN_LONG;
8080

81-
pub const MAX_INT: usize = i32::max_value() as usize; // 0x7fff_ffff
82-
pub const MIN_INT: usize = i32::min_value() as u32 as usize; // 0x8000_0000
81+
pub const MAX_INT: usize = i32::MAX as usize; // 0x7fff_ffff
82+
pub const MIN_INT: usize = i32::MIN as u32 as usize; // 0x8000_0000
8383
}
8484
pub(crate) use java_specific_constants::*;
8585

src/util/erase_vm.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ macro_rules! define_erased_vm_mut_ref {
1717
pub struct $new_type<'a>(usize, PhantomData<&'a ()>);
1818
impl<'a> $new_type<'a> {
1919
pub fn new<VM: VMBinding>(r: &'a mut $orig_type) -> Self {
20-
Self(unsafe { std::mem::transmute(r) }, PhantomData)
20+
let worker_as_usize: usize = unsafe { std::mem::transmute(r) };
21+
Self(worker_as_usize, PhantomData)
2122
}
2223
pub fn into_mut<VM: VMBinding>(self) -> &'a mut $orig_type {
2324
unsafe { std::mem::transmute(self.0) }

src/util/heap/layout/byte_map_mmapper.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use std::sync::Mutex;
1212

1313
use atomic::Atomic;
1414
use std::io::Result;
15-
use std::mem::transmute;
1615

1716
const MMAP_NUM_CHUNKS: usize = if LOG_BYTES_IN_ADDRESS_SPACE == 32 {
1817
1 << (LOG_BYTES_IN_ADDRESS_SPACE as usize - LOG_MMAP_CHUNK_BYTES)
@@ -134,11 +133,22 @@ impl Mmapper for ByteMapMmapper {
134133

135134
impl ByteMapMmapper {
136135
pub fn new() -> Self {
137-
// Hacky because AtomicU8 does not implement Copy
138-
// Should be fiiine because AtomicXXX has the same bit representation as XXX
136+
// Because AtomicU8 does not implement Copy, it is a compilation error to usen the
137+
// expression `[Atomic::new(MapState::Unmapped); MMAP_NUM_CHUNKS]` because that involves
138+
// copying. We must define a constant for it.
139+
//
140+
// TODO: Use the inline const expression `const { Atomic::new(MapState::Unmapped) }` after
141+
// we bump MSRV to 1.79.
142+
143+
// If we declare a const Atomic, Clippy will warn about const items being interior mutable.
144+
// Using inline const expression will eliminate this warning, but that is experimental until
145+
// 1.79. Fix it after we bump MSRV.
146+
#[allow(clippy::declare_interior_mutable_const)]
147+
const INITIAL_ENTRY: Atomic<MapState> = Atomic::new(MapState::Unmapped);
148+
139149
ByteMapMmapper {
140150
lock: Mutex::new(()),
141-
mapped: unsafe { transmute([MapState::Unmapped; MMAP_NUM_CHUNKS]) },
151+
mapped: [INITIAL_ENTRY; MMAP_NUM_CHUNKS],
142152
strategy: Atomic::new(MmapStrategy::Normal),
143153
}
144154
}

src/util/heap/layout/fragmented_mapper.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use atomic::{Atomic, Ordering};
99
use std::cell::UnsafeCell;
1010
use std::fmt;
1111
use std::io::Result;
12-
use std::mem::transmute;
1312
use std::sync::Mutex;
1413

1514
const MMAP_NUM_CHUNKS: usize = 1 << (33 - LOG_MMAP_CHUNK_BYTES);
@@ -242,8 +241,20 @@ impl FragmentedMapper {
242241
}
243242

244243
fn new_slab() -> Box<Slab> {
245-
let mapped: Box<Slab> =
246-
Box::new(unsafe { transmute([MapState::Unmapped; MMAP_NUM_CHUNKS]) });
244+
// Because AtomicU8 does not implement Copy, it is a compilation error to usen the
245+
// expression `[Atomic::new(MapState::Unmapped); MMAP_NUM_CHUNKS]` because that involves
246+
// copying. We must define a constant for it.
247+
//
248+
// TODO: Use the inline const expression `const { Atomic::new(MapState::Unmapped) }` after
249+
// we bump MSRV to 1.79.
250+
251+
// If we declare a const Atomic, Clippy will warn about const items being interior mutable.
252+
// Using inline const expression will eliminate this warning, but that is experimental until
253+
// 1.79. Fix it after we bump MSRV.
254+
#[allow(clippy::declare_interior_mutable_const)]
255+
const INITIAL_ENTRY: Atomic<MapState> = Atomic::new(MapState::Unmapped);
256+
257+
let mapped: Box<Slab> = Box::new([INITIAL_ENTRY; MMAP_NUM_CHUNKS]);
247258
mapped
248259
}
249260

src/util/heap/space_descriptor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl SpaceDescriptor {
3535
let top = end == vm_layout().heap_end;
3636
if vm_layout().force_use_contiguous_spaces {
3737
let space_index = if start > vm_layout().heap_end {
38-
::std::usize::MAX
38+
usize::MAX
3939
} else {
4040
start >> vm_layout().space_shift_64()
4141
};

src/util/int_array_freelist.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::freelist::*;
2-
use std::{mem, ptr::NonNull};
2+
use std::ptr::NonNull;
33

44
#[derive(Debug)]
55
pub struct IntArrayFreeList {
@@ -42,11 +42,12 @@ impl IntArrayFreeList {
4242
iafl
4343
}
4444
pub fn from_parent(parent: &IntArrayFreeList, ordinal: i32) -> Self {
45+
let parent_ptr = std::ptr::NonNull::from(parent);
4546
let iafl = IntArrayFreeList {
4647
head: -(1 + ordinal),
4748
heads: parent.heads,
4849
table: None,
49-
parent: Some(unsafe { mem::transmute(parent) }),
50+
parent: Some(parent_ptr),
5051
};
5152
debug_assert!(-iafl.head <= iafl.heads);
5253
iafl

src/util/options.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use strum_macros::EnumString;
88

99
/// The default stress factor. This is set to the max usize,
1010
/// which means we will never trigger a stress GC for the default value.
11-
pub const DEFAULT_STRESS_FACTOR: usize = usize::max_value();
11+
pub const DEFAULT_STRESS_FACTOR: usize = usize::MAX;
1212

1313
/// The zeroing approach to use for new object allocations.
1414
/// Affects each plan differently.

src/util/test_util/mock_vm.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ lazy_static! {
4444
// we do not store them for access after the mock method returns.
4545
macro_rules! lifetime {
4646
($e: expr) => {
47-
unsafe { std::mem::transmute($e) }
47+
unsafe {
48+
// The dynamic nature of this lifetime-removal macro makes it impossible to reason
49+
// about the source and destination types of the `transmute`.
50+
#[allow(clippy::missing_transmute_annotations)]
51+
std::mem::transmute($e)
52+
}
4853
};
4954
}
5055

0 commit comments

Comments
 (0)