@@ -736,3 +736,99 @@ pub fn discriminant<T>(v: &T) -> Discriminant<T> {
736
736
}
737
737
}
738
738
739
+
740
+ /// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
741
+ ///
742
+ /// This wrapper is 0-cost.
743
+ ///
744
+ /// # Examples
745
+ ///
746
+ /// This wrapper helps with explicitly documenting the drop order dependencies between fields of
747
+ /// the type:
748
+ ///
749
+ /// ```rust
750
+ /// # #![feature(manually_drop)]
751
+ /// use std::mem::ManuallyDrop;
752
+ /// struct Peach;
753
+ /// struct Banana;
754
+ /// struct Melon;
755
+ /// struct FruitBox {
756
+ /// // Immediately clear there’s something non-trivial going on with these fields.
757
+ /// peach: ManuallyDrop<Peach>,
758
+ /// melon: Melon, // Field that’s independent of the other two.
759
+ /// banana: ManuallyDrop<Banana>,
760
+ /// }
761
+ ///
762
+ /// impl Drop for FruitBox {
763
+ /// fn drop(&mut self) {
764
+ /// unsafe {
765
+ /// // Explicit ordering in which field destructors are run specified in the intuitive
766
+ /// // location – the destructor of the structure containing the fields.
767
+ /// // Moreover, one can now reorder fields within the struct however much they want.
768
+ /// ManuallyDrop::drop(&mut self.peach);
769
+ /// ManuallyDrop::drop(&mut self.banana);
770
+ /// }
771
+ /// // After destructor for `FruitBox` runs (this function), the destructor for Melon gets
772
+ /// // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`.
773
+ /// }
774
+ /// }
775
+ /// ```
776
+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
777
+ #[ allow( unions_with_drop_fields) ]
778
+ pub union ManuallyDrop < T > { value : T }
779
+
780
+ impl < T > ManuallyDrop < T > {
781
+ /// Wrap a value to be manually dropped.
782
+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
783
+ pub fn new ( value : T ) -> ManuallyDrop < T > {
784
+ ManuallyDrop { value : value }
785
+ }
786
+
787
+ /// Extract the value from the ManuallyDrop container.
788
+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
789
+ pub fn into_inner ( self ) -> T {
790
+ unsafe {
791
+ self . value
792
+ }
793
+ }
794
+
795
+ /// Manually drops the contained value.
796
+ ///
797
+ /// # Unsafety
798
+ ///
799
+ /// This function runs the destructor of the contained value and thus the wrapped value
800
+ /// now represents uninitialized data. It is up to the user of this method to ensure the
801
+ /// uninitialized data is not actually used.
802
+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
803
+ pub unsafe fn drop ( slot : & mut ManuallyDrop < T > ) {
804
+ ptr:: drop_in_place ( & mut slot. value )
805
+ }
806
+ }
807
+
808
+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
809
+ impl < T > :: ops:: Deref for ManuallyDrop < T > {
810
+ type Target = T ;
811
+ fn deref ( & self ) -> & Self :: Target {
812
+ unsafe {
813
+ & self . value
814
+ }
815
+ }
816
+ }
817
+
818
+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
819
+ impl < T > :: ops:: DerefMut for ManuallyDrop < T > {
820
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
821
+ unsafe {
822
+ & mut self . value
823
+ }
824
+ }
825
+ }
826
+
827
+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
828
+ impl < T : :: fmt:: Debug > :: fmt:: Debug for ManuallyDrop < T > {
829
+ fn fmt ( & self , fmt : & mut :: fmt:: Formatter ) -> :: fmt:: Result {
830
+ unsafe {
831
+ fmt. debug_tuple ( "ManuallyDrop" ) . field ( & self . value ) . finish ( )
832
+ }
833
+ }
834
+ }
0 commit comments