On Fri, Jun 13, 2025 at 11:16:10PM +0900, Alexandre Courbot wrote: [...] > >> +#[repr(transparent)] > >> +pub struct PowerOfTwo<T>(T); > >> + > >> +macro_rules! power_of_two_impl { > >> + ($($t:ty),+) => { > >> + $( > >> + impl PowerOfTwo<$t> { > >> + /// Validates that `v` is a power of two at build-time, > >> and returns it wrapped into > >> + /// `PowerOfTwo`. > >> + /// > >> + /// A build error is triggered if `v` cannot be asserted > >> to be a power of two. > >> + /// > >> + /// # Examples > >> + /// > >> + /// ``` > >> + /// use kernel::num::PowerOfTwo; > >> + /// > >> + /// let v = PowerOfTwo::<u32>::new(256); > >> + /// assert_eq!(v.value(), 256); > >> + /// ``` > >> + #[inline(always)] > >> + pub const fn new(v: $t) -> Self { > > > > Then this function should be unsafe, because an invalid `v` can create > > an invalid PowerOfTwo. > > Doesn't the `build_assert` below allow us to keep this method safe, > since it will fail at build-time if it cannot be asserted that `v` is a > power of two? >
You're right, I misunderstood a bit, so if compiler cannot be sure about the assertion from build_assert!() it'll still generate a build error, i.e. even for cases like: pub fn my_power_of_two(v: i32) -> PowerOfTwo<i32> { PowerOfTwo::new(v) } where `v` is a user input and the value is unknown at the build time. build_assert!() will trigger. Regards, Boqun > > > >> + build_assert!(v.count_ones() == 1); > >> + Self(v) > >> + } [...]