]>
Commit | Line | Data |
---|---|---|
9cc50fc6 SL |
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 | |
9e0c209e SL |
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 | |
9cc50fc6 SL |
28 | return f; |
29 | }; | |
9e0c209e SL |
30 | //~^ NOTE borrowed value dropped before borrower |
31 | //~| NOTE borrowed value dropped before borrower | |
9cc50fc6 SL |
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 | |
9e0c209e SL |
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 | |
9cc50fc6 SL |
51 | f |
52 | }; | |
9e0c209e SL |
53 | //~^ NOTE borrowed value dropped before borrower |
54 | //~| NOTE borrowed value dropped before borrower | |
9cc50fc6 SL |
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 | |
5bcae85e SL |
83 | //~| NOTE `x` is borrowed here |
84 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 85 | //~| ERROR E0373 |
5bcae85e SL |
86 | //~| NOTE `y` is borrowed here |
87 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
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 | |
5bcae85e SL |
98 | //~| NOTE `x` is borrowed here |
99 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 100 | //~| ERROR E0373 |
5bcae85e SL |
101 | //~| NOTE `y` is borrowed here |
102 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
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 | |
5bcae85e SL |
126 | //~| NOTE `x` is borrowed here |
127 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 128 | //~| ERROR E0373 |
5bcae85e SL |
129 | //~| NOTE `y` is borrowed here |
130 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
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 | |
5bcae85e SL |
144 | //~| NOTE `x` is borrowed here |
145 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 146 | //~| ERROR E0373 |
5bcae85e SL |
147 | //~| NOTE `y` is borrowed here |
148 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
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 | |
5bcae85e SL |
176 | //~| NOTE `x` is borrowed here |
177 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 178 | //~| ERROR E0373 |
5bcae85e SL |
179 | //~| NOTE `y` is borrowed here |
180 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
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 | |
5bcae85e SL |
195 | //~| NOTE `x` is borrowed here |
196 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 197 | //~| ERROR E0373 |
5bcae85e SL |
198 | //~| NOTE `y` is borrowed here |
199 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
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 | |
5bcae85e SL |
227 | //~| NOTE `x` is borrowed here |
228 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 229 | //~| ERROR E0373 |
5bcae85e SL |
230 | //~| NOTE `y` is borrowed here |
231 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
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 | |
5bcae85e SL |
245 | //~| NOTE `x` is borrowed here |
246 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 247 | //~| ERROR E0373 |
5bcae85e SL |
248 | //~| NOTE `y` is borrowed here |
249 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
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 |