Skip to content

Commit 3024c4e

Browse files
committed
Auto merge of #68659 - Dylan-DPC:rollup-zo7zi9f, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #66648 (Implement clone_from for BTreeMap and BTreeSet) - #68468 (BTreeMap: tag and explain unsafe internal functions or assert preconditions) - #68626 (Use termize instead of term_size) - #68640 (Document remaining undocumented `From` implementations for IPs) - #68651 (Document `From` implementation for NonZero nums) - #68655 (Fix revision annotations in borrowck-feature-nll-overrides-migrate) Failed merges: r? @ghost
2 parents dc92dfc + 9f497f9 commit 3024c4e

File tree

12 files changed

+332
-136
lines changed

12 files changed

+332
-136
lines changed

Cargo.lock

+11-1
Original file line numberDiff line numberDiff line change
@@ -3540,8 +3540,8 @@ dependencies = [
35403540
"rustc_data_structures",
35413541
"rustc_span",
35423542
"serialize",
3543-
"term_size",
35443543
"termcolor",
3544+
"termize",
35453545
"unicode-width",
35463546
"winapi 0.3.8",
35473547
]
@@ -4580,6 +4580,16 @@ dependencies = [
45804580
"redox_termios",
45814581
]
45824582

4583+
[[package]]
4584+
name = "termize"
4585+
version = "0.1.1"
4586+
source = "registry+https://github.com/rust-lang/crates.io-index"
4587+
checksum = "1706be6b564323ce7092f5f7e6b118a14c8ef7ed0e69c8c5329c914a9f101295"
4588+
dependencies = [
4589+
"libc",
4590+
"winapi 0.3.8",
4591+
]
4592+
45834593
[[package]]
45844594
name = "test"
45854595
version = "0.0.0"

src/liballoc/collections/btree/map.rs

+81-10
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,60 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
207207
clone_subtree(self.root.as_ref())
208208
}
209209
}
210+
211+
fn clone_from(&mut self, other: &Self) {
212+
BTreeClone::clone_from(self, other);
213+
}
214+
}
215+
216+
trait BTreeClone {
217+
fn clone_from(&mut self, other: &Self);
218+
}
219+
220+
impl<K: Clone, V: Clone> BTreeClone for BTreeMap<K, V> {
221+
default fn clone_from(&mut self, other: &Self) {
222+
*self = other.clone();
223+
}
224+
}
225+
226+
impl<K: Clone + Ord, V: Clone> BTreeClone for BTreeMap<K, V> {
227+
fn clone_from(&mut self, other: &Self) {
228+
// This truncates `self` to `other.len()` by calling `split_off` on
229+
// the first key after `other.len()` elements if it exists
230+
let split_off_key = if self.len() > other.len() {
231+
let diff = self.len() - other.len();
232+
if diff <= other.len() {
233+
self.iter().nth_back(diff - 1).map(|pair| (*pair.0).clone())
234+
} else {
235+
self.iter().nth(other.len()).map(|pair| (*pair.0).clone())
236+
}
237+
} else {
238+
None
239+
};
240+
if let Some(key) = split_off_key {
241+
self.split_off(&key);
242+
}
243+
244+
let mut siter = self.range_mut(..);
245+
let mut oiter = other.iter();
246+
// After truncation, `self` is at most as long as `other` so this loop
247+
// replaces every key-value pair in `self`. Since `oiter` is in sorted
248+
// order and the structure of the `BTreeMap` stays the same,
249+
// the BTree invariants are maintained at the end of the loop
250+
while !siter.is_empty() {
251+
if let Some((ok, ov)) = oiter.next() {
252+
// SAFETY: This is safe because the `siter.front != siter.back` check
253+
// ensures that `siter` is nonempty
254+
let (sk, sv) = unsafe { siter.next_unchecked() };
255+
sk.clone_from(ok);
256+
sv.clone_from(ov);
257+
} else {
258+
break;
259+
}
260+
}
261+
// If `other` is longer than `self`, the remaining elements are inserted
262+
self.extend(oiter.map(|(k, v)| ((*k).clone(), (*v).clone())));
263+
}
210264
}
211265

