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