mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-27 16:28:58 -04:00
The core library's `From` implementations do not cover conversions that are not portable or future-proof. For instance, even though it is safe today, `From<usize>` is not implemented for `u64` because of the possibility of supporting larger-than-64bit architectures in the future. However, the kernel supports a narrower set of architectures, with a considerable amount of code that is architecture-specific. This makes it helpful and desirable to provide more infallible conversions, lest we rely on the `as` keyword and carry the risk of silently losing data. Thus, introduce a new module `num::casts` that provides safe const functions performing more conversions allowed by the build target, as well as `FromSafeCast` and `IntoSafeCast` traits that are just extensions of `From` and `Into` to conversions that are known to be lossless. Some conversions are architecture-specific: for instance, converting a `u64` to a `usize` is only lossless on 64-bit platforms. These conversions are made available via a dedicated `arch` sub-module. Suggested-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/rust-for-linux/DDK4KADWJHMG.1FUPL3SDR26XF@kernel.org/ Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Danilo Krummrich <dakr@kernel.org> Link: https://patch.msgid.link/20260806-as_casts-v2-1-cb76a4d3a6ef@nvidia.com [ Added a few more intra-doc links. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
82 lines
1.6 KiB
Rust
82 lines
1.6 KiB
Rust
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
//! Additional numerical features for the kernel.
|
|
|
|
use core::ops;
|
|
|
|
pub mod bounded;
|
|
pub mod casts;
|
|
|
|
pub use bounded::*;
|
|
|
|
/// Designates unsigned primitive types.
|
|
pub enum Unsigned {}
|
|
|
|
/// Designates signed primitive types.
|
|
pub enum Signed {}
|
|
|
|
/// Describes core properties of integer types.
|
|
pub trait Integer:
|
|
Sized
|
|
+ Copy
|
|
+ Clone
|
|
+ PartialEq
|
|
+ Eq
|
|
+ PartialOrd
|
|
+ Ord
|
|
+ ops::Add<Output = Self>
|
|
+ ops::AddAssign
|
|
+ ops::Sub<Output = Self>
|
|
+ ops::SubAssign
|
|
+ ops::Mul<Output = Self>
|
|
+ ops::MulAssign
|
|
+ ops::Div<Output = Self>
|
|
+ ops::DivAssign
|
|
+ ops::Rem<Output = Self>
|
|
+ ops::RemAssign
|
|
+ ops::BitAnd<Output = Self>
|
|
+ ops::BitAndAssign
|
|
+ ops::BitOr<Output = Self>
|
|
+ ops::BitOrAssign
|
|
+ ops::BitXor<Output = Self>
|
|
+ ops::BitXorAssign
|
|
+ ops::Shl<u32, Output = Self>
|
|
+ ops::ShlAssign<u32>
|
|
+ ops::Shr<u32, Output = Self>
|
|
+ ops::ShrAssign<u32>
|
|
+ ops::Not
|
|
{
|
|
/// Whether this type is [`Signed`] or [`Unsigned`].
|
|
type Signedness;
|
|
|
|
/// Number of bits used for value representation.
|
|
const BITS: u32;
|
|
}
|
|
|
|
macro_rules! impl_integer {
|
|
($($type:ty: $signedness:ty), *) => {
|
|
$(
|
|
impl Integer for $type {
|
|
type Signedness = $signedness;
|
|
|
|
const BITS: u32 = <$type>::BITS;
|
|
}
|
|
)*
|
|
};
|
|
}
|
|
|
|
impl_integer!(
|
|
u8: Unsigned,
|
|
u16: Unsigned,
|
|
u32: Unsigned,
|
|
u64: Unsigned,
|
|
u128: Unsigned,
|
|
usize: Unsigned,
|
|
i8: Signed,
|
|
i16: Signed,
|
|
i32: Signed,
|
|
i64: Signed,
|
|
i128: Signed,
|
|
isize: Signed
|
|
);
|