12

Partially stabilize `(const_)slice_ptr_len` feature by stabilizing `NonNull::len...

 2 years ago
source link: https://github.com/rust-lang/rust/pull/94640
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Contributor

@Pointerbender Pointerbender commented on Mar 5

edited

This PR partially stabilizes features const_slice_ptr_len and slice_ptr_len by only stabilizing NonNull::len. This partial stabilization is tracked under features slice_ptr_len_nonnull and const_slice_ptr_len_nonnull, for which this PR can serve as the tracking issue.

To summarize the discussion from #71146 leading up to this partial stabilization request:

It's currently a bit footgunny to obtain the length of a raw slice pointer, stabilization of NonNull:len will help with removing these footguns. Some example footguns are:

/// # Safety
/// The caller must ensure that `ptr`:
/// 1. does not point to memory that was previously allocated but is now deallocated;
/// 2. is within the bounds of a single allocated object;
/// 3. does not to point to a slice for which the length exceeds `isize::MAX` bytes;
/// 4. points to a properly aligned address;
/// 5. does not point to uninitialized memory;
/// 6. does not point to a mutably borrowed memory location.
pub unsafe fn ptr_len<T>(ptr: core::ptr::NonNull<[T]>) -> usize {
   (&*ptr.as_ptr()).len()
}

A slightly less complicated version (but still more complicated than it needs to be):

/// # Safety
/// The caller must ensure that the start of `ptr`:
/// 1. does not point to memory that was previously allocated but is now deallocated;
/// 2. must be within the bounds of a single allocated object.
pub unsafe fn ptr_len<T>(ptr: NonNull<[T]>) -> usize {
   (&*(ptr.as_ptr() as *const [()])).len()
}

This PR does not stabilize <*const [T]>::len and <*mut [T]>::len because the tracking issue #71146 list a potential blocker for these methods, but this blocker does not apply to NonNull::len.

We should probably also ping the Constant Evaluation WG since this PR includes a #[rustc_allow_const_fn_unstable(const_slice_ptr_len)]. My instinct here is that this will probably be okay because the pointer is not actually dereferenced and len() does not touch the address component of the pointer, but would be best to double check :)

One potential down-side was raised that stabilizing NonNull::len could lead to encouragement of coding patterns like:

pub fn ptr_len<T>(ptr: *mut [T]) -> usize {
   NonNull::new(ptr).unwrap().len()
}

which unnecessarily assert non-nullness. However, these are much less of a footgun than the above examples and this should be resolved when slice_ptr_len fully stabilizes eventually.

josephlr reacted with rocket emoji

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK