Skip to content

Commit 770129c

Browse files
committed
Add test to check that assignments to projections do not kill too many loans
1 parent d41e002 commit 770129c

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#![allow(dead_code)]
2+
3+
// Compared to `assignment-kills-loans.rs`, we check here
4+
// that we do not kill too many borrows. Assignments to the `.1`
5+
// field projections should leave the borrows on `.0` intact.
6+
7+
// compile-flags: -Z borrowck=mir -Z polonius
8+
// ignore-compare-mode-nll
9+
10+
struct List<T> {
11+
value: T,
12+
next: Option<Box<List<T>>>,
13+
}
14+
15+
16+
fn assignment_to_field_projection<'a, T>(
17+
mut list: (&'a mut List<T>, &'a mut List<T>),
18+
) -> Vec<&'a mut T> {
19+
let mut result = vec![];
20+
loop {
21+
result.push(&mut (list.0).value);
22+
//~^ ERROR cannot borrow `list.0.value` as mutable
23+
24+
if let Some(n) = (list.0).next.as_mut() {
25+
//~^ ERROR cannot borrow `list.0.next` as mutable
26+
list.1 = n;
27+
} else {
28+
return result;
29+
}
30+
}
31+
}
32+
33+
fn assignment_through_projection_chain<'a, T>(
34+
mut list: (((((Box<&'a mut List<T>>, Box<&'a mut List<T>>),),),),),
35+
) -> Vec<&'a mut T> {
36+
let mut result = vec![];
37+
loop {
38+
result.push(&mut ((((list.0).0).0).0).0.value);
39+
//~^ ERROR cannot borrow `list.0.0.0.0.0.value` as mutable
40+
41+
if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() {
42+
//~^ ERROR cannot borrow `list.0.0.0.0.0.next` as mutable
43+
*((((list.0).0).0).0).1 = n;
44+
} else {
45+
return result;
46+
}
47+
}
48+
}
49+
50+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
error[E0499]: cannot borrow `list.0.value` as mutable more than once at a time
2+
--> $DIR/assignment-to-differing-field.rs:21:21
3+
|
4+
LL | fn assignment_to_field_projection<'a, 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/assignment-to-differing-field.rs:24:26
15+
|
16+
LL | fn assignment_to_field_projection<'a, 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[E0499]: cannot borrow `list.0.0.0.0.0.value` as mutable more than once at a time
26+
--> $DIR/assignment-to-differing-field.rs:38:21
27+
|
28+
LL | fn assignment_through_projection_chain<'a, T>(
29+
| -- lifetime `'a` defined here
30+
...
31+
LL | result.push(&mut ((((list.0).0).0).0).0.value);
32+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop
33+
...
34+
LL | return result;
35+
| ------ returning this value requires that `list.0.0.0.0.0.value` is borrowed for `'a`
36+
37+
error[E0499]: cannot borrow `list.0.0.0.0.0.next` as mutable more than once at a time
38+
--> $DIR/assignment-to-differing-field.rs:41:26
39+
|
40+
LL | fn assignment_through_projection_chain<'a, T>(
41+
| -- lifetime `'a` defined here
42+
...
43+
LL | if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() {
44+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^---------
45+
| |
46+
| mutable borrow starts here in previous iteration of loop
47+
| argument requires that `list.0.0.0.0.0.next` is borrowed for `'a`
48+
49+
error: aborting due to 4 previous errors
50+
51+
For more information about this error, try `rustc --explain E0499`.

0 commit comments

Comments
 (0)