X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fliballoc%2Fcollections%2Fbtree%2Fmap.rs;h=b1f0ef0085f2d42a91f4145302ff788c7aea8358;hb=892cb143e5984f220e6b26b48d972bd1f4644298;hp=5b4b1c933472d8abeb16e36df78f8e89db18db56;hpb=82a366ad860b6f0eed639dd103995e6cee1585c7;p=rust.git diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 5b4b1c93347..b1f0ef0085f 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -227,7 +227,7 @@ impl BTreeClone for BTreeMap { impl BTreeClone for BTreeMap { fn clone_from(&mut self, other: &Self) { // This truncates `self` to `other.len()` by calling `split_off` on - // the first key after `other.len()` elements if it exists + // the first key after `other.len()` elements if it exists. let split_off_key = if self.len() > other.len() { let diff = self.len() - other.len(); if diff <= other.len() { @@ -247,11 +247,10 @@ fn clone_from(&mut self, other: &Self) { // After truncation, `self` is at most as long as `other` so this loop // replaces every key-value pair in `self`. Since `oiter` is in sorted // order and the structure of the `BTreeMap` stays the same, - // the BTree invariants are maintained at the end of the loop + // the BTree invariants are maintained at the end of the loop. while !siter.is_empty() { if let Some((ok, ov)) = oiter.next() { - // SAFETY: This is safe because the `siter.front != siter.back` check - // ensures that `siter` is nonempty + // SAFETY: This is safe because `siter` is nonempty. let (sk, sv) = unsafe { siter.next_unchecked() }; sk.clone_from(ok); sv.clone_from(ov); @@ -259,7 +258,7 @@ fn clone_from(&mut self, other: &Self) { break; } } - // If `other` is longer than `self`, the remaining elements are inserted + // If `other` is longer than `self`, the remaining elements are inserted. self.extend(oiter.map(|(k, v)| ((*k).clone(), (*v).clone()))); } } @@ -1471,7 +1470,22 @@ fn into_iter(self) -> IntoIter { #[stable(feature = "btree_drop", since = "1.7.0")] impl Drop for IntoIter { fn drop(&mut self) { - self.for_each(drop); + struct DropGuard<'a, K, V>(&'a mut IntoIter); + + impl<'a, K, V> Drop for DropGuard<'a, K, V> { + fn drop(&mut self) { + // Continue the same loop we perform below. This only runs when unwinding, so we + // don't have to care about panics this time (they'll abort). + while let Some(_) = self.0.next() {} + } + } + + while let Some(pair) = self.next() { + let guard = DropGuard(self); + drop(pair); + mem::forget(guard); + } + unsafe { let leaf_node = ptr::read(&self.front).into_node(); if leaf_node.is_shared_root() {