@@ -7,7 +7,7 @@ use crate::pin::PinCoerceUnsized;
77use crate :: ptr:: Unique ;
88use crate :: slice:: { self , SliceIndex } ;
99use crate :: ub_checks:: assert_unsafe_precondition;
10- use crate :: { fmt, hash, intrinsics, ptr} ;
10+ use crate :: { fmt, hash, intrinsics, mem , ptr} ;
1111
1212/// `*mut T` but non-zero and [covariant].
1313///
@@ -69,6 +69,8 @@ use crate::{fmt, hash, intrinsics, ptr};
6969#[ rustc_nonnull_optimization_guaranteed]
7070#[ rustc_diagnostic_item = "NonNull" ]
7171pub struct NonNull < T : ?Sized > {
72+ // Remember to use `.as_ptr()` instead of `.pointer`, as field projecting to
73+ // this is banned by <https://github.com/rust-lang/compiler-team/issues/807>.
7274 pointer : * const T ,
7375}
7476
@@ -282,7 +284,7 @@ impl<T: ?Sized> NonNull<T> {
282284 pub fn addr ( self ) -> NonZero < usize > {
283285 // SAFETY: The pointer is guaranteed by the type to be non-null,
284286 // meaning that the address will be non-zero.
285- unsafe { NonZero :: new_unchecked ( self . pointer . addr ( ) ) }
287+ unsafe { NonZero :: new_unchecked ( self . as_ptr ( ) . addr ( ) ) }
286288 }
287289
288290 /// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of
@@ -296,7 +298,7 @@ impl<T: ?Sized> NonNull<T> {
296298 #[ stable( feature = "strict_provenance" , since = "1.84.0" ) ]
297299 pub fn with_addr ( self , addr : NonZero < usize > ) -> Self {
298300 // SAFETY: The result of `ptr::from::with_addr` is non-null because `addr` is guaranteed to be non-zero.
299- unsafe { NonNull :: new_unchecked ( self . pointer . with_addr ( addr. get ( ) ) as * mut _ ) }
301+ unsafe { NonNull :: new_unchecked ( self . as_ptr ( ) . with_addr ( addr. get ( ) ) as * mut _ ) }
300302 }
301303
302304 /// Creates a new pointer by mapping `self`'s address to a new one, preserving the
@@ -335,7 +337,12 @@ impl<T: ?Sized> NonNull<T> {
335337 #[ must_use]
336338 #[ inline( always) ]
337339 pub const fn as_ptr ( self ) -> * mut T {
338- self . pointer as * mut T
340+ // This is a transmute for the same reasons as `NonZero::get`.
341+
342+ // SAFETY: `NonNull` is `transparent` over a `*const T`, and `*const T`
343+ // and `*mut T` have the same layout, so transitively we can transmute
344+ // our `NonNull` to a `*mut T` directly.
345+ unsafe { mem:: transmute :: < Self , * mut T > ( self ) }
339346 }
340347
341348 /// Returns a shared reference to the value. If the value may be uninitialized, [`as_uninit_ref`]
@@ -484,7 +491,7 @@ impl<T: ?Sized> NonNull<T> {
484491 // Additionally safety contract of `offset` guarantees that the resulting pointer is
485492 // pointing to an allocation, there can't be an allocation at null, thus it's safe to
486493 // construct `NonNull`.
487- unsafe { NonNull { pointer : intrinsics:: offset ( self . pointer , count) } }
494+ unsafe { NonNull { pointer : intrinsics:: offset ( self . as_ptr ( ) , count) } }
488495 }
489496
490497 /// Calculates the offset from a pointer in bytes.
@@ -508,7 +515,7 @@ impl<T: ?Sized> NonNull<T> {
508515 // Additionally safety contract of `offset` guarantees that the resulting pointer is
509516 // pointing to an allocation, there can't be an allocation at null, thus it's safe to
510517 // construct `NonNull`.
511- unsafe { NonNull { pointer : self . pointer . byte_offset ( count) } }
518+ unsafe { NonNull { pointer : self . as_ptr ( ) . byte_offset ( count) } }
512519 }
513520
514521 /// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
@@ -560,7 +567,7 @@ impl<T: ?Sized> NonNull<T> {
560567 // Additionally safety contract of `offset` guarantees that the resulting pointer is
561568 // pointing to an allocation, there can't be an allocation at null, thus it's safe to
562569 // construct `NonNull`.
563- unsafe { NonNull { pointer : intrinsics:: offset ( self . pointer , count) } }
570+ unsafe { NonNull { pointer : intrinsics:: offset ( self . as_ptr ( ) , count) } }
564571 }
565572
566573 /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
@@ -584,7 +591,7 @@ impl<T: ?Sized> NonNull<T> {
584591 // Additionally safety contract of `add` guarantees that the resulting pointer is pointing
585592 // to an allocation, there can't be an allocation at null, thus it's safe to construct
586593 // `NonNull`.
587- unsafe { NonNull { pointer : self . pointer . byte_add ( count) } }
594+ unsafe { NonNull { pointer : self . as_ptr ( ) . byte_add ( count) } }
588595 }
589596
590597 /// Subtracts an offset from a pointer (convenience for
@@ -666,7 +673,7 @@ impl<T: ?Sized> NonNull<T> {
666673 // Additionally safety contract of `sub` guarantees that the resulting pointer is pointing
667674 // to an allocation, there can't be an allocation at null, thus it's safe to construct
668675 // `NonNull`.
669- unsafe { NonNull { pointer : self . pointer . byte_sub ( count) } }
676+ unsafe { NonNull { pointer : self . as_ptr ( ) . byte_sub ( count) } }
670677 }
671678
672679 /// Calculates the distance between two pointers within the same allocation. The returned value is in
@@ -763,7 +770,7 @@ impl<T: ?Sized> NonNull<T> {
763770 T : Sized ,
764771 {
765772 // SAFETY: the caller must uphold the safety contract for `offset_from`.
766- unsafe { self . pointer . offset_from ( origin. pointer ) }
773+ unsafe { self . as_ptr ( ) . offset_from ( origin. as_ptr ( ) ) }
767774 }
768775
769776 /// Calculates the distance between two pointers within the same allocation. The returned value is in
@@ -781,7 +788,7 @@ impl<T: ?Sized> NonNull<T> {
781788 #[ rustc_const_stable( feature = "non_null_convenience" , since = "1.80.0" ) ]
782789 pub const unsafe fn byte_offset_from < U : ?Sized > ( self , origin : NonNull < U > ) -> isize {
783790 // SAFETY: the caller must uphold the safety contract for `byte_offset_from`.
784- unsafe { self . pointer . byte_offset_from ( origin. pointer ) }
791+ unsafe { self . as_ptr ( ) . byte_offset_from ( origin. as_ptr ( ) ) }
785792 }
786793
787794 // N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null
@@ -856,7 +863,7 @@ impl<T: ?Sized> NonNull<T> {
856863 T : Sized ,
857864 {
858865 // SAFETY: the caller must uphold the safety contract for `sub_ptr`.
859- unsafe { self . pointer . sub_ptr ( subtracted. pointer ) }
866+ unsafe { self . as_ptr ( ) . sub_ptr ( subtracted. as_ptr ( ) ) }
860867 }
861868
862869 /// Calculates the distance between two pointers within the same allocation, *where it's known that
@@ -875,7 +882,7 @@ impl<T: ?Sized> NonNull<T> {
875882 #[ rustc_const_unstable( feature = "const_ptr_sub_ptr" , issue = "95892" ) ]
876883 pub const unsafe fn byte_sub_ptr < U : ?Sized > ( self , origin : NonNull < U > ) -> usize {
877884 // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
878- unsafe { self . pointer . byte_sub_ptr ( origin. pointer ) }
885+ unsafe { self . as_ptr ( ) . byte_sub_ptr ( origin. as_ptr ( ) ) }
879886 }
880887
881888 /// Reads the value from `self` without moving it. This leaves the
@@ -893,7 +900,7 @@ impl<T: ?Sized> NonNull<T> {
893900 T : Sized ,
894901 {
895902 // SAFETY: the caller must uphold the safety contract for `read`.
896- unsafe { ptr:: read ( self . pointer ) }
903+ unsafe { ptr:: read ( self . as_ptr ( ) ) }
897904 }
898905
899906 /// Performs a volatile read of the value from `self` without moving it. This
@@ -914,7 +921,7 @@ impl<T: ?Sized> NonNull<T> {
914921 T : Sized ,
915922 {
916923 // SAFETY: the caller must uphold the safety contract for `read_volatile`.
917- unsafe { ptr:: read_volatile ( self . pointer ) }
924+ unsafe { ptr:: read_volatile ( self . as_ptr ( ) ) }
918925 }
919926
920927 /// Reads the value from `self` without moving it. This leaves the
@@ -934,7 +941,7 @@ impl<T: ?Sized> NonNull<T> {
934941 T : Sized ,
935942 {
936943 // SAFETY: the caller must uphold the safety contract for `read_unaligned`.
937- unsafe { ptr:: read_unaligned ( self . pointer ) }
944+ unsafe { ptr:: read_unaligned ( self . as_ptr ( ) ) }
938945 }
939946
940947 /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@@ -954,7 +961,7 @@ impl<T: ?Sized> NonNull<T> {
954961 T : Sized ,
955962 {
956963 // SAFETY: the caller must uphold the safety contract for `copy`.
957- unsafe { ptr:: copy ( self . pointer , dest. as_ptr ( ) , count) }
964+ unsafe { ptr:: copy ( self . as_ptr ( ) , dest. as_ptr ( ) , count) }
958965 }
959966
960967 /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@@ -974,7 +981,7 @@ impl<T: ?Sized> NonNull<T> {
974981 T : Sized ,
975982 {
976983 // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
977- unsafe { ptr:: copy_nonoverlapping ( self . pointer , dest. as_ptr ( ) , count) }
984+ unsafe { ptr:: copy_nonoverlapping ( self . as_ptr ( ) , dest. as_ptr ( ) , count) }
978985 }
979986
980987 /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@@ -994,7 +1001,7 @@ impl<T: ?Sized> NonNull<T> {
9941001 T : Sized ,
9951002 {
9961003 // SAFETY: the caller must uphold the safety contract for `copy`.
997- unsafe { ptr:: copy ( src. pointer , self . as_ptr ( ) , count) }
1004+ unsafe { ptr:: copy ( src. as_ptr ( ) , self . as_ptr ( ) , count) }
9981005 }
9991006
10001007 /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@@ -1014,7 +1021,7 @@ impl<T: ?Sized> NonNull<T> {
10141021 T : Sized ,
10151022 {
10161023 // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
1017- unsafe { ptr:: copy_nonoverlapping ( src. pointer , self . as_ptr ( ) , count) }
1024+ unsafe { ptr:: copy_nonoverlapping ( src. as_ptr ( ) , self . as_ptr ( ) , count) }
10181025 }
10191026
10201027 /// Executes the destructor (if any) of the pointed-to value.
@@ -1201,7 +1208,7 @@ impl<T: ?Sized> NonNull<T> {
12011208
12021209 {
12031210 // SAFETY: `align` has been checked to be a power of 2 above.
1204- unsafe { ptr:: align_offset ( self . pointer , align) }
1211+ unsafe { ptr:: align_offset ( self . as_ptr ( ) , align) }
12051212 }
12061213 }
12071214
@@ -1229,7 +1236,7 @@ impl<T: ?Sized> NonNull<T> {
12291236 where
12301237 T : Sized ,
12311238 {
1232- self . pointer . is_aligned ( )
1239+ self . as_ptr ( ) . is_aligned ( )
12331240 }
12341241
12351242 /// Returns whether the pointer is aligned to `align`.
@@ -1266,7 +1273,7 @@ impl<T: ?Sized> NonNull<T> {
12661273 #[ must_use]
12671274 #[ unstable( feature = "pointer_is_aligned_to" , issue = "96284" ) ]
12681275 pub fn is_aligned_to ( self , align : usize ) -> bool {
1269- self . pointer . is_aligned_to ( align)
1276+ self . as_ptr ( ) . is_aligned_to ( align)
12701277 }
12711278}
12721279
0 commit comments