Skip to content

Commit f0bef49

Browse files
committed
fix invalidating references in BTree iterators
1 parent d87df69 commit f0bef49

File tree

2 files changed

+21
-13
lines changed

2 files changed

+21
-13
lines changed

src/liballoc/collections/btree/map.rs

+20-12
Original file line numberDiff line numberDiff line change
@@ -1634,9 +1634,11 @@ impl<'a, K, V> RangeMut<'a, K, V> {
16341634

16351635
let mut cur_handle = match handle.right_kv() {
16361636
Ok(kv) => {
1637-
let (k, v) = ptr::read(&kv).into_kv_mut();
1638-
self.front = kv.right_edge();
1639-
return (k, v);
1637+
self.front = ptr::read(&kv).right_edge();
1638+
// Doing the descend invalidates the references returned by `into_kv_mut`,
1639+
// so we have to do this last.
1640+
let (k, v) = kv.into_kv_mut();
1641+
return (k, v); // coerce k from `&mut K` to `&K`
16401642
}
16411643
Err(last_edge) => {
16421644
let next_level = last_edge.into_node().ascend().ok();
@@ -1647,9 +1649,11 @@ impl<'a, K, V> RangeMut<'a, K, V> {
16471649
loop {
16481650
match cur_handle.right_kv() {
16491651
Ok(kv) => {
1650-
let (k, v) = ptr::read(&kv).into_kv_mut();
1651-
self.front = first_leaf_edge(kv.right_edge().descend());
1652-
return (k, v);
1652+
self.front = first_leaf_edge(ptr::read(&kv).right_edge().descend());
1653+
// Doing the descend invalidates the references returned by `into_kv_mut`,
1654+
// so we have to do this last.
1655+
let (k, v) = kv.into_kv_mut();
1656+
return (k, v); // coerce k from `&mut K` to `&K`
16531657
}
16541658
Err(last_edge) => {
16551659
let next_level = last_edge.into_node().ascend().ok();
@@ -1680,9 +1684,11 @@ impl<'a, K, V> RangeMut<'a, K, V> {
16801684

16811685
let mut cur_handle = match handle.left_kv() {
16821686
Ok(kv) => {
1683-
let (k, v) = ptr::read(&kv).into_kv_mut();
1684-
self.back = kv.left_edge();
1685-
return (k, v);
1687+
self.back = ptr::read(&kv).left_edge();
1688+
// Doing the descend invalidates the references returned by `into_kv_mut`,
1689+
// so we have to do this last.
1690+
let (k, v) = kv.into_kv_mut();
1691+
return (k, v); // coerce k from `&mut K` to `&K`
16861692
}
16871693
Err(last_edge) => {
16881694
let next_level = last_edge.into_node().ascend().ok();
@@ -1693,9 +1699,11 @@ impl<'a, K, V> RangeMut<'a, K, V> {
16931699
loop {
16941700
match cur_handle.left_kv() {
16951701
Ok(kv) => {
1696-
let (k, v) = ptr::read(&kv).into_kv_mut();
1697-
self.back = last_leaf_edge(kv.left_edge().descend());
1698-
return (k, v);
1702+
self.back = last_leaf_edge(ptr::read(&kv).left_edge().descend());
1703+
// Doing the descend invalidates the references returned by `into_kv_mut`,
1704+
// so we have to do this last.
1705+
let (k, v) = kv.into_kv_mut();
1706+
return (k, v); // coerce k from `&mut K` to `&K`
16991707
}
17001708
Err(last_edge) => {
17011709
let next_level = last_edge.into_node().ascend().ok();

src/liballoc/collections/btree/node.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
675675
// invalidates the reference returned by the first.
676676
// More precisely, it is the call to `len` that is the culprit,
677677
// because that creates a shared reference to the header, which *can*
678-
// overlap with the keys.
678+
// overlap with the keys (and even the values, for ZST keys).
679679
unsafe {
680680
let len = self.len();
681681
let leaf = self.as_leaf_mut();

0 commit comments

Comments
 (0)