about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-11-16 23:58:27 +0100
committerGitHub <noreply@github.com>2021-11-16 23:58:27 +0100
commit0c3a662ba97b292e253f340a7831542887457af9 (patch)
treee7496a9868e119357c401c3fc90b69c5db0f1412
parent862565c3af5a1181100484cc9de0a463a768d56d (diff)
parentf926c0e0d986baaf5caaec3bf21fa996422bb0b7 (diff)
downloadrust-0c3a662ba97b292e253f340a7831542887457af9.tar.gz
rust-0c3a662ba97b292e253f340a7831542887457af9.zip
Rollup merge of #90958 - WaffleLapkin:const_align_offset, r=oli-obk
Mark `<*const _>::align_offset` and `<*mut _>::align_offset` as `const fn`

This PR marks the following APIs as `const`:
```rust
impl<T> *const T {
    pub const fn align_offset(self, align: usize) -> usize;
}

impl<T> *mut T {
    pub const fn align_offset(self, align: usize) -> usize;
}
```

`const` implementation simply returns `usize::MAX`.

---

Previous discussion: https://github.com/rust-lang/rust/pull/90607#discussion_r743638164

---

r? `@oli-obk`
-rw-r--r--library/core/src/ptr/const_ptr.rs21
-rw-r--r--library/core/src/ptr/mut_ptr.rs21
2 files changed, 36 insertions, 6 deletions
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 95e86a688be..344b483662a 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -879,15 +879,30 @@ impl<T: ?Sized> *const T {
     /// # } }
     /// ```
     #[stable(feature = "align_offset", since = "1.36.0")]
-    pub fn align_offset(self, align: usize) -> usize
+    #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
+    pub const fn align_offset(self, align: usize) -> usize
     where
         T: Sized,
     {
         if !align.is_power_of_two() {
             panic!("align_offset: align is not a power-of-two");
         }
-        // SAFETY: `align` has been checked to be a power of 2 above
-        unsafe { align_offset(self, align) }
+
+        fn rt_impl<T>(p: *const T, align: usize) -> usize {
+            // SAFETY: `align` has been checked to be a power of 2 above
+            unsafe { align_offset(p, align) }
+        }
+
+        const fn ctfe_impl<T>(_: *const T, _: usize) -> usize {
+            usize::MAX
+        }
+
+        // SAFETY:
+        // It is permisseble for `align_offset` to always return `usize::MAX`,
+        // algorithm correctness can not depend on `align_offset` returning non-max values.
+        //
+        // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
+        unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
     }
 }
 
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 5d5527dc8b4..f3b2bdfefe5 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1142,15 +1142,30 @@ impl<T: ?Sized> *mut T {
     /// # } }
     /// ```
     #[stable(feature = "align_offset", since = "1.36.0")]
-    pub fn align_offset(self, align: usize) -> usize
+    #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
+    pub const fn align_offset(self, align: usize) -> usize
     where
         T: Sized,
     {
         if !align.is_power_of_two() {
             panic!("align_offset: align is not a power-of-two");
         }
-        // SAFETY: `align` has been checked to be a power of 2 above
-        unsafe { align_offset(self, align) }
+
+        fn rt_impl<T>(p: *mut T, align: usize) -> usize {
+            // SAFETY: `align` has been checked to be a power of 2 above
+            unsafe { align_offset(p, align) }
+        }
+
+        const fn ctfe_impl<T>(_: *mut T, _: usize) -> usize {
+            usize::MAX
+        }
+
+        // SAFETY:
+        // It is permisseble for `align_offset` to always return `usize::MAX`,
+        // algorithm correctness can not depend on `align_offset` returning non-max values.
+        //
+        // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
+        unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
     }
 }