@@ -195,17 +195,27 @@ use core::{
195195 NonZeroU16 , NonZeroU32 , NonZeroU64 , NonZeroU8 , NonZeroUsize , Wrapping ,
196196 } ,
197197 ops:: { Deref , DerefMut } ,
198- ptr, slice,
198+ ptr:: { self , NonNull } ,
199+ slice,
199200} ;
200201
201202#[ cfg( feature = "alloc" ) ]
202203extern crate alloc;
203204#[ cfg( feature = "alloc" ) ]
204205use {
205206 alloc:: { boxed:: Box , vec:: Vec } ,
206- core:: { alloc:: Layout , ptr :: NonNull } ,
207+ core:: alloc:: Layout ,
207208} ;
208209
210+ // For each polyfill, as soon as the corresponding feature is stable, the
211+ // polyfill import will be unused because method/function resolution will prefer
212+ // the inherent method/function over a trait method/function. Thus, we suppress
213+ // the `unused_imports` warning.
214+ //
215+ // See the documentation on `util::polyfills` for more information.
216+ #[ allow( unused_imports) ]
217+ use crate :: util:: polyfills:: { NonNullExt as _, NonNullSliceExt as _} ;
218+
209219// This is a hack to allow zerocopy-derive derives to work in this crate. They
210220// assume that zerocopy is linked as an extern crate, so they access items from
211221// it as `zerocopy::Xxx`. This makes that still work.
@@ -300,8 +310,11 @@ impl SizeInfo {
300310 }
301311}
302312
303- #[ cfg_attr( test, derive( Copy , Clone , Debug ) ) ]
304- enum _CastType {
313+ #[ doc( hidden) ]
314+ #[ derive( Copy , Clone ) ]
315+ #[ cfg_attr( test, derive( Debug ) ) ]
316+ #[ allow( missing_debug_implementations) ]
317+ pub enum _CastType {
305318 _Prefix,
306319 _Suffix,
307320}
@@ -406,6 +419,9 @@ impl DstLayout {
406419 ///
407420 /// # Panics
408421 ///
422+ /// `validate_cast_and_convert_metadata` will panic if `self` describes a
423+ /// DST whose trailing slice element is zero-sized.
424+ ///
409425 /// If `addr + bytes_len` overflows `usize`,
410426 /// `validate_cast_and_convert_metadata` may panic, or it may return
411427 /// incorrect results. No guarantees are made about when
@@ -573,12 +589,27 @@ impl DstLayout {
573589pub unsafe trait KnownLayout : sealed:: KnownLayoutSealed {
574590 #[ doc( hidden) ]
575591 const LAYOUT : DstLayout ;
592+
593+ /// SAFETY: The returned pointer has the same address and provenance as
594+ /// `bytes`. If `Self` is a DST, the returned pointer's referent has `elems`
595+ /// elements in its trailing slice. If `Self` is sized, `elems` is ignored.
596+ #[ doc( hidden) ]
597+ fn raw_from_ptr_len ( bytes : NonNull < u8 > , elems : usize ) -> NonNull < Self > ;
576598}
577599
578600impl < T : KnownLayout > sealed:: KnownLayoutSealed for [ T ] { }
579601// SAFETY: Delegates safety to `DstLayout::for_slice`.
580602unsafe impl < T : KnownLayout > KnownLayout for [ T ] {
581603 const LAYOUT : DstLayout = DstLayout :: for_slice :: < T > ( ) ;
604+
605+ // SAFETY: `.cast` preserves address and provenance. The returned pointer
606+ // refers to an object with `elems` elements by construction.
607+ #[ inline( always) ]
608+ fn raw_from_ptr_len ( data : NonNull < u8 > , elems : usize ) -> NonNull < Self > {
609+ // TODO(#67): Remove this allow. See NonNullExt for more details.
610+ #[ allow( unstable_name_collisions) ]
611+ NonNull :: slice_from_raw_parts ( data. cast :: < T > ( ) , elems)
612+ }
582613}
583614
584615#[ rustfmt:: skip]
0 commit comments