-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tracking Issue for const_pointer_is_aligned
#104203
Comments
What would const code need this for? |
Const alignment in generalConst code doesn't need to check for alignment. The are, however, algorithms that depend on alignment at runtime and also make sense in const. In the standard library we have To make these functions work in const we have two options:
This feature (
|
…lign-offset, r=oli-obk Constify `is_aligned` via `align_offset` Alternative to rust-lang#102753 Make `align_offset` work in const eval (and not always return `usize::MAX`) and then use that to constify `is_aligned{_to}`. Tracking Issue: rust-lang#104203
…et, r=oli-obk Constify `is_aligned` via `align_offset` Alternative to rust-lang/rust#102753 Make `align_offset` work in const eval (and not always return `usize::MAX`) and then use that to constify `is_aligned{_to}`. Tracking Issue: rust-lang/rust#104203
Also see the discussion here -- having I think something like a new |
If we add If it just returns As for potential footguns, the only thing I can think of is relying on
Or the same thing extended for larger alignments. For example in this buggy buggy program & error message#![feature(const_slice_split_at_not_mut)]
#![feature(const_pointer_is_aligned)]
#![feature(pointer_is_aligned)]
use core::slice;
const fn bad_align_to(slice: &[u8]) -> (&[u8], &[u16], &[u8]) {
if slice.is_empty() {
return (&[], &[], &[]);
}
let (front, aligned) = if slice.as_ptr().is_aligned_to(2) {
([].as_slice(), slice)
} else {
slice.split_at(1)
};
let (middle, back) = aligned.split_at(aligned.len() / 2 * 2);
// SAFETY: It's safe to transmute between `[u8; N * 2]` and `[u16; N]`.
// We ensure that `middle` is aligned to 2 above.
let middle_transmute = unsafe {
slice::from_raw_parts(middle.as_ptr().cast::<u16>(), middle.len() / 2)
};
(front, middle_transmute, back)
}
fn main() {
let a = [1, 2, 3, 4, 5, 6];
for start in 0..a.len() {
for end in start..a.len() {
let slice = &a[start..end];
println!("{:X?} -> {:X?}", slice, bad_align_to(slice));
}
}
const _FOO: &[u16] = bad_align_to(&[1, 2, 3]).1; // ERROR
const _BAR: u16 = bad_align_to(&[1, 2, 3]).1[0]; // ERROR after #104616
}
In my opinion, every program that uses |
Yeah I was thinking the function name would help serve as a warning sign. Cc @thomcc who brought this up in Zulip. |
Imo this is preferable. The alignment checks are only needed for performance optimizations that aren't relevant at comptime. The const version can be very naive code.
Note that we don't even ship the standard library with debug asserts enabled. So for now these are mostly CI aids. It doesn't seem right to extend the public API surface to enable this at const time, especially since alignment at const time is underdetermined, unlike runtime alignment.
Wouldn't a |
…et, r=oli-obk Constify `is_aligned` via `align_offset` Alternative to rust-lang/rust#102753 Make `align_offset` work in const eval (and not always return `usize::MAX`) and then use that to constify `is_aligned{_to}`. Tracking Issue: rust-lang/rust#104203
#132423 will remove this feature gate and de-constify these functions. Their current implementation is not something we want to stabilize, so a blank restart is required here. |
Rollup merge of rust-lang#132423 - RalfJung:const-eval-align-offset, r=dtolnay remove const-support for align_offset and is_aligned As part of the recent discussion to stabilize `ptr.is_null()` in const context, the general vibe was that it's okay for a const function to panic when the same operation would work at runtime (that's just a case of "dynamically detecting that something is not supported as a const operation"), but it is *not* okay for a const function to just return a different result. Following that, `is_aligned` and `is_aligned_to` have their const status revoked in this PR, since they do return actively wrong results at const time. In the future we can consider having a new intrinsic or so that can check whether a pointer is "guaranteed to be aligned", but the current implementation based on `align_offset` does not have the behavior we want. In fact `align_offset` itself behaves quite strangely in const, and that support needs a bunch of special hacks. That doesn't seem worth it. Instead, the users that can fall back to a different implementation should just use const_eval_select directly, and everything else should not be made const-callable. So this PR does exactly that, and entirely removes const support for align_offset. Closes some tracking issues by removing the associated features: Closes rust-lang#90962 Closes rust-lang#104203 Cc `@rust-lang/wg-const-eval` `@rust-lang/libs-api`
Feature gate:
#![feature(const_pointer_is_aligned)]
This is a tracking issue for using
ptr.is_aligned()
andptr.is_aligned_to(alignment)
inconst
contexts.Public API
Steps / History
is_aligned
viaalign_offset
#102795NonNull
methods stabilized,const
ness moved to this gate Stabilizenon_null_convenience
#124498const
functions to behave differently during constant-evaluation and runtime: Relax const-eval restrictions rfcs#3352Unresolved Questions
guaranteed_aligned{,to}
instead?true
if the pointer is guaranteed to be aligned at runtime andfalse
if we don't know whether the pointer is aligned at runtime. This is the current implementation.align_offset
. This allows changes to const alignment in the future.Related Links
is_aligned
: Tracking Issue for pointer_is_aligned_to #96284align_offset
: Tracking Issue forconst_align_offset
#90962Footnotes
https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html ↩
The text was updated successfully, but these errors were encountered: