Skip to content

Commit 3b8ef01

Browse files
committed
Add test that our handling of projections hasn't gone too far:
overwriting one field should not allow reborrow of an unrelated field.
1 parent 241ceed commit 3b8ef01

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Double-check we didn't go too far with our resolution to issue
2+
// #62007: assigning over a field projection (`list.1 = n;` in this
3+
// case) should kill only borrows of `list.1`; `list.0` can *not*
4+
// necessarily be borrowed on the next iteration through the loop.
5+
6+
#![allow(dead_code)]
7+
8+
struct List<T> {
9+
value: T,
10+
next: Option<Box<List<T>>>,
11+
}
12+
13+
fn to_refs<'a, T>(mut list: (&'a mut List<T>, &'a mut List<T>)) -> Vec<&'a mut T> {
14+
let mut result = vec![];
15+
loop {
16+
result.push(&mut (list.0).value); //~ ERROR cannot borrow `list.0.value` as mutable
17+
if let Some(n) = (list.0).next.as_mut() { //~ ERROR cannot borrow `list.0.next` as mutable
18+
list.1 = n;
19+
} else {
20+
return result;
21+
}
22+
}
23+
}
24+
25+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0499]: cannot borrow `list.0.value` as mutable more than once at a time
2+
--> $DIR/issue-62007-assign-differing-fields.rs:16:21
3+
|
4+
LL | fn to_refs<'a, T>(mut list: (&'a mut List<T>, &'a mut List<T>)) -> Vec<&'a mut T> {
5+
| -- lifetime `'a` defined here
6+
...
7+
LL | result.push(&mut (list.0).value);
8+
| ^^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop
9+
...
10+
LL | return result;
11+
| ------ returning this value requires that `list.0.value` is borrowed for `'a`
12+
13+
error[E0499]: cannot borrow `list.0.next` as mutable more than once at a time
14+
--> $DIR/issue-62007-assign-differing-fields.rs:17:26
15+
|
16+
LL | fn to_refs<'a, T>(mut list: (&'a mut List<T>, &'a mut List<T>)) -> Vec<&'a mut T> {
17+
| -- lifetime `'a` defined here
18+
...
19+
LL | if let Some(n) = (list.0).next.as_mut() {
20+
| ^^^^^^^^^^^^^---------
21+
| |
22+
| mutable borrow starts here in previous iteration of loop
23+
| argument requires that `list.0.next` is borrowed for `'a`
24+
25+
error: aborting due to 2 previous errors
26+
27+
For more information about this error, try `rustc --explain E0499`.

0 commit comments

Comments
 (0)