99use core:: {
1010 fmt:: { Debug , Formatter } ,
1111 marker:: PhantomData ,
12- ptr:: NonNull ,
1312} ;
1413
1514use crate :: {
@@ -50,6 +49,7 @@ mod def {
5049 ///
5150 /// `Ptr<'a, T>` is [covariant] in `'a` and invariant in `T`.
5251 ///
52+ /// [`NonNull<T>`]: core::ptr::NonNull
5353 /// [covariant]: https://doc.rust-lang.org/reference/subtyping.html
5454 pub struct Ptr < ' a , T , I >
5555 where
@@ -74,32 +74,6 @@ mod def {
7474 T : ' a + ?Sized ,
7575 I : Invariants ,
7676 {
77- /// Constructs a `Ptr` from a [`NonNull`].
78- ///
79- /// # Safety
80- ///
81- /// The caller promises that:
82- ///
83- /// 0. If `ptr`'s referent is not zero sized, then `ptr` has valid
84- /// provenance for its referent, which is entirely contained in some
85- /// Rust allocation, `A`.
86- /// 1. If `ptr`'s referent is not zero sized, `A` is guaranteed to live
87- /// for at least `'a`.
88- /// 2. `ptr` conforms to the aliasing invariant of
89- /// [`I::Aliasing`](invariant::Aliasing).
90- /// 3. `ptr` conforms to the alignment invariant of
91- /// [`I::Alignment`](invariant::Alignment).
92- /// 4. `ptr` conforms to the validity invariant of
93- /// [`I::Validity`](invariant::Validity).
94- pub ( super ) unsafe fn new ( ptr : NonNull < T > ) -> Ptr < ' a , T , I > {
95- // SAFETY: The caller has promised (in 0 - 1) to satisfy all safety
96- // invariants of `PtrInner::new`.
97- let ptr = unsafe { PtrInner :: new ( ptr) } ;
98- // SAFETY: The caller has promised (in 2 - 4) to satisfy all safety
99- // invariants of `Ptr`.
100- Self { ptr, _invariants : PhantomData }
101- }
102-
10377 /// Constructs a new `Ptr` from a [`PtrInner`].
10478 ///
10579 /// # Safety
@@ -402,7 +376,7 @@ mod _conversions {
402376 // operate on these references simultaneously
403377 // - By `U: TransmuteFromPtr<T, I::Aliasing, I::Validity, V>`, it is
404378 // sound to perform this transmute.
405- unsafe { self . transmute_unchecked ( |ptr| SizeEq :: cast_from_raw ( ptr ) . as_non_null ( ) ) }
379+ unsafe { self . transmute_unchecked ( SizeEq :: cast_from_raw) }
406380 }
407381
408382 #[ doc( hidden) ]
@@ -420,7 +394,7 @@ mod _conversions {
420394 // referent simultaneously
421395 // - By `T: TransmuteFromPtr<T, I::Aliasing, I::Validity, V>`, it is
422396 // sound to perform this transmute.
423- let ptr = unsafe { self . transmute_unchecked ( |t| t . as_non_null ( ) ) } ;
397+ let ptr = unsafe { self . transmute_unchecked ( SizeEq :: cast_from_raw ) } ;
424398 // SAFETY: `self` and `ptr` have the same address and referent type.
425399 // Therefore, if `self` satisfies `I::Alignment`, then so does
426400 // `ptr`.
@@ -450,12 +424,6 @@ mod _conversions {
450424 /// `I::Aliasing`, `I::Validity`, and `V`, and may depend upon the
451425 /// presence, absence, or specific location of `UnsafeCell`s in `T`
452426 /// and/or `U`. See [`Validity`] for more details.
453- ///
454- /// `transmute_unchecked` guarantees that the pointer passed to `cast`
455- /// will reference a byte sequence which is either contained inside a
456- /// single allocated object or is zero sized. In either case, this means
457- /// that its size will fit in an `isize` and it will not wrap around the
458- /// address space.
459427 #[ doc( hidden) ]
460428 #[ inline]
461429 pub unsafe fn transmute_unchecked < U : ?Sized , V , F > (
@@ -464,25 +432,18 @@ mod _conversions {
464432 ) -> Ptr < ' a , U , ( I :: Aliasing , Unaligned , V ) >
465433 where
466434 V : Validity ,
467- F : FnOnce ( PtrInner < ' _ , T > ) -> NonNull < U > ,
435+ F : FnOnce ( PtrInner < ' a , T > ) -> PtrInner < ' a , U > ,
468436 {
469- // SAFETY: By invariant on `self`, `self.as_inner().as_non_null()`
470- // either references a zero-sized byte range, or else it references
471- // a byte range contained inside of a single allocated objection.
472437 let ptr = cast ( self . as_inner ( ) ) ;
473438
474439 // SAFETY:
475440 //
476- // Lemma 1: `ptr` has the same provenance as `self`. The caller
477- // promises that `cast` preserves provenance, and we call it with
478- // `self.as_inner().as_non_null()`.
441+ // The following safety arguments rely on the fact that the caller
442+ // promises that `cast` returns a `PtrInner` which addresses a
443+ // prefix of the bytes of `*self`, and so properties that hold of
444+ // `*self` also hold of `*ptr`.
479445 //
480- // 0. By invariant, if `self`'s referent is not zero sized, then
481- // `self` has valid provenance for its entire referent, which is
482- // entirely contained in `A`. By Lemma 1, so does `ptr`.
483- // 1. By invariant on `self`, if `self`'s referent is not zero
484- // sized, then `A` is guaranteed to live for at least `'a`.
485- // 2. `ptr` conforms to the aliasing invariant of `I::Aliasing`:
446+ // 0. `ptr` conforms to the aliasing invariant of `I::Aliasing`:
486447 // - `Exclusive`: `self` is the only `Ptr` or reference which is
487448 // permitted to read or modify the referent for the lifetime
488449 // `'a`. Since we consume `self` by value, the returned pointer
@@ -499,10 +460,10 @@ mod _conversions {
499460 // of `UnsafeCell`s is unsound, this must be impossible using
500461 // `&T` and `&U`.
501462 // - `Inaccessible`: There are no restrictions we need to uphold.
502- // 3 . `ptr` trivially satisfies the alignment invariant `Unaligned`.
503- // 4 . The caller promises that `ptr` conforms to the validity
463+ // 1 . `ptr` trivially satisfies the alignment invariant `Unaligned`.
464+ // 2 . The caller promises that `ptr` conforms to the validity
504465 // invariant `V` with respect to its referent type, `U`.
505- unsafe { Ptr :: new ( ptr) }
466+ unsafe { Ptr :: from_inner ( ptr) }
506467 }
507468 }
508469
@@ -533,10 +494,7 @@ mod _conversions {
533494 // and the returned `Ptr` permit the same set of bit patterns in
534495 // their referents, and so neither can be used to violate the
535496 // validity of the other.
536- let ptr = unsafe {
537- #[ allow( clippy:: as_conversions) ]
538- self . transmute_unchecked ( |ptr| ptr. as_non_null ( ) . cast :: < crate :: Unalign < T > > ( ) )
539- } ;
497+ let ptr = unsafe { self . transmute_unchecked ( PtrInner :: cast_sized) } ;
540498 ptr. bikeshed_recall_aligned ( )
541499 }
542500 }
@@ -911,7 +869,7 @@ mod _casts {
911869 /// around the address space.
912870 #[ doc( hidden) ]
913871 #[ inline]
914- pub unsafe fn cast_unsized_unchecked < U , F : FnOnce ( PtrInner < ' _ , T > ) -> NonNull < U > > (
872+ pub unsafe fn cast_unsized_unchecked < U , F : FnOnce ( PtrInner < ' a , T > ) -> PtrInner < ' a , U > > (
915873 self ,
916874 cast : F ,
917875 ) -> Ptr < ' a , U , ( I :: Aliasing , Unaligned , I :: Validity ) >
@@ -959,7 +917,7 @@ mod _casts {
959917 where
960918 T : MutationCompatible < U , I :: Aliasing , I :: Validity , I :: Validity , R > ,
961919 U : ' a + ?Sized + CastableFrom < T , I :: Validity , I :: Validity > ,
962- F : FnOnce ( PtrInner < ' _ , T > ) -> NonNull < U > ,
920+ F : FnOnce ( PtrInner < ' a , T > ) -> PtrInner < ' a , U > ,
963921 {
964922 // SAFETY: Because `T: MutationCompatible<U, I::Aliasing, R>`, one
965923 // of the following holds:
@@ -982,40 +940,18 @@ mod _casts {
982940 {
983941 /// Casts this pointer-to-initialized into a pointer-to-bytes.
984942 #[ allow( clippy:: wrong_self_convention) ]
985- pub ( crate ) fn as_bytes < R > ( self ) -> Ptr < ' a , [ u8 ] , ( I :: Aliasing , Aligned , Valid ) >
943+ #[ must_use]
944+ #[ inline]
945+ pub fn as_bytes < R > ( self ) -> Ptr < ' a , [ u8 ] , ( I :: Aliasing , Aligned , Valid ) >
986946 where
987947 T : Read < I :: Aliasing , R > ,
988948 I :: Aliasing : Reference ,
989949 {
990- let bytes = match T :: size_of_val_raw ( self . as_inner ( ) . as_non_null ( ) ) {
991- Some ( bytes) => bytes,
992- // SAFETY: `KnownLayout::size_of_val_raw` promises to always
993- // return `Some` so long as the resulting size fits in a
994- // `usize`. By invariant on `Ptr`, `self` refers to a range of
995- // bytes whose size fits in an `isize`, which implies that it
996- // also fits in a `usize`.
997- None => unsafe { core:: hint:: unreachable_unchecked ( ) } ,
998- } ;
999-
1000- // SAFETY:
1001- // - `slice_from_raw_parts_mut` and `.cast` both preserve the
1002- // pointer's address, and `bytes` is the length of `p`, so the
1003- // returned pointer addresses the same bytes as `p`
1004- // - `slice_from_raw_parts_mut` and `.cast` both preserve provenance
1005- let ptr: Ptr < ' a , [ u8 ] , _ > = unsafe {
1006- self . cast_unsized ( |p : PtrInner < ' _ , T > | {
1007- let ptr = core:: ptr:: slice_from_raw_parts_mut (
1008- p. as_non_null ( ) . cast :: < u8 > ( ) . as_ptr ( ) ,
1009- bytes,
1010- ) ;
1011- // SAFETY: `ptr` has the same address as `p`, which is
1012- // non-null.
1013- core:: ptr:: NonNull :: new_unchecked ( ptr)
1014- } )
1015- } ;
1016-
1017- let ptr = ptr. bikeshed_recall_aligned ( ) ;
1018- ptr. recall_validity :: < _ , ( _ , ( _ , _ ) ) > ( )
950+ // SAFETY: `PtrInner::as_bytes` returns a pointer which addresses
951+ // the same byte range as its argument, and which has the same
952+ // provenance.
953+ let ptr = unsafe { self . cast_unsized ( PtrInner :: as_bytes) } ;
954+ ptr. bikeshed_recall_aligned ( ) . recall_validity :: < Valid , ( _ , ( _ , _ ) ) > ( )
1019955 }
1020956 }
1021957
@@ -1234,7 +1170,7 @@ mod _casts {
12341170 // inner type `T`. A consequence of this guarantee is that it is
12351171 // possible to convert between `T` and `UnsafeCell<T>`.
12361172 #[ allow( clippy:: as_conversions) ]
1237- let ptr = unsafe { self . transmute_unchecked ( |ptr| cast ! ( ptr) . as_non_null ( ) ) } ;
1173+ let ptr = unsafe { self . transmute_unchecked ( |ptr| cast ! ( ptr) ) } ;
12381174
12391175 // SAFETY: `UnsafeCell<T>` has the same alignment as `T` [1],
12401176 // and so if `self` is guaranteed to be aligned, then so is the
0 commit comments