@@ -7,7 +7,7 @@ use crate::pin::PinCoerceUnsized;
7
7
use crate :: ptr:: Unique ;
8
8
use crate :: slice:: { self , SliceIndex } ;
9
9
use crate :: ub_checks:: assert_unsafe_precondition;
10
- use crate :: { fmt, hash, intrinsics, ptr} ;
10
+ use crate :: { fmt, hash, intrinsics, mem , ptr} ;
11
11
12
12
/// `*mut T` but non-zero and [covariant].
13
13
///
@@ -69,6 +69,8 @@ use crate::{fmt, hash, intrinsics, ptr};
69
69
#[ rustc_nonnull_optimization_guaranteed]
70
70
#[ rustc_diagnostic_item = "NonNull" ]
71
71
pub 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>.
72
74
pointer : * const T ,
73
75
}
74
76
@@ -282,7 +284,7 @@ impl<T: ?Sized> NonNull<T> {
282
284
pub fn addr ( self ) -> NonZero < usize > {
283
285
// SAFETY: The pointer is guaranteed by the type to be non-null,
284
286
// 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 ( ) ) }
286
288
}
287
289
288
290
/// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of
@@ -296,7 +298,7 @@ impl<T: ?Sized> NonNull<T> {
296
298
#[ stable( feature = "strict_provenance" , since = "CURRENT_RUSTC_VERSION" ) ]
297
299
pub fn with_addr ( self , addr : NonZero < usize > ) -> Self {
298
300
// 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 _ ) }
300
302
}
301
303
302
304
/// Creates a new pointer by mapping `self`'s address to a new one, preserving the
@@ -335,7 +337,12 @@ impl<T: ?Sized> NonNull<T> {
335
337
#[ must_use]
336
338
#[ inline( always) ]
337
339
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 ) }
339
346
}
340
347
341
348
/// 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> {
484
491
// Additionally safety contract of `offset` guarantees that the resulting pointer is
485
492
// pointing to an allocation, there can't be an allocation at null, thus it's safe to
486
493
// construct `NonNull`.
487
- unsafe { NonNull { pointer : intrinsics:: offset ( self . pointer , count) } }
494
+ unsafe { NonNull { pointer : intrinsics:: offset ( self . as_ptr ( ) , count) } }
488
495
}
489
496
490
497
/// Calculates the offset from a pointer in bytes.
@@ -508,7 +515,7 @@ impl<T: ?Sized> NonNull<T> {
508
515
// Additionally safety contract of `offset` guarantees that the resulting pointer is
509
516
// pointing to an allocation, there can't be an allocation at null, thus it's safe to
510
517
// construct `NonNull`.
511
- unsafe { NonNull { pointer : self . pointer . byte_offset ( count) } }
518
+ unsafe { NonNull { pointer : self . as_ptr ( ) . byte_offset ( count) } }
512
519
}
513
520
514
521
/// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
@@ -560,7 +567,7 @@ impl<T: ?Sized> NonNull<T> {
560
567
// Additionally safety contract of `offset` guarantees that the resulting pointer is
561
568
// pointing to an allocation, there can't be an allocation at null, thus it's safe to
562
569
// construct `NonNull`.
563
- unsafe { NonNull { pointer : intrinsics:: offset ( self . pointer , count) } }
570
+ unsafe { NonNull { pointer : intrinsics:: offset ( self . as_ptr ( ) , count) } }
564
571
}
565
572
566
573
/// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
@@ -584,7 +591,7 @@ impl<T: ?Sized> NonNull<T> {
584
591
// Additionally safety contract of `add` guarantees that the resulting pointer is pointing
585
592
// to an allocation, there can't be an allocation at null, thus it's safe to construct
586
593
// `NonNull`.
587
- unsafe { NonNull { pointer : self . pointer . byte_add ( count) } }
594
+ unsafe { NonNull { pointer : self . as_ptr ( ) . byte_add ( count) } }
588
595
}
589
596
590
597
/// Subtracts an offset from a pointer (convenience for
@@ -667,7 +674,7 @@ impl<T: ?Sized> NonNull<T> {
667
674
// Additionally safety contract of `sub` guarantees that the resulting pointer is pointing
668
675
// to an allocation, there can't be an allocation at null, thus it's safe to construct
669
676
// `NonNull`.
670
- unsafe { NonNull { pointer : self . pointer . byte_sub ( count) } }
677
+ unsafe { NonNull { pointer : self . as_ptr ( ) . byte_sub ( count) } }
671
678
}
672
679
673
680
/// Calculates the distance between two pointers within the same allocation. The returned value is in
@@ -764,7 +771,7 @@ impl<T: ?Sized> NonNull<T> {
764
771
T : Sized ,
765
772
{
766
773
// SAFETY: the caller must uphold the safety contract for `offset_from`.
767
- unsafe { self . pointer . offset_from ( origin. pointer ) }
774
+ unsafe { self . as_ptr ( ) . offset_from ( origin. as_ptr ( ) ) }
768
775
}
769
776
770
777
/// Calculates the distance between two pointers within the same allocation. The returned value is in
@@ -782,7 +789,7 @@ impl<T: ?Sized> NonNull<T> {
782
789
#[ rustc_const_stable( feature = "non_null_convenience" , since = "1.80.0" ) ]
783
790
pub const unsafe fn byte_offset_from < U : ?Sized > ( self , origin : NonNull < U > ) -> isize {
784
791
// SAFETY: the caller must uphold the safety contract for `byte_offset_from`.
785
- unsafe { self . pointer . byte_offset_from ( origin. pointer ) }
792
+ unsafe { self . as_ptr ( ) . byte_offset_from ( origin. as_ptr ( ) ) }
786
793
}
787
794
788
795
// N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null
@@ -857,7 +864,7 @@ impl<T: ?Sized> NonNull<T> {
857
864
T : Sized ,
858
865
{
859
866
// SAFETY: the caller must uphold the safety contract for `sub_ptr`.
860
- unsafe { self . pointer . sub_ptr ( subtracted. pointer ) }
867
+ unsafe { self . as_ptr ( ) . sub_ptr ( subtracted. as_ptr ( ) ) }
861
868
}
862
869
863
870
/// Calculates the distance between two pointers within the same allocation, *where it's known that
@@ -876,7 +883,7 @@ impl<T: ?Sized> NonNull<T> {
876
883
#[ rustc_const_unstable( feature = "const_ptr_sub_ptr" , issue = "95892" ) ]
877
884
pub const unsafe fn byte_sub_ptr < U : ?Sized > ( self , origin : NonNull < U > ) -> usize {
878
885
// SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
879
- unsafe { self . pointer . byte_sub_ptr ( origin. pointer ) }
886
+ unsafe { self . as_ptr ( ) . byte_sub_ptr ( origin. as_ptr ( ) ) }
880
887
}
881
888
882
889
/// Reads the value from `self` without moving it. This leaves the
@@ -894,7 +901,7 @@ impl<T: ?Sized> NonNull<T> {
894
901
T : Sized ,
895
902
{
896
903
// SAFETY: the caller must uphold the safety contract for `read`.
897
- unsafe { ptr:: read ( self . pointer ) }
904
+ unsafe { ptr:: read ( self . as_ptr ( ) ) }
898
905
}
899
906
900
907
/// Performs a volatile read of the value from `self` without moving it. This
@@ -915,7 +922,7 @@ impl<T: ?Sized> NonNull<T> {
915
922
T : Sized ,
916
923
{
917
924
// SAFETY: the caller must uphold the safety contract for `read_volatile`.
918
- unsafe { ptr:: read_volatile ( self . pointer ) }
925
+ unsafe { ptr:: read_volatile ( self . as_ptr ( ) ) }
919
926
}
920
927
921
928
/// Reads the value from `self` without moving it. This leaves the
@@ -935,7 +942,7 @@ impl<T: ?Sized> NonNull<T> {
935
942
T : Sized ,
936
943
{
937
944
// SAFETY: the caller must uphold the safety contract for `read_unaligned`.
938
- unsafe { ptr:: read_unaligned ( self . pointer ) }
945
+ unsafe { ptr:: read_unaligned ( self . as_ptr ( ) ) }
939
946
}
940
947
941
948
/// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@@ -955,7 +962,7 @@ impl<T: ?Sized> NonNull<T> {
955
962
T : Sized ,
956
963
{
957
964
// SAFETY: the caller must uphold the safety contract for `copy`.
958
- unsafe { ptr:: copy ( self . pointer , dest. as_ptr ( ) , count) }
965
+ unsafe { ptr:: copy ( self . as_ptr ( ) , dest. as_ptr ( ) , count) }
959
966
}
960
967
961
968
/// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@@ -975,7 +982,7 @@ impl<T: ?Sized> NonNull<T> {
975
982
T : Sized ,
976
983
{
977
984
// SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
978
- unsafe { ptr:: copy_nonoverlapping ( self . pointer , dest. as_ptr ( ) , count) }
985
+ unsafe { ptr:: copy_nonoverlapping ( self . as_ptr ( ) , dest. as_ptr ( ) , count) }
979
986
}
980
987
981
988
/// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@@ -995,7 +1002,7 @@ impl<T: ?Sized> NonNull<T> {
995
1002
T : Sized ,
996
1003
{
997
1004
// SAFETY: the caller must uphold the safety contract for `copy`.
998
- unsafe { ptr:: copy ( src. pointer , self . as_ptr ( ) , count) }
1005
+ unsafe { ptr:: copy ( src. as_ptr ( ) , self . as_ptr ( ) , count) }
999
1006
}
1000
1007
1001
1008
/// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@@ -1015,7 +1022,7 @@ impl<T: ?Sized> NonNull<T> {
1015
1022
T : Sized ,
1016
1023
{
1017
1024
// SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
1018
- unsafe { ptr:: copy_nonoverlapping ( src. pointer , self . as_ptr ( ) , count) }
1025
+ unsafe { ptr:: copy_nonoverlapping ( src. as_ptr ( ) , self . as_ptr ( ) , count) }
1019
1026
}
1020
1027
1021
1028
/// Executes the destructor (if any) of the pointed-to value.
@@ -1202,7 +1209,7 @@ impl<T: ?Sized> NonNull<T> {
1202
1209
1203
1210
{
1204
1211
// SAFETY: `align` has been checked to be a power of 2 above.
1205
- unsafe { ptr:: align_offset ( self . pointer , align) }
1212
+ unsafe { ptr:: align_offset ( self . as_ptr ( ) , align) }
1206
1213
}
1207
1214
}
1208
1215
@@ -1230,7 +1237,7 @@ impl<T: ?Sized> NonNull<T> {
1230
1237
where
1231
1238
T : Sized ,
1232
1239
{
1233
- self . pointer . is_aligned ( )
1240
+ self . as_ptr ( ) . is_aligned ( )
1234
1241
}
1235
1242
1236
1243
/// Returns whether the pointer is aligned to `align`.
@@ -1267,7 +1274,7 @@ impl<T: ?Sized> NonNull<T> {
1267
1274
#[ must_use]
1268
1275
#[ unstable( feature = "pointer_is_aligned_to" , issue = "96284" ) ]
1269
1276
pub fn is_aligned_to ( self , align : usize ) -> bool {
1270
- self . pointer . is_aligned_to ( align)
1277
+ self . as_ptr ( ) . is_aligned_to ( align)
1271
1278
}
1272
1279
}
1273
1280
0 commit comments