@@ -2,11 +2,14 @@ use crate::cmp::Ordering;
2
2
use crate :: convert:: From ;
3
3
use crate :: fmt;
4
4
use crate :: hash;
5
+ use crate :: intrinsics;
5
6
use crate :: intrinsics:: assert_unsafe_precondition;
6
7
use crate :: marker:: Unsize ;
8
+ use crate :: mem:: SizedTypeProperties ;
7
9
use crate :: mem:: { self , MaybeUninit } ;
8
10
use crate :: num:: NonZeroUsize ;
9
11
use crate :: ops:: { CoerceUnsized , DispatchFromDyn } ;
12
+ use crate :: ptr;
10
13
use crate :: ptr:: Unique ;
11
14
use crate :: slice:: { self , SliceIndex } ;
12
15
@@ -471,30 +474,236 @@ impl<T: ?Sized> NonNull<T> {
471
474
unsafe { NonNull :: new_unchecked ( self . as_ptr ( ) as * mut U ) }
472
475
}
473
476
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" ) ]
475
485
#[ 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
477
488
where
478
489
T : Sized ,
479
490
{
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 ) }
485
493
}
486
494
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" ) ]
488
506
#[ 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 )
490
702
where
491
703
T : Sized ,
492
704
{
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) }
498
707
}
499
708
500
709
/// See [`pointer::sub_ptr`] for semantics and safety requirements.
0 commit comments