Skip to content

Commit 0c3a662

Browse files
authored
Rollup merge of rust-lang#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: rust-lang#90607 (comment) --- r? `@oli-obk`
2 parents 862565c + f926c0e commit 0c3a662

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

library/core/src/ptr/const_ptr.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -879,15 +879,30 @@ impl<T: ?Sized> *const T {
879879
/// # } }
880880
/// ```
881881
#[stable(feature = "align_offset", since = "1.36.0")]
882-
pub fn align_offset(self, align: usize) -> usize
882+
#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
883+
pub const fn align_offset(self, align: usize) -> usize
883884
where
884885
T: Sized,
885886
{
886887
if !align.is_power_of_two() {
887888
panic!("align_offset: align is not a power-of-two");
888889
}
889-
// SAFETY: `align` has been checked to be a power of 2 above
890-
unsafe { align_offset(self, align) }
890+
891+
fn rt_impl<T>(p: *const T, align: usize) -> usize {
892+
// SAFETY: `align` has been checked to be a power of 2 above
893+
unsafe { align_offset(p, align) }
894+
}
895+
896+
const fn ctfe_impl<T>(_: *const T, _: usize) -> usize {
897+
usize::MAX
898+
}
899+
900+
// SAFETY:
901+
// It is permisseble for `align_offset` to always return `usize::MAX`,
902+
// algorithm correctness can not depend on `align_offset` returning non-max values.
903+
//
904+
// As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
905+
unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
891906
}
892907
}
893908

library/core/src/ptr/mut_ptr.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -1142,15 +1142,30 @@ impl<T: ?Sized> *mut T {
11421142
/// # } }
11431143
/// ```
11441144
#[stable(feature = "align_offset", since = "1.36.0")]
1145-
pub fn align_offset(self, align: usize) -> usize
1145+
#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
1146+
pub const fn align_offset(self, align: usize) -> usize
11461147
where
11471148
T: Sized,
11481149
{
11491150
if !align.is_power_of_two() {
11501151
panic!("align_offset: align is not a power-of-two");
11511152
}
1152-
// SAFETY: `align` has been checked to be a power of 2 above
1153-
unsafe { align_offset(self, align) }
1153+
1154+
fn rt_impl<T>(p: *mut T, align: usize) -> usize {
1155+
// SAFETY: `align` has been checked to be a power of 2 above
1156+
unsafe { align_offset(p, align) }
1157+
}
1158+
1159+
const fn ctfe_impl<T>(_: *mut T, _: usize) -> usize {
1160+
usize::MAX
1161+
}
1162+
1163+
// SAFETY:
1164+
// It is permisseble for `align_offset` to always return `usize::MAX`,
1165+
// algorithm correctness can not depend on `align_offset` returning non-max values.
1166+
//
1167+
// As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
1168+
unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
11541169
}
11551170
}
11561171

0 commit comments

Comments
 (0)