Rollup merge of #71082 - NeoRaider:ptr_slice_len, r=oli-obk,SimonSapin
ptr: introduce len() method on raw slices It is already possible to extract the pointer part of a raw slice by a simple cast, but retrieving the length is not possible without relying on the representation of the raw slice when it is not valid to convert the raw slice into a slice reference (i.e. the pointer is null or unaligned). ~Introduce a new function ptr::slice_len() to add this missing feature.~ Introduce a len() method on raw slices to add this missing feature.
This commit is contained in:
commit
6b8fb7c48a
@ -706,6 +706,34 @@ impl<T: ?Sized> *const T {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[lang = "const_slice_ptr"]
|
||||
impl<T> *const [T] {
|
||||
/// Returns the length of a raw slice.
|
||||
///
|
||||
/// The returned value is the number of **elements**, not the number of bytes.
|
||||
///
|
||||
/// This function is safe, even when the raw slice cannot be cast to a slice
|
||||
/// reference because the pointer is null or unaligned.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(slice_ptr_len)]
|
||||
///
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
|
||||
/// assert_eq!(slice.len(), 3);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "slice_ptr_len", issue = "71146")]
|
||||
#[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
|
||||
pub const fn len(self) -> usize {
|
||||
unsafe { Repr { rust: self }.raw }.len
|
||||
}
|
||||
}
|
||||
|
||||
// Equality for pointers
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> PartialEq for *const T {
|
||||
|
@ -894,6 +894,34 @@ impl<T: ?Sized> *mut T {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[lang = "mut_slice_ptr"]
|
||||
impl<T> *mut [T] {
|
||||
/// Returns the length of a raw slice.
|
||||
///
|
||||
/// The returned value is the number of **elements**, not the number of bytes.
|
||||
///
|
||||
/// This function is safe, even when the raw slice cannot be cast to a slice
|
||||
/// reference because the pointer is null or unaligned.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(slice_ptr_len)]
|
||||
///
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// let slice: *mut [i8] = ptr::slice_from_raw_parts_mut(ptr::null_mut(), 3);
|
||||
/// assert_eq!(slice.len(), 3);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "slice_ptr_len", issue = "71146")]
|
||||
#[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
|
||||
pub const fn len(self) -> usize {
|
||||
unsafe { Repr { rust_mut: self }.raw }.len
|
||||
}
|
||||
}
|
||||
|
||||
// Equality for pointers
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> PartialEq for *mut T {
|
||||
|
@ -135,6 +135,8 @@ language_item_table! {
|
||||
SliceU8AllocImplItem, "slice_u8_alloc", slice_u8_alloc_impl, Target::Impl;
|
||||
ConstPtrImplItem, "const_ptr", const_ptr_impl, Target::Impl;
|
||||
MutPtrImplItem, "mut_ptr", mut_ptr_impl, Target::Impl;
|
||||
ConstSlicePtrImplItem, "const_slice_ptr", const_slice_ptr_impl, Target::Impl;
|
||||
MutSlicePtrImplItem, "mut_slice_ptr", mut_slice_ptr_impl, Target::Impl;
|
||||
I8ImplItem, "i8", i8_impl, Target::Impl;
|
||||
I16ImplItem, "i16", i16_impl, Target::Impl;
|
||||
I32ImplItem, "i32", i32_impl, Target::Impl;
|
||||
|
@ -649,11 +649,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
ty::RawPtr(ty::TypeAndMut { ty: _, mutbl }) => {
|
||||
let lang_def_id = match mutbl {
|
||||
hir::Mutability::Not => lang_items.const_ptr_impl(),
|
||||
hir::Mutability::Mut => lang_items.mut_ptr_impl(),
|
||||
let (lang_def_id1, lang_def_id2) = match mutbl {
|
||||
hir::Mutability::Not => {
|
||||
(lang_items.const_ptr_impl(), lang_items.const_slice_ptr_impl())
|
||||
}
|
||||
hir::Mutability::Mut => {
|
||||
(lang_items.mut_ptr_impl(), lang_items.mut_slice_ptr_impl())
|
||||
}
|
||||
};
|
||||
self.assemble_inherent_impl_for_primitive(lang_def_id);
|
||||
self.assemble_inherent_impl_for_primitive(lang_def_id1);
|
||||
self.assemble_inherent_impl_for_primitive(lang_def_id2);
|
||||
}
|
||||
ty::Int(i) => {
|
||||
let lang_def_id = match i {
|
||||
|
@ -112,6 +112,30 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
||||
item.span,
|
||||
);
|
||||
}
|
||||
ty::RawPtr(ty::TypeAndMut { ty: inner, mutbl: hir::Mutability::Not })
|
||||
if matches!(inner.kind, ty::Slice(_)) =>
|
||||
{
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.const_slice_ptr_impl(),
|
||||
None,
|
||||
"const_slice_ptr",
|
||||
"*const [T]",
|
||||
item.span,
|
||||
);
|
||||
}
|
||||
ty::RawPtr(ty::TypeAndMut { ty: inner, mutbl: hir::Mutability::Mut })
|
||||
if matches!(inner.kind, ty::Slice(_)) =>
|
||||
{
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
lang_items.mut_slice_ptr_impl(),
|
||||
None,
|
||||
"mut_slice_ptr",
|
||||
"*mut [T]",
|
||||
item.span,
|
||||
);
|
||||
}
|
||||
ty::RawPtr(ty::TypeAndMut { ty: _, mutbl: hir::Mutability::Not }) => {
|
||||
self.check_primitive_impl(
|
||||
def_id,
|
||||
|
@ -62,6 +62,8 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
||||
lang_items.slice_u8_alloc_impl(),
|
||||
lang_items.const_ptr_impl(),
|
||||
lang_items.mut_ptr_impl(),
|
||||
lang_items.const_slice_ptr_impl(),
|
||||
lang_items.mut_slice_ptr_impl(),
|
||||
];
|
||||
|
||||
for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user