@@ -139,126 +139,34 @@ pub use intrinsics::transmute;
139
139
/// [ub]: ../../reference/behavior-considered-undefined.html
140
140
#[ inline]
141
141
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
142
- #[ cfg( not( stage0) ) ]
143
- pub fn forget < T : ?Sized > ( t : T ) {
144
- unsafe { intrinsics:: forget ( t) }
142
+ pub fn forget < T > ( t : T ) {
143
+ ManuallyDrop :: new ( t) ;
145
144
}
146
145
147
146
/// Takes ownership and "forgets" about the value **without running its destructor**.
148
147
///
149
- /// Any resources the value manages, such as heap memory or a file handle, will linger
150
- /// forever in an unreachable state. However, it does not guarantee that pointers
151
- /// to this memory will remain valid.
152
- ///
153
- /// * If you want to leak memory, see [`Box::leak`][leak].
154
- /// * If you want to obtain a raw pointer to the memory, see [`Box::into_raw`][into_raw].
155
- /// * If you want to dispose of a value properly, running its destructor, see
156
- /// [`mem::drop`][drop].
157
- ///
158
- /// # Safety
159
- ///
160
- /// `forget` is not marked as `unsafe`, because Rust's safety guarantees
161
- /// do not include a guarantee that destructors will always run. For example,
162
- /// a program can create a reference cycle using [`Rc`][rc], or call
163
- /// [`process::exit`][exit] to exit without running destructors. Thus, allowing
164
- /// `mem::forget` from safe code does not fundamentally change Rust's safety
165
- /// guarantees.
166
- ///
167
- /// That said, leaking resources such as memory or I/O objects is usually undesirable,
168
- /// so `forget` is only recommended for specialized use cases like those shown below.
169
- ///
170
- /// Because forgetting a value is allowed, any `unsafe` code you write must
171
- /// allow for this possibility. You cannot return a value and expect that the
172
- /// caller will necessarily run the value's destructor.
148
+ /// This function works exactly the same as [`forget`], except it also accepts unsized values. It
149
+ /// will never be stabilized and is only available because we haven't decided to relax the bounds
150
+ /// on [`forget`] just yet.
173
151
///
174
- /// [rc]: ../../std/rc/struct.Rc.html
175
- /// [exit]: ../../std/process/fn.exit.html
152
+ /// [`forget`]: fn.forget.html
176
153
///
177
154
/// # Examples
178
155
///
179
- /// Leak an I/O object, never closing the file:
180
- ///
181
- /// ```no_run
182
- /// use std::mem;
183
- /// use std::fs::File;
184
- ///
185
- /// let file = File::open("foo.txt").unwrap();
186
- /// mem::forget(file);
187
- /// ```
188
- ///
189
- /// The practical use cases for `forget` are rather specialized and mainly come
190
- /// up in unsafe or FFI code.
191
- ///
192
- /// ## Use case 1
193
- ///
194
- /// You have created an uninitialized value using [`mem::uninitialized`][uninit].
195
- /// You must either initialize or `forget` it on every computation path before
196
- /// Rust drops it automatically, like at the end of a scope or after a panic.
197
- /// Running the destructor on an uninitialized value would be [undefined behavior][ub].
198
- ///
199
- /// ```
200
- /// use std::mem;
201
- /// use std::ptr;
202
- ///
203
- /// # let some_condition = false;
204
- /// unsafe {
205
- /// let mut uninit_vec: Vec<u32> = mem::uninitialized();
206
- ///
207
- /// if some_condition {
208
- /// // Initialize the variable.
209
- /// ptr::write(&mut uninit_vec, Vec::new());
210
- /// } else {
211
- /// // Forget the uninitialized value so its destructor doesn't run.
212
- /// mem::forget(uninit_vec);
213
- /// }
214
- /// }
215
156
/// ```
157
+ /// #![feature(forget_unsized)]
216
158
///
217
- /// ## Use case 2
218
- ///
219
- /// You have duplicated the bytes making up a value, without doing a proper
220
- /// [`Clone`][clone]. You need the value's destructor to run only once,
221
- /// because a double `free` is undefined behavior.
222
- ///
223
- /// An example is a possible implementation of [`mem::swap`][swap]:
224
- ///
225
- /// ```
226
159
/// use std::mem;
227
- /// use std::ptr;
228
- ///
229
- /// # #[allow(dead_code)]
230
- /// fn swap<T>(x: &mut T, y: &mut T) {
231
- /// unsafe {
232
- /// // Give ourselves some scratch space to work with
233
- /// let mut t: T = mem::uninitialized();
234
160
///
235
- /// // Perform the swap, `&mut` pointers never alias
236
- /// ptr::copy_nonoverlapping(&*x, &mut t, 1);
237
- /// ptr::copy_nonoverlapping(&*y, x, 1);
238
- /// ptr::copy_nonoverlapping(&t, y, 1);
239
- ///
240
- /// // y and t now point to the same thing, but we need to completely
241
- /// // forget `t` because we do not want to run the destructor for `T`
242
- /// // on its value, which is still owned somewhere outside this function.
243
- /// mem::forget(t);
244
- /// }
245
- /// }
161
+ /// let f: Box<FnOnce()> = Box::new(|| ());
162
+ /// let f = *f;
163
+ /// mem::forget_unsized(f);
246
164
/// ```
247
- ///
248
- /// [drop]: fn.drop.html
249
- /// [uninit]: fn.uninitialized.html
250
- /// [clone]: ../clone/trait.Clone.html
251
- /// [swap]: fn.swap.html
252
- /// [FFI]: ../../book/first-edition/ffi.html
253
- /// [box]: ../../std/boxed/struct.Box.html
254
- /// [leak]: ../../std/boxed/struct.Box.html#method.leak
255
- /// [into_raw]: ../../std/boxed/struct.Box.html#method.into_raw
256
- /// [ub]: ../../reference/behavior-considered-undefined.html
257
165
#[ inline]
258
- #[ cfg( stage0) ]
259
- #[ stable ( feature = "rust1 " , since = "1.0. 0" ) ]
260
- pub fn forget < T > ( t : T ) {
261
- ManuallyDrop :: new ( t) ;
166
+ #[ cfg( not ( stage0) ) ]
167
+ #[ unstable ( feature = "forget_unsized " , issue = "0" ) ]
168
+ pub fn forget_unsized < T : ? Sized > ( t : T ) {
169
+ unsafe { intrinsics :: forget ( t) }
262
170
}
263
171
264
172
/// Returns the size of a type in bytes.
@@ -881,7 +789,7 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
881
789
/// [`Copy`]: ../../std/marker/trait.Copy.html
882
790
#[ inline]
883
791
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
884
- pub fn drop < T : ? Sized > ( _x : T ) { }
792
+ pub fn drop < T > ( _x : T ) { }
885
793
886
794
/// Interprets `src` as having type `&U`, and then reads `src` without moving
887
795
/// the contained value.
0 commit comments