Skip to content

Commit 892df1d

Browse files
committed
expose needs_drop under mem::
1 parent 1cda810 commit 892df1d

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

src/libcore/mem.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,58 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
302302
unsafe { intrinsics::min_align_of_val(val) }
303303
}
304304

305+
/// Returns whether dropping values of type `T` matters.
306+
///
307+
/// This is purely an optimization hint, and may be implemented conservatively.
308+
/// For instance, always returning `true` would be a valid implementation of
309+
/// this function.
310+
///
311+
/// Low level implementations of things like collections, which need to manually
312+
/// drop their data, should use this function to avoid unnecessarily
313+
/// trying to drop all their contents when they are destroyed. This might not
314+
/// make a difference in release builds (where a loop that has no side-effects
315+
/// is easily detected and eliminated), but is often a big win for debug builds.
316+
///
317+
/// Note that `ptr::drop_in_place` already performs this check, so if your workload
318+
/// can be reduced to some small number of drop_in_place calls, using this is
319+
/// unnecessary. In particular note that you can drop_in_place a slice, and that
320+
/// will do a single needs_drop check for all the values.
321+
///
322+
/// Types like Vec therefore just `drop_in_place(&mut self[..])` without using
323+
/// needs_drop explicitly. Types like HashMap, on the other hand, have to drop
324+
/// values one at a time and should use this API.
325+
///
326+
///
327+
/// # Examples
328+
///
329+
/// Here's an example of how a collection might make use of needs_drop:
330+
///
331+
/// ```ignore
332+
/// #![feature(needs_drop)]
333+
/// use std::{mem, ptr};
334+
///
335+
/// pub struct MyCollection<T> { /* ... */ }
336+
///
337+
/// impl<T> Drop for MyCollection<T> {
338+
/// fn drop(&mut self) {
339+
/// unsafe {
340+
/// // drop the data
341+
/// if mem::needs_drop::<T>() {
342+
/// for x in self.iter_mut() {
343+
/// ptr::drop_in_place(x);
344+
/// }
345+
/// }
346+
/// self.free_buffer();
347+
/// }
348+
/// }
349+
/// }
350+
/// ```
351+
#[inline]
352+
#[unstable(feature = "needs_drop", issue = "41890")]
353+
pub fn needs_drop<T>() -> bool {
354+
unsafe { intrinsics::needs_drop::<T>() }
355+
}
356+
305357
/// Creates a value whose bytes are all zero.
306358
///
307359
/// This has the same effect as allocating space with

0 commit comments

Comments
 (0)