diff options
| author | Stefan Lankes <slankes@eonerc.rwth-aachen.de> | 2019-11-13 00:24:37 +0100 |
|---|---|---|
| committer | Stefan Lankes <slankes@eonerc.rwth-aachen.de> | 2019-11-13 00:24:37 +0100 |
| commit | 88717319142e162ae2f48124d94f33d2c21bc2ce (patch) | |
| tree | e50a968f836c55007e9bc8f305d4f0f80aca042c /src/liballoc | |
| parent | 969b74144641bf1c8ae5aba0581f4b52a4c15bac (diff) | |
| parent | 4f03f4a989d1c8346c19dfb417a77c09b34408b8 (diff) | |
| download | rust-88717319142e162ae2f48124d94f33d2c21bc2ce.tar.gz rust-88717319142e162ae2f48124d94f33d2c21bc2ce.zip | |
Merge remote-tracking branch 'rust-lang/master' into hermit
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/collections/linked_list.rs | 2 | ||||
| -rw-r--r-- | src/liballoc/collections/vec_deque.rs | 32 | ||||
| -rw-r--r-- | src/liballoc/collections/vec_deque/tests.rs | 35 | ||||
| -rw-r--r-- | src/liballoc/lib.rs | 2 | ||||
| -rw-r--r-- | src/liballoc/rc.rs | 2 | ||||
| -rw-r--r-- | src/liballoc/string.rs | 2 | ||||
| -rw-r--r-- | src/liballoc/sync.rs | 2 |
7 files changed, 68 insertions, 9 deletions
diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 48f9865b870..a0c9263673d 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -90,7 +90,7 @@ impl<T> Clone for Iter<'_, T> { #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, T: 'a> { // We do *not* exclusively own the entire list here, references to node's `element` - // have been handed out by the iterator! So be careful when using this; the methods + // have been handed out by the iterator! So be careful when using this; the methods // called must be aware that there can be aliasing pointers to `element`. list: &'a mut LinkedList<T>, head: Option<NonNull<Node<T>>>, diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 8f3dfabd888..7795083e058 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -835,7 +835,8 @@ impl<T> VecDeque<T> { } } - /// Shortens the `VecDeque`, dropping excess elements from the back. + /// Shortens the `VecDeque`, keeping the first `len` elements and dropping + /// the rest. /// /// If `len` is greater than the `VecDeque`'s current length, this has no /// effect. @@ -855,8 +856,31 @@ impl<T> VecDeque<T> { /// ``` #[stable(feature = "deque_extras", since = "1.16.0")] pub fn truncate(&mut self, len: usize) { - for _ in len..self.len() { - self.pop_back(); + // Safe because: + // + // * Any slice passed to `drop_in_place` is valid; the second case has + // `len <= front.len()` and returning on `len > self.len()` ensures + // `begin <= back.len()` in the first case + // * The head of the VecDeque is moved before calling `drop_in_place`, + // so no value is dropped twice if `drop_in_place` panics + unsafe { + if len > self.len() { + return; + } + let num_dropped = self.len() - len; + let (front, back) = self.as_mut_slices(); + if len > front.len() { + let begin = len - front.len(); + let drop_back = back.get_unchecked_mut(begin..) as *mut _; + self.head = self.wrap_sub(self.head, num_dropped); + ptr::drop_in_place(drop_back); + } else { + let drop_back = back as *mut _; + let drop_front = front.get_unchecked_mut(len..) as *mut _; + self.head = self.wrap_sub(self.head, num_dropped); + ptr::drop_in_place(drop_front); + ptr::drop_in_place(drop_back); + } } } @@ -1117,7 +1141,7 @@ impl<T> VecDeque<T> { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn clear(&mut self) { - self.drain(..); + self.truncate(0); } /// Returns `true` if the `VecDeque` contains an element equal to the diff --git a/src/liballoc/collections/vec_deque/tests.rs b/src/liballoc/collections/vec_deque/tests.rs index d578ee0dac4..09009ff516a 100644 --- a/src/liballoc/collections/vec_deque/tests.rs +++ b/src/liballoc/collections/vec_deque/tests.rs @@ -385,6 +385,41 @@ fn test_clone_from() { } #[test] +fn test_vec_deque_truncate_drop() { + static mut DROPS: u32 = 0; + #[derive(Clone)] + struct Elem(i32); + impl Drop for Elem { + fn drop(&mut self) { + unsafe { + DROPS += 1; + } + } + } + + let v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)]; + for push_front in 0..=v.len() { + let v = v.clone(); + let mut tester = VecDeque::with_capacity(5); + for (index, elem) in v.into_iter().enumerate() { + if index < push_front { + tester.push_front(elem); + } else { + tester.push_back(elem); + } + } + assert_eq!(unsafe { DROPS }, 0); + tester.truncate(3); + assert_eq!(unsafe { DROPS }, 2); + tester.truncate(0); + assert_eq!(unsafe { DROPS }, 5); + unsafe { + DROPS = 0; + } + } +} + +#[test] fn issue_53529() { use crate::boxed::Box; diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 94379afc2bd..ddfa6797a57 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -116,7 +116,7 @@ #![feature(unsize)] #![feature(unsized_locals)] #![feature(allocator_internals)] -#![feature(on_unimplemented)] +#![cfg_attr(bootstrap, feature(on_unimplemented))] #![feature(rustc_const_unstable)] #![feature(slice_partition_dedup)] #![feature(maybe_uninit_extra, maybe_uninit_slice)] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index f1c4c32e116..a11f9e8c145 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -280,7 +280,7 @@ struct RcBox<T: ?Sized> { #[stable(feature = "rust1", since = "1.0.0")] pub struct Rc<T: ?Sized> { ptr: NonNull<RcBox<T>>, - phantom: PhantomData<T>, + phantom: PhantomData<RcBox<T>>, } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 0e5746d0d9d..f7dff4c21f7 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -687,7 +687,7 @@ impl String { /// checked: /// /// * The memory at `ptr` needs to have been previously allocated by the - /// same allocator the standard library uses. + /// same allocator the standard library uses, with a required alignment of exactly 1. /// * `length` needs to be less than or equal to `capacity`. /// * `capacity` needs to be the correct value. /// diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 80d6c6e0d43..4b10f089c29 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -195,7 +195,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; #[stable(feature = "rust1", since = "1.0.0")] pub struct Arc<T: ?Sized> { ptr: NonNull<ArcInner<T>>, - phantom: PhantomData<T>, + phantom: PhantomData<ArcInner<T>>, } #[stable(feature = "rust1", since = "1.0.0")] |
