diff options
| author | Lukas Markeffsky <@> | 2022-10-07 22:24:31 +0200 |
|---|---|---|
| committer | Lukas Markeffsky <@> | 2022-11-19 16:47:42 +0100 |
| commit | 6f6320a0a916b57dc37568d3ce5f5ed0e749ef61 (patch) | |
| tree | 174f96c95e58a75b88b93ef90b430a271c3131fe | |
| parent | 8cf6b16185745822b109dfa17c26d2a4ee4184ab (diff) | |
| download | rust-6f6320a0a916b57dc37568d3ce5f5ed0e749ef61.tar.gz rust-6f6320a0a916b57dc37568d3ce5f5ed0e749ef61.zip | |
constify `pointer::is_aligned{,_to}`
| -rw-r--r-- | library/core/src/lib.rs | 1 | ||||
| -rw-r--r-- | library/core/src/ptr/const_ptr.rs | 25 | ||||
| -rw-r--r-- | library/core/src/ptr/mut_ptr.rs | 25 |
3 files changed, 39 insertions, 12 deletions
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 33b969c249a..848eccd7f29 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -130,6 +130,7 @@ #![feature(const_option)] #![feature(const_option_ext)] #![feature(const_pin)] +#![feature(const_pointer_is_aligned)] #![feature(const_ptr_sub_ptr)] #![feature(const_replace)] #![feature(const_result_drop)] diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index f0cdc3d8399..8b96cf06be4 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1363,10 +1363,13 @@ impl<T: ?Sized> *const T { } /// Returns whether the pointer is properly aligned for `T`. + // #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap + // compiler will always return false. #[must_use] #[inline] #[unstable(feature = "pointer_is_aligned", issue = "96284")] - pub fn is_aligned(self) -> bool + #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")] + pub const fn is_aligned(self) -> bool where T: Sized, { @@ -1381,16 +1384,26 @@ impl<T: ?Sized> *const T { /// # Panics /// /// The function panics if `align` is not a power-of-two (this includes 0). + // #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap + // compiler will always return false. #[must_use] #[inline] #[unstable(feature = "pointer_is_aligned", issue = "96284")] - pub fn is_aligned_to(self, align: usize) -> bool { - if !align.is_power_of_two() { - panic!("is_aligned_to: align is not a power-of-two"); + #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")] + pub const fn is_aligned_to(self, align: usize) -> bool { + assert!(align.is_power_of_two(), "is_aligned_to: align is not a power-of-two"); + + #[inline] + fn runtime(ptr: *const u8, align: usize) -> bool { + ptr.addr() & (align - 1) == 0 + } + + const fn comptime(ptr: *const u8, align: usize) -> bool { + ptr.align_offset(align) == 0 } - // Cast is needed for `T: !Sized` - self.cast::<u8>().addr() & align - 1 == 0 + // SAFETY: `ptr.align_offset(align)` returns 0 if and only if the pointer is already aligned. + unsafe { intrinsics::const_eval_select((self.cast::<u8>(), align), comptime, runtime) } } } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index eb1a6a07c6b..2d73c24b5b4 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1631,10 +1631,13 @@ impl<T: ?Sized> *mut T { } /// Returns whether the pointer is properly aligned for `T`. + // #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap + // compiler will always return false. #[must_use] #[inline] #[unstable(feature = "pointer_is_aligned", issue = "96284")] - pub fn is_aligned(self) -> bool + #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")] + pub const fn is_aligned(self) -> bool where T: Sized, { @@ -1649,16 +1652,26 @@ impl<T: ?Sized> *mut T { /// # Panics /// /// The function panics if `align` is not a power-of-two (this includes 0). + // #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap + // compiler will always return false. #[must_use] #[inline] #[unstable(feature = "pointer_is_aligned", issue = "96284")] - pub fn is_aligned_to(self, align: usize) -> bool { - if !align.is_power_of_two() { - panic!("is_aligned_to: align is not a power-of-two"); + #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")] + pub const fn is_aligned_to(self, align: usize) -> bool { + assert!(align.is_power_of_two(), "is_aligned_to: align is not a power-of-two"); + + #[inline] + fn runtime(ptr: *mut u8, align: usize) -> bool { + ptr.addr() & (align - 1) == 0 + } + + const fn comptime(ptr: *mut u8, align: usize) -> bool { + ptr.align_offset(align) == 0 } - // Cast is needed for `T: !Sized` - self.cast::<u8>().addr() & align - 1 == 0 + // SAFETY: `ptr.align_offset(align)` returns 0 if and only if the pointer is already aligned. + unsafe { intrinsics::const_eval_select((self.cast::<u8>(), align), comptime, runtime) } } } |
