Before Rust 1.29.0, Clippy introduced the `cast_lossless` lint [1]:
Rust’s `as` keyword will perform many kinds of conversions, including silently lossy conversions. Conversion functions such as `i32::from` will only perform lossless conversions. Using the conversion functions prevents conversions from becoming silently lossy if the input types ever change, and makes it clear for people reading the code that the conversion is lossless.
While this doesn't eliminate unchecked `as` conversions, it makes such conversions easier to scrutinize. It also has the slight benefit of removing a degree of freedom on which to bikeshed. Thus apply the changes and enable the lint -- no functional change intended.
Link: https://rust-lang.github.io/rust-clippy/master/index.html#cast_lossless [1] Suggested-by: Benno Lossin benno.lossin@proton.me Link: https://lore.kernel.org/all/D8ORTXSUTKGL.1KOJAGBM8F8TN@proton.me/ Reviewed-by: Benno Lossin benno.lossin@proton.me Reviewed-by: Boqun Feng boqun.feng@gmail.com Signed-off-by: Tamir Duberstein tamird@gmail.com --- Makefile | 1 + drivers/gpu/drm/drm_panic_qr.rs | 4 ++-- drivers/gpu/nova-core/regs.rs | 2 +- drivers/gpu/nova-core/regs/macros.rs | 2 +- rust/bindings/lib.rs | 1 + rust/kernel/net/phy.rs | 4 ++-- rust/uapi/lib.rs | 1 + 7 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/Makefile b/Makefile index 0ba22c361de8..29cf39be14de 100644 --- a/Makefile +++ b/Makefile @@ -481,6 +481,7 @@ export rust_common_flags := --edition=2021 \ -Wclippy::all \ -Wclippy::as_ptr_cast_mut \ -Wclippy::as_underscore \ + -Wclippy::cast_lossless \ -Wclippy::ignored_unit_patterns \ -Wclippy::mut_mut \ -Wclippy::needless_bitwise_bool \ diff --git a/drivers/gpu/drm/drm_panic_qr.rs b/drivers/gpu/drm/drm_panic_qr.rs index dd55b1cb764d..6b59d19ab631 100644 --- a/drivers/gpu/drm/drm_panic_qr.rs +++ b/drivers/gpu/drm/drm_panic_qr.rs @@ -404,7 +404,7 @@ fn pop3(&mut self) -> Option<(u16, usize)> { let mut out = 0; let mut exp = 1; for i in 0..poplen { - out += self.decimals[self.len + i] as u16 * exp; + out += u16::from(self.decimals[self.len + i]) * exp; exp *= 10; } Some((out, NUM_CHARS_BITS[poplen])) @@ -425,7 +425,7 @@ fn next(&mut self) -> OptionSelf::Item { match self.segment { Segment::Binary(data) => { if self.offset < data.len() { - let byte = data[self.offset] as u16; + let byte = u16::from(data[self.offset]); self.offset += 1; Some((byte, 8)) } else { diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs index 5a1273230306..c1cb6d4c49ee 100644 --- a/drivers/gpu/nova-core/regs.rs +++ b/drivers/gpu/nova-core/regs.rs @@ -32,7 +32,7 @@ pub(crate) fn architecture(self) -> Result<Architecture> { pub(crate) fn chipset(self) -> Result<Chipset> { self.architecture() .map(|arch| { - ((arch as u32) << Self::IMPLEMENTATION.len()) | self.implementation() as u32 + ((arch as u32) << Self::IMPLEMENTATION.len()) | u32::from(self.implementation()) }) .and_then(Chipset::try_from) } diff --git a/drivers/gpu/nova-core/regs/macros.rs b/drivers/gpu/nova-core/regs/macros.rs index 7ecc70efb3cd..6851af8b5885 100644 --- a/drivers/gpu/nova-core/regs/macros.rs +++ b/drivers/gpu/nova-core/regs/macros.rs @@ -264,7 +264,7 @@ pub(crate) fn $field(self) -> $res_type { pub(crate) fn [<set_ $field>](mut self, value: $to_type) -> Self { const MASK: u32 = $name::[<$field:upper _MASK>]; const SHIFT: u32 = $name::[<$field:upper _SHIFT>]; - let value = ((value as u32) << SHIFT) & MASK; + let value = (u32::from(value) << SHIFT) & MASK; self.0 = (self.0 & !MASK) | value;
self diff --git a/rust/bindings/lib.rs b/rust/bindings/lib.rs index 81b6c7aa4916..7631c9f6708d 100644 --- a/rust/bindings/lib.rs +++ b/rust/bindings/lib.rs @@ -25,6 +25,7 @@ )]
#[allow(dead_code)] +#[allow(clippy::cast_lossless)] #[allow(clippy::ptr_as_ptr)] #[allow(clippy::undocumented_unsafe_blocks)] #[cfg_attr(CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES, allow(unnecessary_transmutes))] diff --git a/rust/kernel/net/phy.rs b/rust/kernel/net/phy.rs index 32ea43ece646..65ac4d59ad77 100644 --- a/rust/kernel/net/phy.rs +++ b/rust/kernel/net/phy.rs @@ -142,7 +142,7 @@ pub fn is_autoneg_enabled(&self) -> bool { // SAFETY: The struct invariant ensures that we may access // this field without additional synchronization. let bit_field = unsafe { &(*self.0.get())._bitfield_1 }; - bit_field.get(13, 1) == bindings::AUTONEG_ENABLE as u64 + bit_field.get(13, 1) == u64::from(bindings::AUTONEG_ENABLE) }
/// Gets the current auto-negotiation state. @@ -427,7 +427,7 @@ impl<T: Driver> Adapter<T> { // where we hold `phy_device->lock`, so the accessors on // `Device` are okay to call. let dev = unsafe { Device::from_raw(phydev) }; - T::match_phy_device(dev) as i32 + T::match_phy_device(dev).into() }
/// # Safety diff --git a/rust/uapi/lib.rs b/rust/uapi/lib.rs index e79a1f49f055..08e68ebef606 100644 --- a/rust/uapi/lib.rs +++ b/rust/uapi/lib.rs @@ -14,6 +14,7 @@ #![cfg_attr(test, allow(unsafe_op_in_unsafe_fn))] #![allow( clippy::all, + clippy::cast_lossless, clippy::ptr_as_ptr, clippy::undocumented_unsafe_blocks, dead_code,