Skip to content

ACP: ptr::is_aligned_for::<U> #588

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

Open
mathisbot opened this issue May 13, 2025 · 3 comments
Open

ACP: ptr::is_aligned_for::<U> #588

mathisbot opened this issue May 13, 2025 · 3 comments
Labels
api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api

Comments

@mathisbot
Copy link

mathisbot commented May 13, 2025

ACP: ptr::is_aligned_for::<U>

Summary

Introduce ptr::is_aligned_for<U>(self) -> bool on raw pointers (*const, *mut) and NonNull. This method checks whether the pointer is correctly aligned for a target type U, streamlining safe pointer casts without intermediate steps.

Alternatively (preferably?), introduce ptr::try_cast_aligned<U>(self) -> Option<Ptr<U>> on the same types. This method checks alignment and returns a casted pointer if it is correctly aligned.

Motivation

Currently, users that want to perform aligned read/write must cast before checking alignment:

#[repr(C)]
struct Complex {
    // ...
}

let ptr: *mut u8 = /* FFI pointer or any other provenance */ ;

assert!(ptr.cast::<Complex>().is_aligned(), "not aligned");
let complex_ptr = ptr.cast::<Complex>();
  • Clippy lint: clippy::cast_ptr_alignment triggers even when alignment checks are valid.
  • Readability: alignment intent is obscured by the needed cast.

Alternatively, users can use ptr::is_aligned_to, which is still unstable (see #96284) and less verbose.
Here, the problem of invalid alignments discussed in #96284 are not relevant as it would be provided by core::mem::align_of.

API

impl<T: ?Sized> *const T {
    pub fn is_aligned_for<U: Sized>(self) -> bool;
}

impl<T: ?Sized> *mut T { /* same */ }
impl<T: ?Sized> NonNull<T> { /* same */ }

Alternative: try_cast_aligned

As stated and suggested by @hanna-kruppe, it would be wise to combine alignment check and cast as follows:

impl<T: ?Sized> *const T {
    pub fn try_cast_aligned<U: Sized>(self) -> Option<*const U>;
}

impl<T: ?Sized> *mut T { /* same */ }
impl<T: ?Sized> NonNull<T> { /* same */ }

mirroring <[T]>::align_to but at a lower level.
This ensures the pointer is cast to the exact same type as the one used for alignment checks.

Rare cases (such as FFI) where the boolean value is needed, one could use ptr.try_cast_aligned::<SomeType>().is_some().
The implementation would be a combination of is_aligned_to and cast, so it would compile down to the exact same assembly as the hypothetical is_aligned_for.

The only downside of this solution is that it loses the verbosity of is_aligned_for in such cases.

References

@mathisbot mathisbot added T-libs-api api-change-proposal A proposal to add or alter unstable APIs in the standard libraries labels May 13, 2025
@hanna-kruppe
Copy link

hanna-kruppe commented May 14, 2025

Currently, checking that a pointer is properly aligned for a target type requires a cast prior to invoking ptr.is_aligned().
This can trigger the Clippy lint clippy::cast_ptr_alignment, which users must manually silence even though their check is valid.

The lint would have to learn to not warn about casts guarded by a is_aligned_for check. Probably doable, but as an outsider to clippy it’s not clear to me that this will be much easier than recognizing the cast + is_aligned pattern.

This ties to my other reservation about the proposal as written: while it allows checking alignment before casting, it doesn’t help with ensuring check + cast are always done together and agree on the type. An alternative would be something closer to <[T]>::align_to that combines alignment check and cast: try_cast_aligned(Ptr<T>) -> Option<Ptr<U>>.

@mathisbot
Copy link
Author

An alternative would be something closer to <[T]>::align_to that combines alignment check and cast: try_cast_aligned(Ptr<T>) -> Option<Ptr<U>>.

I've updated the original post to include this idea.
As it comes from you, feel free to make the PR and everything else your own should the proposal be accepted. Otherwise, it would be a pleasure to do it myself 😊

@hanna-kruppe
Copy link

hanna-kruppe commented May 16, 2025

I have very limited time for open source contributions these days, and I don’t have a big need for this API myself, so I don’t intend to claim any of the work here for myself :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-change-proposal A proposal to add or alter unstable APIs in the standard libraries T-libs-api
Projects
None yet
Development

No branches or pull requests

2 participants