* [PATCH] rust: num: reject bool conversion to signed one-bit Bounded
@ 2026-08-15 8:06 ` Younes Akhouayri
0 siblings, 0 replies; 6+ messages in thread
From: Younes Akhouayri via B4 Relay @ 2026-08-15 8:06 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan
Cc: rust-for-linux, stable, Younes Akhouayri
From: Younes Akhouayri <git@younes.io>
From<bool> turns true into 1. A signed Bounded with N = 1 can hold
only -1 and 0. From<bool> therefore creates a value that the type does
not allow. Deref assumes the value is valid and calls
unreachable_unchecked() when it is not. Safe Rust can therefore reach
undefined behavior.
Rust cannot write N >= 2 directly in this From implementation. Add a
private BoolFits trait. It accepts every valid unsigned width and signed
widths from 2 through 128. The current Integer types do not use more
than 128 bits, so this keeps every valid conversion.
Fixes: 01e345e82ec3 ("rust: num: add Bounded integer wrapping type")
Closes: https://lore.kernel.org/rust-for-linux/OzuVxu0--J-9@younes.io/
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Younes Akhouayri <git@younes.io>
---
Do not allow From<bool> for signed Bounded values with N = 1.
Keep it available for signed Bounded values with N >= 2.
---
rust/kernel/num/bounded.rs | 50 +++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 45 insertions(+), 5 deletions(-)
diff --git a/rust/kernel/num/bounded.rs b/rust/kernel/num/bounded.rs
index d192610a687d..1856fe6c9865 100644
--- a/rust/kernel/num/bounded.rs
+++ b/rust/kernel/num/bounded.rs
@@ -13,7 +13,7 @@
};
use kernel::{
- num::Integer,
+ num::{Integer, Signed, Unsigned},
prelude::*, //
};
@@ -174,13 +174,26 @@ fn fits_within<T: Integer>(value: T, num_bits: u32) -> bool {
/// // `u8` (regardless of the passed value).
/// // let _ = Bounded::<u32, 6>::from(10u8);
///
-/// // Booleans can be converted into single-bit `Bounded`s.
+/// // Booleans can be converted into unsigned single-bit `Bounded`s.
///
/// let v = Bounded::<u64, 1>::from(false);
/// assert_eq!(v.get(), 0);
///
/// let v = Bounded::<u64, 1>::from(true);
/// assert_eq!(v.get(), 1);
+///
+/// // Signed integers need at least two bits to represent both `0` and `1`.
+/// let v = Bounded::<i8, 2>::from(true);
+/// assert_eq!(v.get(), 1);
+/// ```
+///
+/// A signed single-bit [`Bounded`] cannot represent `1`, so converting a boolean into one does not
+/// build.
+///
+/// ```compile_fail,E0277
+/// use kernel::num::Bounded;
+///
+/// let _: Bounded<i8, 1> = true.into();
/// ```
///
/// Infallible conversions from a [`Bounded`] to a primitive integer are also supported, and
@@ -1109,7 +1122,33 @@ fn from(value: Bounded<T, N>) -> $type {
i8 i16 i32 i64 isize
);
-// Single-bit `Bounded`s can be converted from/to a boolean.
+// Conversions between `Bounded`s and booleans.
+
+/// Marker for signedness types for which a valid `N`-bit integer can represent a boolean.
+trait BoolFits<const N: u32> {}
+
+impl<const N: u32> BoolFits<N> for Unsigned {}
+
+macro_rules! impl_signed_bool_fits {
+ ($($num_bits:literal)*) => {
+ $(
+ impl BoolFits<$num_bits> for Signed {}
+ )*
+ };
+}
+
+// `N >= 2` cannot be expressed as a trait bound without `generic_const_exprs`, so enumerate every
+// width supported by the current `Integer` implementations.
+impl_signed_bool_fits!(
+ 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+ 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
+ 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
+ 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
+ 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
+ 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
+ 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
+ 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
+);
impl<T> From<Bounded<T, 1>> for bool
where
@@ -1123,10 +1162,11 @@ fn from(value: Bounded<T, 1>) -> Self {
impl<T, const N: u32> From<bool> for Bounded<T, N>
where
T: Integer + From<bool>,
+ T::Signedness: BoolFits<N>,
{
fn from(value: bool) -> Self {
- // SAFETY: A boolean can be represented using a single bit, and thus fits within any
- // integer type for any `N` > 0.
+ // SAFETY: `__new` enforces that `N` is a valid width, and the `BoolFits` bound guarantees
+ // that the integer representation of `value` fits within any such `N`.
unsafe { Self::__new(T::from(value)) }
}
}
---
base-commit: 47f27155f17498fccb1f222f79089642337498a9
change-id: 20260815-fix-rust-bounded-from-bool-submit-3af836d8f718
Best regards,
--
Younes Akhouayri <git@younes.io>
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] rust: num: reject bool conversion to signed one-bit Bounded
@ 2026-08-15 8:06 ` Younes Akhouayri
0 siblings, 0 replies; 6+ messages in thread
From: Younes Akhouayri @ 2026-08-15 8:06 UTC (permalink / raw)
To: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan
Cc: rust-for-linux, stable, Younes Akhouayri
From<bool> turns true into 1. A signed Bounded with N = 1 can hold
only -1 and 0. From<bool> therefore creates a value that the type does
not allow. Deref assumes the value is valid and calls
unreachable_unchecked() when it is not. Safe Rust can therefore reach
undefined behavior.
Rust cannot write N >= 2 directly in this From implementation. Add a
private BoolFits trait. It accepts every valid unsigned width and signed
widths from 2 through 128. The current Integer types do not use more
than 128 bits, so this keeps every valid conversion.
Fixes: 01e345e82ec3 ("rust: num: add Bounded integer wrapping type")
Closes: https://lore.kernel.org/rust-for-linux/OzuVxu0--J-9@younes.io/
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Younes Akhouayri <git@younes.io>
---
Do not allow From<bool> for signed Bounded values with N = 1.
Keep it available for signed Bounded values with N >= 2.
---
rust/kernel/num/bounded.rs | 50 +++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 45 insertions(+), 5 deletions(-)
diff --git a/rust/kernel/num/bounded.rs b/rust/kernel/num/bounded.rs
index d192610a687d..1856fe6c9865 100644
--- a/rust/kernel/num/bounded.rs
+++ b/rust/kernel/num/bounded.rs
@@ -13,7 +13,7 @@
};
use kernel::{
- num::Integer,
+ num::{Integer, Signed, Unsigned},
prelude::*, //
};
@@ -174,13 +174,26 @@ fn fits_within<T: Integer>(value: T, num_bits: u32) -> bool {
/// // `u8` (regardless of the passed value).
/// // let _ = Bounded::<u32, 6>::from(10u8);
///
-/// // Booleans can be converted into single-bit `Bounded`s.
+/// // Booleans can be converted into unsigned single-bit `Bounded`s.
///
/// let v = Bounded::<u64, 1>::from(false);
/// assert_eq!(v.get(), 0);
///
/// let v = Bounded::<u64, 1>::from(true);
/// assert_eq!(v.get(), 1);
+///
+/// // Signed integers need at least two bits to represent both `0` and `1`.
+/// let v = Bounded::<i8, 2>::from(true);
+/// assert_eq!(v.get(), 1);
+/// ```
+///
+/// A signed single-bit [`Bounded`] cannot represent `1`, so converting a boolean into one does not
+/// build.
+///
+/// ```compile_fail,E0277
+/// use kernel::num::Bounded;
+///
+/// let _: Bounded<i8, 1> = true.into();
/// ```
///
/// Infallible conversions from a [`Bounded`] to a primitive integer are also supported, and
@@ -1109,7 +1122,33 @@ fn from(value: Bounded<T, N>) -> $type {
i8 i16 i32 i64 isize
);
-// Single-bit `Bounded`s can be converted from/to a boolean.
+// Conversions between `Bounded`s and booleans.
+
+/// Marker for signedness types for which a valid `N`-bit integer can represent a boolean.
+trait BoolFits<const N: u32> {}
+
+impl<const N: u32> BoolFits<N> for Unsigned {}
+
+macro_rules! impl_signed_bool_fits {
+ ($($num_bits:literal)*) => {
+ $(
+ impl BoolFits<$num_bits> for Signed {}
+ )*
+ };
+}
+
+// `N >= 2` cannot be expressed as a trait bound without `generic_const_exprs`, so enumerate every
+// width supported by the current `Integer` implementations.
+impl_signed_bool_fits!(
+ 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+ 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
+ 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
+ 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
+ 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
+ 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
+ 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
+ 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
+);
impl<T> From<Bounded<T, 1>> for bool
where
@@ -1123,10 +1162,11 @@ fn from(value: Bounded<T, 1>) -> Self {
impl<T, const N: u32> From<bool> for Bounded<T, N>
where
T: Integer + From<bool>,
+ T::Signedness: BoolFits<N>,
{
fn from(value: bool) -> Self {
- // SAFETY: A boolean can be represented using a single bit, and thus fits within any
- // integer type for any `N` > 0.
+ // SAFETY: `__new` enforces that `N` is a valid width, and the `BoolFits` bound guarantees
+ // that the integer representation of `value` fits within any such `N`.
unsafe { Self::__new(T::from(value)) }
}
}
---
base-commit: 47f27155f17498fccb1f222f79089642337498a9
change-id: 20260815-fix-rust-bounded-from-bool-submit-3af836d8f718
Best regards,
--
Younes Akhouayri <git@younes.io>
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] rust: num: reject bool conversion to signed one-bit Bounded
2026-08-15 8:06 ` Younes Akhouayri
(?)
@ 2026-08-15 9:47 ` Miguel Ojeda
2026-08-15 14:56 ` Younes Akhouayri
-1 siblings, 1 reply; 6+ messages in thread
From: Miguel Ojeda @ 2026-08-15 9:47 UTC (permalink / raw)
To: git
Cc: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, rust-for-linux, stable
On Sat, Aug 15, 2026 at 10:07 AM Younes Akhouayri via B4 Relay
<devnull+git.younes.io@kernel.org> wrote:
>
> +// `N >= 2` cannot be expressed as a trait bound without `generic_const_exprs`, so enumerate every
> +// width supported by the current `Integer` implementations.
> +impl_signed_bool_fits!(
> + 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
> + 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
> + 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
> + 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
> + 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
> + 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
> + 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
> + 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
> +);
Hmm... Did you see compile time suffer with this?
Cheers,
Miguel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] rust: num: reject bool conversion to signed one-bit Bounded
2026-08-15 9:47 ` Miguel Ojeda
@ 2026-08-15 14:56 ` Younes Akhouayri
2026-08-15 15:00 ` Miguel Ojeda
0 siblings, 1 reply; 6+ messages in thread
From: Younes Akhouayri @ 2026-08-15 14:56 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, Rust For Linux, Stable, Younes Akhouayri
I tested this in a Linux Docker container with Rust 1.85.0 and two CPUs,
alternating 50 builds of `rust/kernel.o` for the parent and v1.
The difference was 1.16 ms (0.066%), similar to the identical-source
control at 0.96 ms. So I could not measure a clear slowdown from the
patch.
Thanks,
Younes
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] rust: num: reject bool conversion to signed one-bit Bounded
2026-08-15 14:56 ` Younes Akhouayri
@ 2026-08-15 15:00 ` Miguel Ojeda
0 siblings, 0 replies; 6+ messages in thread
From: Miguel Ojeda @ 2026-08-15 15:00 UTC (permalink / raw)
To: Younes Akhouayri
Cc: Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Onur Özkan, Rust For Linux, Stable
On Sat, Aug 15, 2026 at 4:56 PM Younes Akhouayri <git@younes.io> wrote:
>
> I tested this in a Linux Docker container with Rust 1.85.0 and two CPUs,
> alternating 50 builds of `rust/kernel.o` for the parent and v1.
>
> The difference was 1.16 ms (0.066%), similar to the identical-source
> control at 0.96 ms. So I could not measure a clear slowdown from the
> patch.
Great, thanks for testing that!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] rust: num: reject bool conversion to signed one-bit Bounded
2026-08-15 8:06 ` Younes Akhouayri
(?)
(?)
@ 2026-08-15 18:50 ` Gary Guo
-1 siblings, 0 replies; 6+ messages in thread
From: Gary Guo @ 2026-08-15 18:50 UTC (permalink / raw)
To: git, Alexandre Courbot, Yury Norov, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Danilo Krummrich, Daniel Almeida,
Tamir Duberstein, Onur Özkan
Cc: rust-for-linux, stable
On Sat Aug 15, 2026 at 9:06 AM BST, Younes Akhouayri via B4 Relay wrote:
> From: Younes Akhouayri <git@younes.io>
>
> From<bool> turns true into 1. A signed Bounded with N = 1 can hold
> only -1 and 0. From<bool> therefore creates a value that the type does
> not allow. Deref assumes the value is valid and calls
> unreachable_unchecked() when it is not. Safe Rust can therefore reach
> undefined behavior.
>
> Rust cannot write N >= 2 directly in this From implementation. Add a
> private BoolFits trait. It accepts every valid unsigned width and signed
> widths from 2 through 128. The current Integer types do not use more
> than 128 bits, so this keeps every valid conversion.
Given that the existing `From<Bounded<T, N>> for uXX` implementation all
requires signedness match, I think this is being inconsistent (if we view bool
as u1). I think restricting it to just unsigned integer is better.
Best,
Gary
>
> Fixes: 01e345e82ec3 ("rust: num: add Bounded integer wrapping type")
> Closes: https://lore.kernel.org/rust-for-linux/OzuVxu0--J-9@younes.io/
> Cc: stable@vger.kernel.org
> Assisted-by: Codex:gpt-5.6-sol
> Signed-off-by: Younes Akhouayri <git@younes.io>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-08-15 18:50 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-15 8:06 [PATCH] rust: num: reject bool conversion to signed one-bit Bounded Younes Akhouayri via B4 Relay
2026-08-15 8:06 ` Younes Akhouayri
2026-08-15 9:47 ` Miguel Ojeda
2026-08-15 14:56 ` Younes Akhouayri
2026-08-15 15:00 ` Miguel Ojeda
2026-08-15 18:50 ` Gary Guo
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.