@@ -2,11 +2,14 @@ use crate::cmp::Ordering;
22use crate :: convert:: From ;
33use crate :: fmt;
44use crate :: hash;
5+ use crate :: intrinsics;
56use crate :: intrinsics:: assert_unsafe_precondition;
67use crate :: marker:: Unsize ;
8+ use crate :: mem:: SizedTypeProperties ;
79use crate :: mem:: { self , MaybeUninit } ;
810use crate :: num:: NonZeroUsize ;
911use crate :: ops:: { CoerceUnsized , DispatchFromDyn } ;
12+ use crate :: ptr;
1013use crate :: ptr:: Unique ;
1114use crate :: slice:: { self , SliceIndex } ;
1215
@@ -471,30 +474,236 @@ impl<T: ?Sized> NonNull<T> {
471474 unsafe { NonNull :: new_unchecked ( self . as_ptr ( ) as * mut U ) }
472475 }
473476
474- /// See [`pointer::add`] for semantics and safety requirements.
477+ /// Reads the value from `self` without moving it. This leaves the
478+ /// memory in `self` unchanged.
479+ ///
480+ /// See [`ptr::read`] for safety concerns and examples.
481+ ///
482+ /// [`ptr::read`]: crate::ptr::read()
483+ #[ unstable( feature = "non_null_convenience" , issue = "117691" ) ]
484+ #[ rustc_const_unstable( feature = "non_null_convenience" , issue = "117691" ) ]
475485 #[ inline]
476- pub ( crate ) const unsafe fn add ( self , delta : usize ) -> Self
486+ #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
487+ pub const unsafe fn read ( self ) -> T
477488 where
478489 T : Sized ,
479490 {
480- // SAFETY: We require that the delta stays in-bounds of the object, and
481- // thus it cannot become null, as that would require wrapping the
482- // address space, which no legal objects are allowed to do.
483- // And the caller promised the `delta` is sound to add.
484- unsafe { NonNull { pointer : self . pointer . add ( delta) } }
491+ // SAFETY: the caller must uphold the safety contract for `read`.
492+ unsafe { ptr:: read ( self . pointer ) }
485493 }
486494
487- /// See [`pointer::sub`] for semantics and safety requirements.
495+ /// Performs a volatile read of the value from `self` without moving it. This
496+ /// leaves the memory in `self` unchanged.
497+ ///
498+ /// Volatile operations are intended to act on I/O memory, and are guaranteed
499+ /// to not be elided or reordered by the compiler across other volatile
500+ /// operations.
501+ ///
502+ /// See [`ptr::read_volatile`] for safety concerns and examples.
503+ ///
504+ /// [`ptr::read_volatile`]: crate::ptr::read_volatile()
505+ #[ unstable( feature = "non_null_convenience" , issue = "117691" ) ]
488506 #[ inline]
489- pub ( crate ) const unsafe fn sub ( self , delta : usize ) -> Self
507+ #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
508+ pub unsafe fn read_volatile ( self ) -> T
509+ where
510+ T : Sized ,
511+ {
512+ // SAFETY: the caller must uphold the safety contract for `read_volatile`.
513+ unsafe { ptr:: read_volatile ( self . pointer ) }
514+ }
515+
516+ /// Reads the value from `self` without moving it. This leaves the
517+ /// memory in `self` unchanged.
518+ ///
519+ /// Unlike `read`, the pointer may be unaligned.
520+ ///
521+ /// See [`ptr::read_unaligned`] for safety concerns and examples.
522+ ///
523+ /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
524+ #[ unstable( feature = "non_null_convenience" , issue = "117691" ) ]
525+ #[ rustc_const_unstable( feature = "non_null_convenience" , issue = "117691" ) ]
526+ #[ inline]
527+ #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
528+ pub const unsafe fn read_unaligned ( self ) -> T
529+ where
530+ T : Sized ,
531+ {
532+ // SAFETY: the caller must uphold the safety contract for `read_unaligned`.
533+ unsafe { ptr:: read_unaligned ( self . pointer ) }
534+ }
535+
536+ /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
537+ /// and destination may overlap.
538+ ///
539+ /// NOTE: this has the *same* argument order as [`ptr::copy`].
540+ ///
541+ /// See [`ptr::copy`] for safety concerns and examples.
542+ ///
543+ /// [`ptr::copy`]: crate::ptr::copy()
544+ #[ unstable( feature = "non_null_convenience" , issue = "117691" ) ]
545+ #[ rustc_const_unstable( feature = "non_null_convenience" , issue = "117691" ) ]
546+ #[ inline( always) ]
547+ #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
548+ pub const unsafe fn copy_to ( self , dest : NonNull < T > , count : usize )
549+ where
550+ T : Sized ,
551+ {
552+ // SAFETY: the caller must uphold the safety contract for `copy`.
553+ unsafe { ptr:: copy ( self . pointer , dest. as_ptr ( ) , count) }
554+ }
555+
556+ /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
557+ /// and destination may *not* overlap.
558+ ///
559+ /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`].
560+ ///
561+ /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
562+ ///
563+ /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
564+ #[ unstable( feature = "non_null_convenience" , issue = "117691" ) ]
565+ #[ rustc_const_unstable( feature = "non_null_convenience" , issue = "117691" ) ]
566+ #[ inline( always) ]
567+ #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
568+ pub const unsafe fn copy_to_nonoverlapping ( self , dest : NonNull < T > , count : usize )
569+ where
570+ T : Sized ,
571+ {
572+ // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
573+ unsafe { ptr:: copy_nonoverlapping ( self . pointer , dest. as_ptr ( ) , count) }
574+ }
575+
576+ /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
577+ /// and destination may overlap.
578+ ///
579+ /// NOTE: this has the *opposite* argument order of [`ptr::copy`].
580+ ///
581+ /// See [`ptr::copy`] for safety concerns and examples.
582+ ///
583+ /// [`ptr::copy`]: crate::ptr::copy()
584+ #[ unstable( feature = "non_null_convenience" , issue = "117691" ) ]
585+ #[ rustc_const_unstable( feature = "non_null_convenience" , issue = "117691" ) ]
586+ #[ inline( always) ]
587+ #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
588+ pub const unsafe fn copy_from ( self , src : NonNull < T > , count : usize )
589+ where
590+ T : Sized ,
591+ {
592+ // SAFETY: the caller must uphold the safety contract for `copy`.
593+ unsafe { ptr:: copy ( src. pointer , self . as_ptr ( ) , count) }
594+ }
595+
596+ /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
597+ /// and destination may *not* overlap.
598+ ///
599+ /// NOTE: this has the *opposite* argument order of [`ptr::copy_nonoverlapping`].
600+ ///
601+ /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
602+ ///
603+ /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
604+ #[ unstable( feature = "non_null_convenience" , issue = "117691" ) ]
605+ #[ rustc_const_unstable( feature = "non_null_convenience" , issue = "117691" ) ]
606+ #[ inline( always) ]
607+ #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
608+ pub const unsafe fn copy_from_nonoverlapping ( self , src : NonNull < T > , count : usize )
609+ where
610+ T : Sized ,
611+ {
612+ // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
613+ unsafe { ptr:: copy_nonoverlapping ( src. pointer , self . as_ptr ( ) , count) }
614+ }
615+
616+ /// Executes the destructor (if any) of the pointed-to value.
617+ ///
618+ /// See [`ptr::drop_in_place`] for safety concerns and examples.
619+ ///
620+ /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place()
621+ #[ unstable( feature = "non_null_convenience" , issue = "117691" ) ]
622+ #[ inline( always) ]
623+ pub unsafe fn drop_in_place ( self ) {
624+ // SAFETY: the caller must uphold the safety contract for `drop_in_place`.
625+ unsafe { ptr:: drop_in_place ( self . as_ptr ( ) ) }
626+ }
627+
628+ /// Overwrites a memory location with the given value without reading or
629+ /// dropping the old value.
630+ ///
631+ /// See [`ptr::write`] for safety concerns and examples.
632+ ///
633+ /// [`ptr::write`]: crate::ptr::write()
634+ #[ unstable( feature = "non_null_convenience" , issue = "117691" ) ]
635+ #[ rustc_const_unstable( feature = "non_null_convenience" , issue = "117691" ) ]
636+ //#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
637+ #[ inline( always) ]
638+ #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
639+ pub const unsafe fn write ( self , val : T )
640+ where
641+ T : Sized ,
642+ {
643+ // SAFETY: the caller must uphold the safety contract for `write`.
644+ unsafe { ptr:: write ( self . as_ptr ( ) , val) }
645+ }
646+
647+ /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
648+ /// bytes of memory starting at `self` to `val`.
649+ ///
650+ /// See [`ptr::write_bytes`] for safety concerns and examples.
651+ ///
652+ /// [`ptr::write_bytes`]: crate::ptr::write_bytes()
653+ #[ doc( alias = "memset" ) ]
654+ #[ unstable( feature = "non_null_convenience" , issue = "117691" ) ]
655+ #[ rustc_const_unstable( feature = "non_null_convenience" , issue = "117691" ) ]
656+ //#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
657+ #[ inline( always) ]
658+ #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
659+ pub const unsafe fn write_bytes ( self , val : u8 , count : usize )
660+ where
661+ T : Sized ,
662+ {
663+ // SAFETY: the caller must uphold the safety contract for `write_bytes`.
664+ unsafe { ptr:: write_bytes ( self . as_ptr ( ) , val, count) }
665+ }
666+
667+ /// Performs a volatile write of a memory location with the given value without
668+ /// reading or dropping the old value.
669+ ///
670+ /// Volatile operations are intended to act on I/O memory, and are guaranteed
671+ /// to not be elided or reordered by the compiler across other volatile
672+ /// operations.
673+ ///
674+ /// See [`ptr::write_volatile`] for safety concerns and examples.
675+ ///
676+ /// [`ptr::write_volatile`]: crate::ptr::write_volatile()
677+ #[ unstable( feature = "non_null_convenience" , issue = "117691" ) ]
678+ #[ inline( always) ]
679+ #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
680+ pub unsafe fn write_volatile ( self , val : T )
681+ where
682+ T : Sized ,
683+ {
684+ // SAFETY: the caller must uphold the safety contract for `write_volatile`.
685+ unsafe { ptr:: write_volatile ( self . as_ptr ( ) , val) }
686+ }
687+
688+ /// Overwrites a memory location with the given value without reading or
689+ /// dropping the old value.
690+ ///
691+ /// Unlike `write`, the pointer may be unaligned.
692+ ///
693+ /// See [`ptr::write_unaligned`] for safety concerns and examples.
694+ ///
695+ /// [`ptr::write_unaligned`]: crate::ptr::write_unaligned()
696+ #[ unstable( feature = "non_null_convenience" , issue = "117691" ) ]
697+ #[ rustc_const_unstable( feature = "non_null_convenience" , issue = "117691" ) ]
698+ //#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
699+ #[ inline( always) ]
700+ #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
701+ pub const unsafe fn write_unaligned ( self , val : T )
490702 where
491703 T : Sized ,
492704 {
493- // SAFETY: We require that the delta stays in-bounds of the object, and
494- // thus it cannot become null, as no legal objects can be allocated
495- // in such as way that the null address is part of them.
496- // And the caller promised the `delta` is sound to subtract.
497- unsafe { NonNull { pointer : self . pointer . sub ( delta) } }
705+ // SAFETY: the caller must uphold the safety contract for `write_unaligned`.
706+ unsafe { ptr:: write_unaligned ( self . as_ptr ( ) , val) }
498707 }
499708
500709 /// See [`pointer::sub_ptr`] for semantics and safety requirements.
0 commit comments