Skip to content

Commit d41e002

Browse files
committed
Add test checking various assignments are accepted in Polonius
1 parent 2f3e36f commit d41e002

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#![allow(dead_code)]
2+
3+
// This tests the various kinds of assignments there are. Polonius used to generate `killed`
4+
// facts only on simple assigments, but not projections, incorrectly causing errors to be emitted
5+
// for code accepted by NLL. They are all variations from example code in the NLL RFC.
6+
7+
// check-pass
8+
// compile-flags: -Z borrowck=mir -Z polonius
9+
// ignore-compare-mode-nll
10+
11+
struct List<T> {
12+
value: T,
13+
next: Option<Box<List<T>>>,
14+
}
15+
16+
// Assignment to a local: the `list` assignment should clear the existing
17+
// borrows of `list.value` and `list.next`
18+
fn assignment_to_local<T>(mut list: &mut List<T>) -> Vec<&mut T> {
19+
let mut result = vec![];
20+
loop {
21+
result.push(&mut list.value);
22+
if let Some(n) = list.next.as_mut() {
23+
list = n;
24+
} else {
25+
return result;
26+
}
27+
}
28+
}
29+
30+
// Assignment to a deref projection: the `*list` assignment should clear the existing
31+
// borrows of `list.value` and `list.next`
32+
fn assignment_to_deref_projection<T>(mut list: Box<&mut List<T>>) -> Vec<&mut T> {
33+
let mut result = vec![];
34+
loop {
35+
result.push(&mut list.value);
36+
if let Some(n) = list.next.as_mut() {
37+
*list = n;
38+
} else {
39+
return result;
40+
}
41+
}
42+
}
43+
44+
// Assignment to a field projection: the `list.0` assignment should clear the existing
45+
// borrows of `list.0.value` and `list.0.next`
46+
fn assignment_to_field_projection<T>(mut list: (&mut List<T>,)) -> Vec<&mut T> {
47+
let mut result = vec![];
48+
loop {
49+
result.push(&mut list.0.value);
50+
if let Some(n) = list.0.next.as_mut() {
51+
list.0 = n;
52+
} else {
53+
return result;
54+
}
55+
}
56+
}
57+
58+
// Assignment to a deref field projection: the `*list.0` assignment should clear the existing
59+
// borrows of `list.0.value` and `list.0.next`
60+
fn assignment_to_deref_field_projection<T>(mut list: (Box<&mut List<T>>,)) -> Vec<&mut T> {
61+
let mut result = vec![];
62+
loop {
63+
result.push(&mut list.0.value);
64+
if let Some(n) = list.0.next.as_mut() {
65+
*list.0 = n;
66+
} else {
67+
return result;
68+
}
69+
}
70+
}
71+
72+
// Similar to `assignment_to_deref_field_projection` but through a longer projection chain
73+
fn assignment_through_projection_chain<T>(
74+
mut list: (((((Box<&mut List<T>>,),),),),),
75+
) -> Vec<&mut T> {
76+
let mut result = vec![];
77+
loop {
78+
result.push(&mut ((((list.0).0).0).0).0.value);
79+
if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() {
80+
*((((list.0).0).0).0).0 = n;
81+
} else {
82+
return result;
83+
}
84+
}
85+
}
86+
87+
fn main() {
88+
}

0 commit comments

Comments
 (0)