]> git.lizzy.rs Git - rust.git/blob - src/test/ui/borrowck/borrowck-describe-lvalue.rs
Simplify SaveHandler trait
[rust.git] / src / test / ui / borrowck / borrowck-describe-lvalue.rs
1 // ignore-tidy-linelength
2
3 #![feature(slice_patterns)]
4
5 pub struct Foo {
6   x: u32
7 }
8
9 pub struct Bar(u32);
10
11 pub enum Baz {
12     X(u32)
13 }
14
15 union U {
16     a: u8,
17     b: u64,
18 }
19
20 impl Foo {
21   fn x(&mut self) -> &mut u32 { &mut self.x }
22 }
23
24 impl Bar {
25     fn x(&mut self) -> &mut u32 { &mut self.0 }
26 }
27
28 impl Baz {
29     fn x(&mut self) -> &mut u32 {
30         match *self {
31             Baz::X(ref mut value) => value
32         }
33     }
34 }
35
36 fn main() {
37     // Local and field from struct
38     {
39         let mut f = Foo { x: 22 };
40         let x = f.x();
41         f.x; //~ ERROR cannot use `f.x` because it was mutably borrowed
42         drop(x);
43     }
44     // Local and field from tuple-struct
45     {
46         let mut g = Bar(22);
47         let x = g.x();
48         g.0; //~ ERROR cannot use `g.0` because it was mutably borrowed
49         drop(x);
50     }
51     // Local and field from tuple
52     {
53         let mut h = (22, 23);
54         let x = &mut h.0;
55         h.0; //~ ERROR cannot use `h.0` because it was mutably borrowed
56         drop(x);
57     }
58     // Local and field from enum
59     {
60         let mut e = Baz::X(2);
61         let x = e.x();
62         match e {
63             Baz::X(value) => value //~ ERROR cannot use `e.0` because it was mutably borrowed
64         };
65         drop(x);
66     }
67     // Local and field from union
68     unsafe {
69         let mut u = U { b: 0 };
70         let x = &mut u.a;
71         u.a; //~ ERROR cannot use `u.a` because it was mutably borrowed
72         drop(x);
73     }
74     // Deref and field from struct
75     {
76         let mut f = Box::new(Foo { x: 22 });
77         let x = f.x();
78         f.x; //~ ERROR cannot use `f.x` because it was mutably borrowed
79         drop(x);
80     }
81     // Deref and field from tuple-struct
82     {
83         let mut g = Box::new(Bar(22));
84         let x = g.x();
85         g.0; //~ ERROR cannot use `g.0` because it was mutably borrowed
86         drop(x);
87     }
88     // Deref and field from tuple
89     {
90         let mut h = Box::new((22, 23));
91         let x = &mut h.0;
92         h.0; //~ ERROR cannot use `h.0` because it was mutably borrowed
93         drop(x);
94     }
95     // Deref and field from enum
96     {
97         let mut e = Box::new(Baz::X(3));
98         let x = e.x();
99         match *e {
100             Baz::X(value) => value
101             //~^ ERROR cannot use `e.0` because it was mutably borrowed
102         };
103         drop(x);
104     }
105     // Deref and field from union
106     unsafe {
107         let mut u = Box::new(U { b: 0 });
108         let x = &mut u.a;
109         u.a; //~ ERROR cannot use `u.a` because it was mutably borrowed
110         drop(x);
111     }
112     // Constant index
113     {
114         let mut v = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
115         let x = &mut v;
116         match v {
117             &[x, _, .., _, _] => println!("{}", x),
118                 //~^ ERROR cannot use `v[..]` because it was mutably borrowed
119                             _ => panic!("other case"),
120         }
121         match v {
122             &[_, x, .., _, _] => println!("{}", x),
123                 //~^ ERROR cannot use `v[..]` because it was mutably borrowed
124                             _ => panic!("other case"),
125         }
126         match v {
127             &[_, _, .., x, _] => println!("{}", x),
128                 //~^ ERROR cannot use `v[..]` because it was mutably borrowed
129                             _ => panic!("other case"),
130         }
131         match v {
132             &[_, _, .., _, x] => println!("{}", x),
133                 //~^ ERROR cannot use `v[..]` because it was mutably borrowed
134                             _ => panic!("other case"),
135         }
136         drop(x);
137     }
138     // Subslices
139     {
140         let mut v = &[1, 2, 3, 4, 5];
141         let x = &mut v;
142         match v {
143             &[x..] => println!("{:?}", x),
144                 //~^ ERROR cannot use `v[..]` because it was mutably borrowed
145             _ => panic!("other case"),
146         }
147         match v {
148             &[_, x..] => println!("{:?}", x),
149                 //~^ ERROR cannot use `v[..]` because it was mutably borrowed
150             _ => panic!("other case"),
151         }
152         match v {
153             &[x.., _] => println!("{:?}", x),
154                 //~^ ERROR cannot use `v[..]` because it was mutably borrowed
155             _ => panic!("other case"),
156         }
157         match v {
158             &[_, x.., _] => println!("{:?}", x),
159                 //~^ ERROR cannot use `v[..]` because it was mutably borrowed
160             _ => panic!("other case"),
161         }
162         drop(x);
163     }
164     // Downcasted field
165     {
166         enum E<X> { A(X), B { x: X } }
167
168         let mut e = E::A(3);
169         let x = &mut e;
170         match e {
171             E::A(ref ax) =>
172                 //~^ ERROR cannot borrow `e.0` as immutable because it is also borrowed as mutable
173                 //~| ERROR cannot use `e` because it was mutably borrowed
174                 println!("e.ax: {:?}", ax),
175             E::B { x: ref bx } =>
176                 //~^ ERROR cannot borrow `e.x` as immutable because it is also borrowed as mutable
177                 println!("e.bx: {:?}", bx),
178         }
179         drop(x);
180     }
181     // Field in field
182     {
183         struct F { x: u32, y: u32 };
184         struct S { x: F, y: (u32, u32), };
185         let mut s = S { x: F { x: 1, y: 2}, y: (999, 998) };
186         let x = &mut s;
187         match s {
188             S  { y: (ref y0, _), .. } =>
189                 //~^ ERROR cannot borrow `s.y.0` as immutable because it is also borrowed as mutable
190                 println!("y0: {:?}", y0),
191             _ => panic!("other case"),
192         }
193         match s {
194             S  { x: F { y: ref x0, .. }, .. } =>
195                 //~^ ERROR cannot borrow `s.x.y` as immutable because it is also borrowed as mutable
196                 println!("x0: {:?}", x0),
197             _ => panic!("other case"),
198         }
199         drop(x);
200     }
201     // Field of ref
202     {
203         struct Block<'a> {
204             current: &'a u8,
205             unrelated: &'a u8,
206         };
207
208         fn bump<'a>(mut block: &mut Block<'a>) {
209             let x = &mut block;
210             let p: &'a u8 = &*block.current;
211             //~^ WARNING cannot borrow `*block.current` as immutable because it is also borrowed as mutable
212             //~| this error has been downgraded
213             //~| this warning will become a hard error in the future
214             // Warning because of issue rust#38899
215             drop(x);
216         }
217     }
218     // Field of ptr
219     {
220         struct Block2 {
221             current: *const u8,
222             unrelated: *const u8,
223         }
224
225         unsafe fn bump2(mut block: *mut Block2) {
226             let x = &mut block;
227             let p : *const u8 = &*(*block).current;
228             //~^ WARNING cannot borrow `*block.current` as immutable because it is also borrowed as mutable
229             //~| this error has been downgraded
230             //~| this warning will become a hard error in the future
231             // Warning because of issue rust#38899
232             drop(x);
233         }
234     }
235     // Field of index
236     {
237         struct F {x: u32, y: u32};
238         let mut v = &[F{x: 1, y: 2}, F{x: 3, y: 4}];
239         let x = &mut v;
240         v[0].y;
241         //~^ ERROR cannot use `v[_].y` because it was mutably borrowed
242         //~| ERROR cannot use `*v` because it was mutably borrowed
243         drop(x);
244     }
245     // Field of constant index
246     {
247         struct F {x: u32, y: u32};
248         let mut v = &[F{x: 1, y: 2}, F{x: 3, y: 4}];
249         let x = &mut v;
250         match v {
251             &[_, F {x: ref xf, ..}] => println!("{}", xf),
252             //~^ ERROR cannot borrow `v[..].x` as immutable because it is also borrowed as mutable
253             _ => panic!("other case")
254         }
255         drop(x);
256     }
257     // Field from upvar
258     {
259         let mut x = 0;
260         || {
261             let y = &mut x;
262             &mut x; //~ ERROR cannot borrow `x` as mutable more than once at a time
263             *y = 1;
264         };
265     }
266     // Field from upvar nested
267     {
268         let mut x = 0;
269            || {
270                || { //~ ERROR captured variable cannot escape `FnMut` closure body
271                    let y = &mut x;
272                    &mut x; //~ ERROR cannot borrow `x` as mutable more than once at a time
273                    *y = 1;
274                    drop(y);
275                 }
276            };
277     }
278     {
279         fn foo(x: Vec<i32>) {
280             let c = || {
281                 drop(x);
282                 drop(x); //~ ERROR use of moved value: `x`
283             };
284             c();
285         }
286     }
287 }