212266
impl<K, Q: ?Sized> super::Recover<Q> for BTreeMap<K, ()>
@@ -1357,7 +1411,10 @@ impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> {
13571411
None
13581412
} else {
13591413
self.length -= 1;
1360-
unsafe { Some(self.range.next_unchecked()) }
1414+
unsafe {
1415+
let (k, v) = self.range.next_unchecked();
1416+
Some((k, v)) // coerce k from `&mut K` to `&K`
1417+
}
13611418
}
13621419
}
13631420

@@ -1736,7 +1793,14 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> {
17361793
type Item = (&'a K, &'a mut V);
17371794

17381795
fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1739-
if self.front == self.back { None } else { unsafe { Some(self.next_unchecked()) } }
1796+
if self.is_empty() {
1797+
None
1798+
} else {
1799+
unsafe {
1800+
let (k, v) = self.next_unchecked();
1801+
Some((k, v)) // coerce k from `&mut K` to `&K`
1802+
}
1803+
}
17401804
}
17411805

17421806
fn last(mut self) -> Option<(&'a K, &'a mut V)> {
@@ -1745,16 +1809,19 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> {
17451809
}
17461810

17471811
impl<'a, K, V> RangeMut<'a, K, V> {
1748-
unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) {
1812+
fn is_empty(&self) -> bool {
1813+
self.front == self.back
1814+
}
1815+
1816+
unsafe fn next_unchecked(&mut self) -> (&'a mut K, &'a mut V) {
17491817
let handle = ptr::read(&self.front);
17501818

17511819
let mut cur_handle = match handle.right_kv() {
17521820
Ok(kv) => {
17531821
self.front = ptr::read(&kv).right_edge();
17541822
// Doing the descend invalidates the references returned by `into_kv_mut`,
17551823
// so we have to do this last.
1756-
let (k, v) = kv.into_kv_mut();
1757-
return (k, v); // coerce k from `&mut K` to `&K`
1824+
return kv.into_kv_mut();
17581825
}
17591826
Err(last_edge) => {
17601827
let next_level = last_edge.into_node().ascend().ok();
@@ -1768,8 +1835,7 @@ impl<'a, K, V> RangeMut<'a, K, V> {
17681835
self.front = first_leaf_edge(ptr::read(&kv).right_edge().descend());
17691836
// Doing the descend invalidates the references returned by `into_kv_mut`,
17701837
// so we have to do this last.
1771-
let (k, v) = kv.into_kv_mut();
1772-
return (k, v); // coerce k from `&mut K` to `&K`
1838+
return kv.into_kv_mut();
17731839
}
17741840
Err(last_edge) => {
17751841
let next_level = last_edge.into_node().ascend().ok();
@@ -1783,7 +1849,7 @@ impl<'a, K, V> RangeMut<'a, K, V> {
17831849
#[stable(feature = "btree_range", since = "1.17.0")]
17841850
impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> {
17851851
fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
1786-
if self.front == self.back { None } else { unsafe { Some(self.next_back_unchecked()) } }
1852+
if self.is_empty() { None } else { unsafe { Some(self.next_back_unchecked()) } }
17871853
}
17881854
}
17891855

@@ -2030,8 +2096,13 @@ where
20302096
}
20312097
}
20322098

2033-
let front = Handle::new_edge(min_node, min_edge);
2034-
let back = Handle::new_edge(max_node, max_edge);
2099+
// Safety guarantee: `min_edge` is always in range for `min_node`, because
2100+
// `min_edge` is unconditionally calculated for each iteration's value of `min_node`,
2101+
// either (if not found) as the edge index returned by `search_linear`,
2102+
// or (if found) as the KV index returned by `search_linear`, possibly + 1.
2103+
// Likewise for `max_node` versus `max_edge`.
2104+
let front = unsafe { Handle::new_edge(min_node, min_edge) };
2105+
let back = unsafe { Handle::new_edge(max_node, max_edge) };
20352106
match (front.force(), back.force()) {
20362107
(Leaf(f), Leaf(b)) => {
20372108
return (f, b);

0 commit comments

Comments
 (0)