@@ -171,7 +171,7 @@ pub use intrinsics::transmute;
171171#[ inline]
172172#[ stable( feature = "rust1" , since = "1.0.0" ) ]
173173pub fn forget < T > ( t : T ) {
174- unsafe { intrinsics :: forget ( t) }
174+ ManuallyDrop :: new ( t) ;
175175}
176176
177177/// Returns the size of a type in bytes.
@@ -736,3 +736,121 @@ pub fn discriminant<T>(v: &T) -> Discriminant<T> {
736736 }
737737}
738738
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+ ///
783+ /// # Examples
784+ ///
785+ /// ```rust
786+ /// # #![feature(manually_drop)]
787+ /// use std::mem::ManuallyDrop;
788+ /// ManuallyDrop::new(Box::new(()));
789+ /// ```
790+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
791+ #[ inline]
792+ pub fn new ( value : T ) -> ManuallyDrop < T > {
793+ ManuallyDrop { value : value }
794+ }
795+
796+ /// Extract the value from the ManuallyDrop container.
797+ ///
798+ /// # Examples
799+ ///
800+ /// ```rust
801+ /// # #![feature(manually_drop)]
802+ /// use std::mem::ManuallyDrop;
803+ /// let x = ManuallyDrop::new(Box::new(()));
804+ /// let _: Box<()> = ManuallyDrop::into_inner(x);
805+ /// ```
806+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
807+ #[ inline]
808+ pub fn into_inner ( slot : ManuallyDrop < T > ) -> T {
809+ unsafe {
810+ slot. value
811+ }
812+ }
813+
814+ /// Manually drops the contained value.
815+ ///
816+ /// # Unsafety
817+ ///
818+ /// This function runs the destructor of the contained value and thus the wrapped value
819+ /// now represents uninitialized data. It is up to the user of this method to ensure the
820+ /// uninitialized data is not actually used.
821+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
822+ #[ inline]
823+ pub unsafe fn drop ( slot : & mut ManuallyDrop < T > ) {
824+ ptr:: drop_in_place ( & mut slot. value )
825+ }
826+ }
827+
828+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
829+ impl < T > :: ops:: Deref for ManuallyDrop < T > {
830+ type Target = T ;
831+ #[ inline]
832+ fn deref ( & self ) -> & Self :: Target {
833+ unsafe {
834+ & self . value
835+ }
836+ }
837+ }
838+
839+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
840+ impl < T > :: ops:: DerefMut for ManuallyDrop < T > {
841+ #[ inline]
842+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
843+ unsafe {
844+ & mut self . value
845+ }
846+ }
847+ }
848+
849+ #[ unstable( feature = "manually_drop" , issue = "40673" ) ]
850+ impl < T : :: fmt:: Debug > :: fmt:: Debug for ManuallyDrop < T > {
851+ fn fmt ( & self , fmt : & mut :: fmt:: Formatter ) -> :: fmt:: Result {
852+ unsafe {
853+ fmt. debug_tuple ( "ManuallyDrop" ) . field ( & self . value ) . finish ( )
854+ }
855+ }
856+ }
0 commit comments