@@ -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 = "1.84.0" ) ]
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
@@ -666,7 +673,7 @@ impl<T: ?Sized> NonNull<T> {
666
673
// Additionally safety contract of `sub` guarantees that the resulting pointer is pointing
667
674
// to an allocation, there can't be an allocation at null, thus it's safe to construct
668
675
// `NonNull`.
669
- unsafe { NonNull { pointer : self . pointer . byte_sub ( count) } }
676
+ unsafe { NonNull { pointer : self . as_ptr ( ) . byte_sub ( count) } }
670
677
}
671
678
672
679
/// Calculates the distance between two pointers within the same allocation. The returned value is in
@@ -763,7 +770,7 @@ impl<T: ?Sized> NonNull<T> {
763
770
T : Sized ,
764
771
{
765
772
// 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 ( ) ) }
767
774
}
768
775
769
776
/// Calculates the distance between two pointers within the same allocation. The returned value is in
@@ -781,7 +788,7 @@ impl<T: ?Sized> NonNull<T> {
781
788
#[ rustc_const_stable( feature = "non_null_convenience" , since = "1.80.0" ) ]
782
789
pub const unsafe fn byte_offset_from < U : ?Sized > ( self , origin : NonNull < U > ) -> isize {
783
790
// 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 ( ) ) }
785
792
}
786
793
787
794
// 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> {
856
863
T : Sized ,
857
864
{
858
865
// 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 ( ) ) }
860
867
}
861
868
862
869
/// Calculates the distance between two pointers within the same allocation, *where it's known that
@@ -875,7 +882,7 @@ impl<T: ?Sized> NonNull<T> {
875
882
#[ rustc_const_unstable( feature = "const_ptr_sub_ptr" , issue = "95892" ) ]
876
883
pub const unsafe fn byte_sub_ptr < U : ?Sized > ( self , origin : NonNull < U > ) -> usize {
877
884
// 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 ( ) ) }
879
886
}
880
887
881
888
/// Reads the value from `self` without moving it. This leaves the
@@ -893,7 +900,7 @@ impl<T: ?Sized> NonNull<T> {
893
900
T : Sized ,
894
901
{
895
902
// SAFETY: the caller must uphold the safety contract for `read`.
896
- unsafe { ptr:: read ( self . pointer ) }
903
+ unsafe { ptr:: read ( self . as_ptr ( ) ) }
897
904
}
898
905
899
906
/// Performs a volatile read of the value from `self` without moving it. This
@@ -914,7 +921,7 @@ impl<T: ?Sized> NonNull<T> {
914
921
T : Sized ,
915
922
{
916
923
// 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 ( ) ) }
918
925
}
919
926
920
927
/// Reads the value from `self` without moving it. This leaves the
@@ -934,7 +941,7 @@ impl<T: ?Sized> NonNull<T> {
934
941
T : Sized ,
935
942
{
936
943
// 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 ( ) ) }
938
945
}
939
946
940
947
/// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@@ -954,7 +961,7 @@ impl<T: ?Sized> NonNull<T> {
954
961
T : Sized ,
955
962
{
956
963
// 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) }
958
965
}
959
966
960
967
/// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@@ -974,7 +981,7 @@ impl<T: ?Sized> NonNull<T> {
974
981
T : Sized ,
975
982
{
976
983
// 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) }
978
985
}
979
986
980
987
/// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@@ -994,7 +1001,7 @@ impl<T: ?Sized> NonNull<T> {
994
1001
T : Sized ,
995
1002
{
996
1003
// 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) }
998
1005
}
999
1006
1000
1007
/// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@@ -1014,7 +1021,7 @@ impl<T: ?Sized> NonNull<T> {
1014
1021
T : Sized ,
1015
1022
{
1016
1023
// 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) }
1018
1025
}
1019
1026
1020
1027
/// Executes the destructor (if any) of the pointed-to value.
@@ -1201,7 +1208,7 @@ impl<T: ?Sized> NonNull<T> {
1201
1208
1202
1209
{
1203
1210
// 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) }
1205
1212
}
1206
1213
}
1207
1214
@@ -1229,7 +1236,7 @@ impl<T: ?Sized> NonNull<T> {
1229
1236
where
1230
1237
T : Sized ,
1231
1238
{
1232
- self . pointer . is_aligned ( )
1239
+ self . as_ptr ( ) . is_aligned ( )
1233
1240
}
1234
1241
1235
1242
/// Returns whether the pointer is aligned to `align`.
@@ -1266,7 +1273,7 @@ impl<T: ?Sized> NonNull<T> {
1266
1273
#[ must_use]
1267
1274
#[ unstable( feature = "pointer_is_aligned_to" , issue = "96284" ) ]
1268
1275
pub fn is_aligned_to ( self , align : usize ) -> bool {
1269
- self . pointer . is_aligned_to ( align)
1276
+ self . as_ptr ( ) . is_aligned_to ( align)
1270
1277
}
1271
1278
}
1272
1279
0 commit comments