Skip to content

Commit 0ba2a3a

Browse files
committed
enable clippy::as_conversions to fully rule out as-casts
1 parent d5240cc commit 0ba2a3a

File tree

16 files changed

+61
-57
lines changed

16 files changed

+61
-57
lines changed

src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use std::mem;
1717

1818
use rustc_data_structures::fx::FxHashMap;
1919

20+
use crate::helpers::ToUsize;
21+
2022
/// Intermediate key between a UniKeyMap and a UniValMap.
2123
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2224
pub struct UniIndex {
@@ -158,7 +160,7 @@ where
158160
impl<V> UniValMap<V> {
159161
/// Whether this index has an associated value.
160162
pub fn contains_idx(&self, idx: UniIndex) -> bool {
161-
self.data.get(idx.idx as usize).and_then(Option::as_ref).is_some()
163+
self.data.get(idx.idx.to_usize()).and_then(Option::as_ref).is_some()
162164
}
163165

164166
/// Reserve enough space to insert the value at the right index.
@@ -174,29 +176,29 @@ impl<V> UniValMap<V> {
174176

175177
/// Assign a value to the index. Permanently overwrites any previous value.
176178
pub fn insert(&mut self, idx: UniIndex, val: V) {
177-
self.extend_to_length(idx.idx as usize + 1);
178-
self.data[idx.idx as usize] = Some(val)
179+
self.extend_to_length(idx.idx.to_usize() + 1);
180+
self.data[idx.idx.to_usize()] = Some(val)
179181
}
180182

181183
/// Get the value at this index, if it exists.
182184
pub fn get(&self, idx: UniIndex) -> Option<&V> {
183-
self.data.get(idx.idx as usize).and_then(Option::as_ref)
185+
self.data.get(idx.idx.to_usize()).and_then(Option::as_ref)
184186
}
185187

186188
/// Get the value at this index mutably, if it exists.
187189
pub fn get_mut(&mut self, idx: UniIndex) -> Option<&mut V> {
188-
self.data.get_mut(idx.idx as usize).and_then(Option::as_mut)
190+
self.data.get_mut(idx.idx.to_usize()).and_then(Option::as_mut)
189191
}
190192

191193
/// Delete any value associated with this index.
192194
/// Returns None if the value was not present, otherwise
193195
/// returns the previously stored value.
194196
pub fn remove(&mut self, idx: UniIndex) -> Option<V> {
195-
if idx.idx as usize >= self.data.len() {
197+
if idx.idx.to_usize() >= self.data.len() {
196198
return None;
197199
}
198200
let mut res = None;
199-
mem::swap(&mut res, &mut self.data[idx.idx as usize]);
201+
mem::swap(&mut res, &mut self.data[idx.idx.to_usize()]);
200202
res
201203
}
202204
}
@@ -209,8 +211,8 @@ pub struct UniEntry<'a, V> {
209211
impl<'a, V> UniValMap<V> {
210212
/// Get a wrapper around a mutable access to the value corresponding to `idx`.
211213
pub fn entry(&'a mut self, idx: UniIndex) -> UniEntry<'a, V> {
212-
self.extend_to_length(idx.idx as usize + 1);
213-
UniEntry { inner: &mut self.data[idx.idx as usize] }
214+
self.extend_to_length(idx.idx.to_usize() + 1);
215+
UniEntry { inner: &mut self.data[idx.idx.to_usize()] }
214216
}
215217
}
216218

src/tools/miri/src/concurrency/cpu_affinity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ impl CpuAffinityMask {
2525
let mut this = Self([0; Self::CPU_MASK_BYTES]);
2626

2727
// the default affinity mask includes only the available CPUs
28-
for i in 0..cpu_count as usize {
28+
for i in 0..cpu_count.to_usize() {
2929
this.set(cx, i);
3030
}
3131

src/tools/miri/src/concurrency/vector_clock.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_span::{DUMMY_SP, Span, SpanData};
77
use smallvec::SmallVec;
88

99
use super::data_race::NaReadType;
10+
use crate::helpers::ToUsize;
1011

1112
/// A vector clock index, this is associated with a thread id
1213
/// but in some cases one vector index may be shared with
@@ -157,7 +158,7 @@ impl VClock {
157158

158159
#[inline]
159160
pub(super) fn index_mut(&mut self, index: VectorIdx) -> &mut VTimestamp {
160-
self.0.as_mut_slice().get_mut(index.to_u32() as usize).unwrap()
161+
self.0.as_mut_slice().get_mut(index.to_u32().to_usize()).unwrap()
161162
}
162163

163164
/// Get a mutable slice to the internal vector with minimum `min_len`
@@ -420,7 +421,7 @@ impl Index<VectorIdx> for VClock {
420421

421422
#[inline]
422423
fn index(&self, index: VectorIdx) -> &VTimestamp {
423-
self.as_slice().get(index.to_u32() as usize).unwrap_or(&VTimestamp::ZERO)
424+
self.as_slice().get(index.to_u32().to_usize()).unwrap_or(&VTimestamp::ZERO)
424425
}
425426
}
426427

src/tools/miri/src/helpers.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,3 +1412,14 @@ pub(crate) fn windows_check_buffer_size((success, len): (bool, u64)) -> u32 {
14121412
u32::try_from(len).unwrap()
14131413
}
14141414
}
1415+
1416+
/// We don't support 16-bit systems, so let's have ergonomic conversion from `u32` to `usize`.
1417+
pub trait ToUsize {
1418+
fn to_usize(self) -> usize;
1419+
}
1420+
1421+
impl ToUsize for u32 {
1422+
fn to_usize(self) -> usize {
1423+
self.try_into().unwrap()
1424+
}
1425+
}

src/tools/miri/src/intrinsics/simd.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
634634
let index_len = index.len();
635635

636636
assert_eq!(left_len, right_len);
637-
assert_eq!(index_len as u64, dest_len);
637+
assert_eq!(u64::try_from(index_len).unwrap(), dest_len);
638638

639639
for i in 0..dest_len {
640640
let src_index: u64 =

src/tools/miri/src/lib.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,7 @@
4141
rustc::potential_query_instability,
4242
rustc::untranslatable_diagnostic,
4343
)]
44-
#![warn(
45-
rust_2018_idioms,
46-
unqualified_local_imports,
47-
clippy::cast_possible_wrap, // unsigned -> signed
48-
clippy::cast_sign_loss, // signed -> unsigned
49-
clippy::cast_lossless,
50-
clippy::cast_possible_truncation,
51-
)]
44+
#![warn(rust_2018_idioms, unqualified_local_imports, clippy::as_conversions)]
5245
// Needed for rustdoc from bootstrap (with `-Znormalize-docs`).
5346
#![recursion_limit = "256"]
5447

@@ -140,7 +133,7 @@ pub use crate::eval::{
140133
AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, MiriEntryFnType, RejectOpWith,
141134
ValidationMode, create_ecx, eval_entry,
142135
};
143-
pub use crate::helpers::{AccessKind, EvalContextExt as _};
136+
pub use crate::helpers::{AccessKind, EvalContextExt as _, ToUsize as _};
144137
pub use crate::intrinsics::EvalContextExt as _;
145138
pub use crate::machine::{
146139
AllocExtra, DynMachineCallback, FrameExtra, MachineCallback, MemoryKind, MiriInterpCx,

src/tools/miri/src/shims/foreign_items.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
639639
let val = this.read_scalar(val)?.to_i32()?;
640640
let num = this.read_target_usize(num)?;
641641
// The docs say val is "interpreted as unsigned char".
642-
#[expect(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
642+
#[expect(clippy::as_conversions)]
643643
let val = val as u8;
644644

645645
// C requires that this must always be a valid pointer (C18 §7.1.4).
@@ -665,7 +665,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
665665
let val = this.read_scalar(val)?.to_i32()?;
666666
let num = this.read_target_usize(num)?;
667667
// The docs say val is "interpreted as unsigned char".
668-
#[expect(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
668+
#[expect(clippy::as_conversions)]
669669
let val = val as u8;
670670

671671
// C requires that this must always be a valid pointer (C18 §7.1.4).
@@ -676,7 +676,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
676676
.iter()
677677
.position(|&c| c == val);
678678
if let Some(idx) = idx {
679-
let new_ptr = ptr.wrapping_offset(Size::from_bytes(idx as u64), this);
679+
let new_ptr = ptr.wrapping_offset(Size::from_bytes(idx), this);
680680
this.write_pointer(new_ptr, dest)?;
681681
} else {
682682
this.write_null(dest)?;

src/tools/miri/src/shims/native_lib.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
9494
// Try getting the function from the shared library.
9595
// On windows `_lib_path` will be unused, hence the name starting with `_`.
9696
let (lib, _lib_path) = this.machine.native_lib.as_ref().unwrap();
97-
let func: libloading::Symbol<'_, unsafe extern "C" fn()> = unsafe {
98-
match lib.get(link_name.as_str().as_bytes()) {
99-
Ok(x) => x,
100-
Err(_) => {
101-
return None;
102-
}
103-
}
104-
};
97+
let func: libloading::Symbol<'_, unsafe extern "C" fn()> =
98+
unsafe { lib.get(link_name.as_str().as_bytes()).ok()? };
99+
#[expect(clippy::as_conversions)] // fn-ptr to raw-ptr cast needs `as`.
100+
let fn_ptr = *func.deref() as *mut std::ffi::c_void;
105101

106102
// FIXME: this is a hack!
107103
// The `libloading` crate will automatically load system libraries like `libc`.
@@ -116,7 +112,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
116112
// using the `libc` crate where this interface is public.
117113
let mut info = std::mem::MaybeUninit::<libc::Dl_info>::uninit();
118114
unsafe {
119-
if libc::dladdr(*func.deref() as *const _, info.as_mut_ptr()) != 0 {
115+
if libc::dladdr(fn_ptr, info.as_mut_ptr()) != 0 {
120116
let info = info.assume_init();
121117
#[cfg(target_os = "cygwin")]
122118
let fname_ptr = info.dli_fname.as_ptr();
@@ -129,8 +125,9 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
129125
}
130126
}
131127
}
128+
132129
// Return a pointer to the function.
133-
Some(CodePtr(*func.deref() as *mut _))
130+
Some(CodePtr(fn_ptr))
134131
}
135132
}
136133

src/tools/miri/src/shims/unix/android/thread.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::helpers::check_min_vararg_count;
77
use crate::shims::unix::thread::{EvalContextExt as _, ThreadNameResult};
88
use crate::*;
99

10-
const TASK_COMM_LEN: usize = 16;
10+
const TASK_COMM_LEN: u32 = 16;
1111

1212
pub fn prctl<'tcx>(
1313
ecx: &mut MiriInterpCx<'tcx>,
@@ -29,16 +29,20 @@ pub fn prctl<'tcx>(
2929
let thread = ecx.pthread_self()?;
3030
// The Linux kernel silently truncates long names.
3131
// https://www.man7.org/linux/man-pages/man2/PR_SET_NAME.2const.html
32-
let res =
33-
ecx.pthread_setname_np(thread, name, TASK_COMM_LEN, /* truncate */ true)?;
32+
let res = ecx.pthread_setname_np(
33+
thread,
34+
name,
35+
TASK_COMM_LEN.to_usize(),
36+
/* truncate */ true,
37+
)?;
3438
assert_eq!(res, ThreadNameResult::Ok);
3539
Scalar::from_u32(0)
3640
}
3741
op if op == pr_get_name => {
3842
let [name] = check_min_vararg_count("prctl(PR_GET_NAME, ...)", varargs)?;
3943
let name = ecx.read_scalar(name)?;
4044
let thread = ecx.pthread_self()?;
41-
let len = Scalar::from_target_usize(TASK_COMM_LEN as u64, ecx);
45+
let len = Scalar::from_target_usize(TASK_COMM_LEN.into(), ecx);
4246
ecx.check_ptr_access(
4347
name.to_pointer(ecx)?,
4448
Size::from_bytes(TASK_COMM_LEN),

src/tools/miri/src/shims/unix/fs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,13 @@ impl UnixFileDescription for FileHandle {
121121
use std::os::windows::io::AsRawHandle;
122122

123123
use windows_sys::Win32::Foundation::{
124-
ERROR_IO_PENDING, ERROR_LOCK_VIOLATION, FALSE, HANDLE, TRUE,
124+
ERROR_IO_PENDING, ERROR_LOCK_VIOLATION, FALSE, TRUE,
125125
};
126126
use windows_sys::Win32::Storage::FileSystem::{
127127
LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY, LockFileEx, UnlockFile,
128128
};
129129

130-
let fh = self.file.as_raw_handle() as HANDLE;
130+
let fh = self.file.as_raw_handle();
131131

132132
use FlockOp::*;
133133
let (ret, lock_nb) = match op {

src/tools/miri/src/shims/unix/linux/foreign_items.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::*;
1414
// The documentation of glibc complains that the kernel never exposes
1515
// TASK_COMM_LEN through the headers, so it's assumed to always be 16 bytes
1616
// long including a null terminator.
17-
const TASK_COMM_LEN: usize = 16;
17+
const TASK_COMM_LEN: u32 = 16;
1818

1919
pub fn is_dyn_sym(name: &str) -> bool {
2020
matches!(name, "statx")
@@ -80,7 +80,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
8080
let res = match this.pthread_setname_np(
8181
this.read_scalar(thread)?,
8282
this.read_scalar(name)?,
83-
TASK_COMM_LEN,
83+
TASK_COMM_LEN.to_usize(),
8484
/* truncate */ false,
8585
)? {
8686
ThreadNameResult::Ok => Scalar::from_u32(0),
@@ -96,7 +96,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
9696
// In case of glibc, the length of the output buffer must
9797
// be not shorter than TASK_COMM_LEN.
9898
let len = this.read_scalar(len)?;
99-
let res = if len.to_target_usize(this)? >= TASK_COMM_LEN as u64 {
99+
let res = if len.to_target_usize(this)? >= TASK_COMM_LEN.into() {
100100
match this.pthread_getname_np(
101101
this.read_scalar(thread)?,
102102
this.read_scalar(name)?,

src/tools/miri/src/shims/windows/fs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ fn extract_windows_epoch<'tcx>(
401401
Some(time) => {
402402
let duration = ecx.system_time_since_windows_epoch(&time)?;
403403
let duration_ticks = ecx.windows_ticks_for(duration)?;
404-
#[allow(clippy::cast_possible_truncation)]
404+
#[expect(clippy::as_conversions)]
405405
interp_ok(Some((duration_ticks as u32, (duration_ticks >> 32) as u32)))
406406
}
407407
None => interp_ok(None),

src/tools/miri/src/shims/windows/handle.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ impl Handle {
7070
Self::Null => 0,
7171
Self::Pseudo(pseudo_handle) => pseudo_handle.value(),
7272
Self::Thread(thread) => thread.to_u32(),
73-
#[expect(clippy::cast_sign_loss)]
74-
Self::File(fd) => fd as u32,
73+
Self::File(fd) => fd.cast_unsigned(),
7574
// INVALID_HANDLE_VALUE is -1. This fact is explicitly declared or implied in several
7675
// pages of Windows documentation.
7776
// 1: https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.safehandles.safefilehandle?view=net-9.0
@@ -124,11 +123,10 @@ impl Handle {
124123
Self::NULL_DISCRIMINANT if data == 0 => Some(Self::Null),
125124
Self::PSEUDO_DISCRIMINANT => Some(Self::Pseudo(PseudoHandle::from_value(data)?)),
126125
Self::THREAD_DISCRIMINANT => Some(Self::Thread(ThreadId::new_unchecked(data))),
127-
#[expect(clippy::cast_possible_wrap)]
128126
Self::FILE_DISCRIMINANT => {
129127
// This cast preserves all bits.
130128
assert_eq!(size_of_val(&data), size_of::<FdNum>());
131-
Some(Self::File(data as FdNum))
129+
Some(Self::File(data.cast_signed()))
132130
}
133131
Self::INVALID_DISCRIMINANT => Some(Self::Invalid),
134132
_ => None,
@@ -156,8 +154,7 @@ impl Handle {
156154
pub fn to_scalar(self, cx: &impl HasDataLayout) -> Scalar {
157155
// 64-bit handles are sign extended 32-bit handles
158156
// see https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
159-
#[expect(clippy::cast_possible_wrap)] // we want it to wrap
160-
let signed_handle = self.to_packed() as i32;
157+
let signed_handle = self.to_packed().cast_signed();
161158
Scalar::from_target_isize(signed_handle.into(), cx)
162159
}
163160

@@ -171,9 +168,8 @@ impl Handle {
171168
) -> InterpResult<'tcx, Result<Self, HandleError>> {
172169
let sign_extended_handle = handle.to_target_isize(cx)?;
173170

174-
#[expect(clippy::cast_sign_loss)] // we want to lose the sign
175171
let handle = if let Ok(signed_handle) = i32::try_from(sign_extended_handle) {
176-
signed_handle as u32
172+
signed_handle.cast_unsigned()
177173
} else {
178174
// if a handle doesn't fit in an i32, it isn't valid.
179175
return interp_ok(Err(HandleError::InvalidHandle));

src/tools/miri/src/shims/x86/gfni.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,12 @@ fn affine_transform<'tcx>(
133133
// This is a evaluated at compile time. Trait based conversion is not available.
134134
/// See <https://www.corsix.org/content/galois-field-instructions-2021-cpus> for the
135135
/// definition of `gf_inv` which was used for the creation of this table.
136-
#[expect(clippy::cast_possible_truncation)]
137136
static TABLE: [u8; 256] = {
138137
let mut array = [0; 256];
139138

140139
let mut i = 1;
141140
while i < 256 {
141+
#[expect(clippy::as_conversions)] // no `try_from` in const...
142142
let mut x = i as u8;
143143
let mut y = gf2p8_mul(x, x);
144144
x = y;
@@ -160,7 +160,7 @@ static TABLE: [u8; 256] = {
160160
/// polynomial representation with the reduction polynomial x^8 + x^4 + x^3 + x + 1.
161161
/// See <https://www.corsix.org/content/galois-field-instructions-2021-cpus> for details.
162162
// This is a const function. Trait based conversion is not available.
163-
#[expect(clippy::cast_possible_truncation)]
163+
#[expect(clippy::as_conversions)]
164164
const fn gf2p8_mul(left: u8, right: u8) -> u8 {
165165
// This implementation is based on the `gf2p8mul_byte` definition found inside the Intel intrinsics guide.
166166
// See https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8mul

src/tools/miri/src/shims/x86/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ fn pmulhrsw<'tcx>(
11101110

11111111
// The result of this operation can overflow a signed 16-bit integer.
11121112
// When `left` and `right` are -0x8000, the result is 0x8000.
1113-
#[expect(clippy::cast_possible_truncation)]
1113+
#[expect(clippy::as_conversions)]
11141114
let res = res as i16;
11151115

11161116
ecx.write_scalar(Scalar::from_i16(res), &dest)?;

src/tools/miri/src/shims/x86/sse42.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
440440
let crc = if bit_size == 64 {
441441
// The 64-bit version will only consider the lower 32 bits,
442442
// while the upper 32 bits get discarded.
443-
#[expect(clippy::cast_possible_truncation)]
443+
#[expect(clippy::as_conversions)]
444444
u128::from((left.to_u64()? as u32).reverse_bits())
445445
} else {
446446
u128::from(left.to_u32()?.reverse_bits())

0 commit comments

Comments
 (0)