]> git.lizzy.rs Git - rust.git/blob - src/test/compile-fail/region-borrow-params-issue-29793-small.rs
Move 'doesn't live long enough' errors to labels
[rust.git] / src / test / compile-fail / region-borrow-params-issue-29793-small.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // Issue #29793, small regression tests: do not let borrows of
12 // parameters to ever be returned (expanded with exploration of
13 // variations).
14
15 // CLOSURES
16
17 fn escaping_borrow_of_closure_params_1() {
18     let g = |x: usize, y:usize| {
19         let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
20         //~^ ERROR `x` does not live long enough
21         //~| ERROR `y` does not live long enough
22         //~| NOTE capture occurs here
23         //~| NOTE capture occurs here
24         //~| NOTE does not live long enough
25         //~| NOTE does not live long enough
26         //~| NOTE values in a scope are dropped in the opposite order they are created
27         //~| NOTE values in a scope are dropped in the opposite order they are created
28         return f;
29     };
30     //~^ NOTE borrowed value dropped before borrower 
31     //~| NOTE borrowed value dropped before borrower 
32
33     // We delberately do not call `g`; this small version of the test,
34     // after adding such a call, was (properly) rejected even when the
35     // system still suffered from issue #29793.
36
37     // g(10, 20)(true);
38 }
39
40 fn escaping_borrow_of_closure_params_2() {
41     let g = |x: usize, y:usize| {
42         let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
43         //~^ ERROR `x` does not live long enough
44         //~| ERROR `y` does not live long enough
45         //~| NOTE capture occurs here
46         //~| NOTE capture occurs here
47         //~| NOTE does not live long enough
48         //~| NOTE does not live long enough
49         //~| NOTE values in a scope are dropped in the opposite order they are created
50         //~| NOTE values in a scope are dropped in the opposite order they are created
51         f
52     };
53     //~^ NOTE borrowed value dropped before borrower 
54     //~| NOTE borrowed value dropped before borrower 
55
56     // (we don't call `g`; see above)
57 }
58
59 fn move_of_closure_params() {
60     let g = |x: usize, y:usize| {
61         let f = move |t: bool| if t { x } else { y };
62         f;
63     };
64     // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`)
65     (g(1,2));
66 }
67
68 fn ok_borrow_of_fn_params(a: usize, b:usize) {
69     let g = |x: usize, y:usize| {
70         let f = |t: bool| if t { a } else { b };
71         return f;
72     };
73     // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`)
74     (g(1,2))(true);
75 }
76
77 // TOP-LEVEL FN'S
78
79 fn escaping_borrow_of_fn_params_1() {
80     fn g<'a>(x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
81         let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
82         //~^ ERROR E0373
83         //~| NOTE `x` is borrowed here
84         //~| NOTE may outlive borrowed value `x`
85         //~| ERROR E0373
86         //~| NOTE `y` is borrowed here
87         //~| NOTE may outlive borrowed value `y`
88         return Box::new(f);
89     };
90
91     // (we don't call `g`; see above)
92 }
93
94 fn escaping_borrow_of_fn_params_2() {
95     fn g<'a>(x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
96         let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
97         //~^ ERROR E0373
98         //~| NOTE `x` is borrowed here
99         //~| NOTE may outlive borrowed value `x`
100         //~| ERROR E0373
101         //~| NOTE `y` is borrowed here
102         //~| NOTE may outlive borrowed value `y`
103         Box::new(f)
104     };
105
106     // (we don't call `g`; see above)
107 }
108
109 fn move_of_fn_params() {
110     fn g<'a>(x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
111         let f = move |t: bool| if t { x } else { y };
112         return Box::new(f);
113     };
114     // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`)
115     (g(1,2))(true);
116 }
117
118 // INHERENT METHODS
119
120 fn escaping_borrow_of_method_params_1() {
121     struct S;
122     impl S {
123         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
124             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
125             //~^ ERROR E0373
126             //~| NOTE `x` is borrowed here
127             //~| NOTE may outlive borrowed value `x`
128             //~| ERROR E0373
129             //~| NOTE `y` is borrowed here
130             //~| NOTE may outlive borrowed value `y`
131             return Box::new(f);
132         }
133     }
134
135     // (we don't call `g`; see above)
136 }
137
138 fn escaping_borrow_of_method_params_2() {
139     struct S;
140     impl S {
141         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
142             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
143             //~^ ERROR E0373
144             //~| NOTE `x` is borrowed here
145             //~| NOTE may outlive borrowed value `x`
146             //~| ERROR E0373
147             //~| NOTE `y` is borrowed here
148             //~| NOTE may outlive borrowed value `y`
149             Box::new(f)
150         }
151     }
152     // (we don't call `g`; see above)
153 }
154
155 fn move_of_method_params() {
156     struct S;
157     impl S {
158         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
159             let f = move |t: bool| if t { x } else { y };
160             return Box::new(f);
161         }
162     }
163     // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`)
164     (S.g(1,2))(true);
165 }
166
167 // TRAIT IMPL METHODS
168
169 fn escaping_borrow_of_trait_impl_params_1() {
170     trait T { fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a>; }
171     struct S;
172     impl T for S {
173         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
174             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
175             //~^ ERROR E0373
176             //~| NOTE `x` is borrowed here
177             //~| NOTE may outlive borrowed value `x`
178             //~| ERROR E0373
179             //~| NOTE `y` is borrowed here
180             //~| NOTE may outlive borrowed value `y`
181             return Box::new(f);
182         }
183     }
184
185     // (we don't call `g`; see above)
186 }
187
188 fn escaping_borrow_of_trait_impl_params_2() {
189     trait T { fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a>; }
190     struct S;
191     impl T for S {
192         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
193             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
194             //~^ ERROR E0373
195             //~| NOTE `x` is borrowed here
196             //~| NOTE may outlive borrowed value `x`
197             //~| ERROR E0373
198             //~| NOTE `y` is borrowed here
199             //~| NOTE may outlive borrowed value `y`
200             Box::new(f)
201         }
202     }
203     // (we don't call `g`; see above)
204 }
205
206 fn move_of_trait_impl_params() {
207     trait T { fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a>; }
208     struct S;
209     impl T for S {
210         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
211             let f = move |t: bool| if t { x } else { y };
212             return Box::new(f);
213         }
214     }
215     // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`)
216     (S.g(1,2))(true);
217 }
218
219 // TRAIT DEFAULT METHODS
220
221 fn escaping_borrow_of_trait_default_params_1() {
222     struct S;
223     trait T {
224         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
225             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
226             //~^ ERROR E0373
227             //~| NOTE `x` is borrowed here
228             //~| NOTE may outlive borrowed value `x`
229             //~| ERROR E0373
230             //~| NOTE `y` is borrowed here
231             //~| NOTE may outlive borrowed value `y`
232             return Box::new(f);
233         }
234     }
235     impl T for S {}
236     // (we don't call `g`; see above)
237 }
238
239 fn escaping_borrow_of_trait_default_params_2() {
240     struct S;
241     trait T {
242         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
243             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
244             //~^ ERROR E0373
245             //~| NOTE `x` is borrowed here
246             //~| NOTE may outlive borrowed value `x`
247             //~| ERROR E0373
248             //~| NOTE `y` is borrowed here
249             //~| NOTE may outlive borrowed value `y`
250             Box::new(f)
251         }
252     }
253     impl T for S {}
254     // (we don't call `g`; see above)
255 }
256
257 fn move_of_trait_default_params() {
258     struct S;
259     trait T {
260         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
261             let f = move |t: bool| if t { x } else { y };
262             return Box::new(f);
263         }
264     }
265     impl T for S {}
266     // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`)
267     (S.g(1,2))(true);
268 }
269
270 fn main() { }
271