about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Markeffsky <@>2022-10-07 22:24:31 +0200
committerLukas Markeffsky <@>2022-11-19 16:47:42 +0100
commit6f6320a0a916b57dc37568d3ce5f5ed0e749ef61 (patch)
tree174f96c95e58a75b88b93ef90b430a271c3131fe
parent8cf6b16185745822b109dfa17c26d2a4ee4184ab (diff)
downloadrust-6f6320a0a916b57dc37568d3ce5f5ed0e749ef61.tar.gz
rust-6f6320a0a916b57dc37568d3ce5f5ed0e749ef61.zip
constify `pointer::is_aligned{,_to}`
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/ptr/const_ptr.rs25
-rw-r--r--library/core/src/ptr/mut_ptr.rs25
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) }
     }
 }