@@ -34,8 +34,12 @@ pub struct DropGuard<T, F>
3434where
3535 F : FnOnce ( T ) ,
3636{
37- inner : ManuallyDrop < T > ,
38- f : ManuallyDrop < F > ,
37+ inner : ManuallyDrop < DropGuardInner < T , F > > ,
38+ }
39+
40+ struct DropGuardInner < T , F > {
41+ value : T ,
42+ f : F ,
3943}
4044
4145impl < T , F > DropGuard < T , F >
5761 /// ```
5862 #[ unstable( feature = "drop_guard" , issue = "144426" ) ]
5963 #[ must_use]
60- pub const fn new ( inner : T , f : F ) -> Self {
61- Self { inner : ManuallyDrop :: new ( inner ) , f : ManuallyDrop :: new ( f ) }
64+ pub const fn new ( value : T , f : F ) -> Self {
65+ DropGuard { inner : ManuallyDrop :: new ( DropGuardInner { value , f } ) }
6266 }
6367
6468 /// Consumes the `DropGuard`, returning the wrapped value.
@@ -86,21 +90,12 @@ where
8690 #[ unstable( feature = "drop_guard" , issue = "144426" ) ]
8791 #[ inline]
8892 pub fn into_inner ( guard : Self ) -> T {
89- // First we ensure that dropping the guard will not trigger
90- // its destructor
9193 let mut guard = ManuallyDrop :: new ( guard) ;
92-
93- // Next we manually read the stored value from the guard.
94- //
95- // SAFETY: this is safe because we've taken ownership of the guard.
96- let value = unsafe { ManuallyDrop :: take ( & mut guard. inner ) } ;
97-
98- // Finally we drop the stored closure. We do this *after* having read
99- // the value, so that even if the closure's `drop` function panics,
100- // unwinding still tries to drop the value.
101- //
102- // SAFETY: this is safe because we've taken ownership of the guard.
103- unsafe { ManuallyDrop :: drop ( & mut guard. f ) } ;
94+ // SAFETY: This ManuallyDrop is owned by another ManuallyDrop which is
95+ // dropped at the end of this function.
96+ let DropGuardInner { value, f } = unsafe { ManuallyDrop :: take ( & mut guard. inner ) } ;
97+ // this ensures that, if the drop panics, the value will still be dropped
98+ drop ( f) ;
10499 value
105100 }
106101}
@@ -113,7 +108,7 @@ where
113108 type Target = T ;
114109
115110 fn deref ( & self ) -> & T {
116- & * self . inner
111+ & self . inner . value
117112 }
118113}
119114
@@ -123,7 +118,7 @@ where
123118 F : FnOnce ( T ) ,
124119{
125120 fn deref_mut ( & mut self ) -> & mut T {
126- & mut * self . inner
121+ & mut self . inner . value
127122 }
128123}
129124
@@ -134,12 +129,8 @@ where
134129{
135130 fn drop ( & mut self ) {
136131 // SAFETY: `DropGuard` is in the process of being dropped.
137- let inner = unsafe { ManuallyDrop :: take ( & mut self . inner ) } ;
138-
139- // SAFETY: `DropGuard` is in the process of being dropped.
140- let f = unsafe { ManuallyDrop :: take ( & mut self . f ) } ;
141-
142- f ( inner) ;
132+ let DropGuardInner { value, f } = unsafe { ManuallyDrop :: take ( & mut self . inner ) } ;
133+ f ( value) ;
143134 }
144135}
145136
0 commit comments