]>
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| { | |
5bcae85e SL |
19 | //~^ NOTE reference must be valid for the scope of call-site for function |
20 | //~| NOTE ...but borrowed value is only valid for the scope of function body | |
21 | //~| NOTE reference must be valid for the scope of call-site for function | |
22 | //~| NOTE ...but borrowed value is only valid for the scope of function body | |
9cc50fc6 SL |
23 | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) |
24 | //~^ ERROR `x` does not live long enough | |
25 | //~| ERROR `y` does not live long enough | |
26 | return f; | |
27 | }; | |
28 | ||
29 | // We delberately do not call `g`; this small version of the test, | |
30 | // after adding such a call, was (properly) rejected even when the | |
31 | // system still suffered from issue #29793. | |
32 | ||
33 | // g(10, 20)(true); | |
34 | } | |
35 | ||
36 | fn escaping_borrow_of_closure_params_2() { | |
37 | let g = |x: usize, y:usize| { | |
5bcae85e SL |
38 | //~^ NOTE reference must be valid for the scope of call-site for function |
39 | //~| NOTE ...but borrowed value is only valid for the scope of function body | |
40 | //~| NOTE reference must be valid for the scope of call-site for function | |
41 | //~| NOTE ...but borrowed value is only valid for the scope of function body | |
9cc50fc6 SL |
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 | f | |
46 | }; | |
47 | ||
48 | // (we don't call `g`; see above) | |
49 | } | |
50 | ||
51 | fn move_of_closure_params() { | |
52 | let g = |x: usize, y:usize| { | |
53 | let f = move |t: bool| if t { x } else { y }; | |
54 | f; | |
55 | }; | |
56 | // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) | |
57 | (g(1,2)); | |
58 | } | |
59 | ||
60 | fn ok_borrow_of_fn_params(a: usize, b:usize) { | |
61 | let g = |x: usize, y:usize| { | |
62 | let f = |t: bool| if t { a } else { b }; | |
63 | return f; | |
64 | }; | |
65 | // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) | |
66 | (g(1,2))(true); | |
67 | } | |
68 | ||
69 | // TOP-LEVEL FN'S | |
70 | ||
71 | fn escaping_borrow_of_fn_params_1() { | |
72 | fn g<'a>(x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> { | |
73 | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) | |
74 | //~^ ERROR E0373 | |
5bcae85e SL |
75 | //~| NOTE `x` is borrowed here |
76 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 77 | //~| ERROR E0373 |
5bcae85e SL |
78 | //~| NOTE `y` is borrowed here |
79 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
80 | return Box::new(f); |
81 | }; | |
82 | ||
83 | // (we don't call `g`; see above) | |
84 | } | |
85 | ||
86 | fn escaping_borrow_of_fn_params_2() { | |
87 | fn g<'a>(x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> { | |
88 | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) | |
89 | //~^ ERROR E0373 | |
5bcae85e SL |
90 | //~| NOTE `x` is borrowed here |
91 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 92 | //~| ERROR E0373 |
5bcae85e SL |
93 | //~| NOTE `y` is borrowed here |
94 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
95 | Box::new(f) |
96 | }; | |
97 | ||
98 | // (we don't call `g`; see above) | |
99 | } | |
100 | ||
101 | fn move_of_fn_params() { | |
102 | fn g<'a>(x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> { | |
103 | let f = move |t: bool| if t { x } else { y }; | |
104 | return Box::new(f); | |
105 | }; | |
106 | // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) | |
107 | (g(1,2))(true); | |
108 | } | |
109 | ||
110 | // INHERENT METHODS | |
111 | ||
112 | fn escaping_borrow_of_method_params_1() { | |
113 | struct S; | |
114 | impl S { | |
115 | fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> { | |
116 | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) | |
117 | //~^ ERROR E0373 | |
5bcae85e SL |
118 | //~| NOTE `x` is borrowed here |
119 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 120 | //~| ERROR E0373 |
5bcae85e SL |
121 | //~| NOTE `y` is borrowed here |
122 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
123 | return Box::new(f); |
124 | } | |
125 | } | |
126 | ||
127 | // (we don't call `g`; see above) | |
128 | } | |
129 | ||
130 | fn escaping_borrow_of_method_params_2() { | |
131 | struct S; | |
132 | impl S { | |
133 | fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> { | |
134 | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) | |
135 | //~^ ERROR E0373 | |
5bcae85e SL |
136 | //~| NOTE `x` is borrowed here |
137 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 138 | //~| ERROR E0373 |
5bcae85e SL |
139 | //~| NOTE `y` is borrowed here |
140 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
141 | Box::new(f) |
142 | } | |
143 | } | |
144 | // (we don't call `g`; see above) | |
145 | } | |
146 | ||
147 | fn move_of_method_params() { | |
148 | struct S; | |
149 | impl S { | |
150 | fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> { | |
151 | let f = move |t: bool| if t { x } else { y }; | |
152 | return Box::new(f); | |
153 | } | |
154 | } | |
155 | // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) | |
156 | (S.g(1,2))(true); | |
157 | } | |
158 | ||
159 | // TRAIT IMPL METHODS | |
160 | ||
161 | fn escaping_borrow_of_trait_impl_params_1() { | |
162 | trait T { fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a>; } | |
163 | struct S; | |
164 | impl T for S { | |
165 | fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> { | |
166 | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) | |
167 | //~^ ERROR E0373 | |
5bcae85e SL |
168 | //~| NOTE `x` is borrowed here |
169 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 170 | //~| ERROR E0373 |
5bcae85e SL |
171 | //~| NOTE `y` is borrowed here |
172 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
173 | return Box::new(f); |
174 | } | |
175 | } | |
176 | ||
177 | // (we don't call `g`; see above) | |
178 | } | |
179 | ||
180 | fn escaping_borrow_of_trait_impl_params_2() { | |
181 | trait T { fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a>; } | |
182 | struct S; | |
183 | impl T for S { | |
184 | fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> { | |
185 | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) | |
186 | //~^ ERROR E0373 | |
5bcae85e SL |
187 | //~| NOTE `x` is borrowed here |
188 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 189 | //~| ERROR E0373 |
5bcae85e SL |
190 | //~| NOTE `y` is borrowed here |
191 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
192 | Box::new(f) |
193 | } | |
194 | } | |
195 | // (we don't call `g`; see above) | |
196 | } | |
197 | ||
198 | fn move_of_trait_impl_params() { | |
199 | trait T { fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a>; } | |
200 | struct S; | |
201 | impl T for S { | |
202 | fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> { | |
203 | let f = move |t: bool| if t { x } else { y }; | |
204 | return Box::new(f); | |
205 | } | |
206 | } | |
207 | // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) | |
208 | (S.g(1,2))(true); | |
209 | } | |
210 | ||
211 | // TRAIT DEFAULT METHODS | |
212 | ||
213 | fn escaping_borrow_of_trait_default_params_1() { | |
214 | struct S; | |
215 | trait T { | |
216 | fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> { | |
217 | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) | |
218 | //~^ ERROR E0373 | |
5bcae85e SL |
219 | //~| NOTE `x` is borrowed here |
220 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 221 | //~| ERROR E0373 |
5bcae85e SL |
222 | //~| NOTE `y` is borrowed here |
223 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
224 | return Box::new(f); |
225 | } | |
226 | } | |
227 | impl T for S {} | |
228 | // (we don't call `g`; see above) | |
229 | } | |
230 | ||
231 | fn escaping_borrow_of_trait_default_params_2() { | |
232 | struct S; | |
233 | trait T { | |
234 | fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> { | |
235 | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) | |
236 | //~^ ERROR E0373 | |
5bcae85e SL |
237 | //~| NOTE `x` is borrowed here |
238 | //~| NOTE may outlive borrowed value `x` | |
9cc50fc6 | 239 | //~| ERROR E0373 |
5bcae85e SL |
240 | //~| NOTE `y` is borrowed here |
241 | //~| NOTE may outlive borrowed value `y` | |
9cc50fc6 SL |
242 | Box::new(f) |
243 | } | |
244 | } | |
245 | impl T for S {} | |
246 | // (we don't call `g`; see above) | |
247 | } | |
248 | ||
249 | fn move_of_trait_default_params() { | |
250 | struct S; | |
251 | trait T { | |
252 | fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> { | |
253 | let f = move |t: bool| if t { x } else { y }; | |
254 | return Box::new(f); | |
255 | } | |
256 | } | |
257 | impl T for S {} | |
258 | // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) | |
259 | (S.g(1,2))(true); | |
260 | } | |
261 | ||
262 | fn main() { } | |
263 |