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.
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.
11 // Issue #29793, small regression tests: do not let borrows of
12 // parameters to ever be returned (expanded with exploration of
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
30 //~^ NOTE borrowed value dropped before borrower
31 //~| NOTE borrowed value dropped before borrower
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.
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
53 //~^ NOTE borrowed value dropped before borrower
54 //~| NOTE borrowed value dropped before borrower
56 // (we don't call `g`; see above)
59 fn move_of_closure_params() {
60 let g
= |x
: usize, y
:usize| {
61 let f
= move |t
: bool
| if t { x }
else { y }
;
64 // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`)
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 }
;
73 // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`)
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`)
83 //~| NOTE `x` is borrowed here
84 //~| NOTE may outlive borrowed value `x`
86 //~| NOTE `y` is borrowed here
87 //~| NOTE may outlive borrowed value `y`
91 // (we don't call `g`; see above)
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`)
98 //~| NOTE `x` is borrowed here
99 //~| NOTE may outlive borrowed value `x`
101 //~| NOTE `y` is borrowed here
102 //~| NOTE may outlive borrowed value `y`
106 // (we don't call `g`; see above)
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 }
;
114 // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`)
120 fn escaping_borrow_of_method_params_1() {
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`)
126 //~| NOTE `x` is borrowed here
127 //~| NOTE may outlive borrowed value `x`
129 //~| NOTE `y` is borrowed here
130 //~| NOTE may outlive borrowed value `y`
135 // (we don't call `g`; see above)
138 fn escaping_borrow_of_method_params_2() {
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`)
144 //~| NOTE `x` is borrowed here
145 //~| NOTE may outlive borrowed value `x`
147 //~| NOTE `y` is borrowed here
148 //~| NOTE may outlive borrowed value `y`
152 // (we don't call `g`; see above)
155 fn move_of_method_params() {
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 }
;
163 // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`)
167 // TRAIT IMPL METHODS
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>; }
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`)
176 //~| NOTE `x` is borrowed here
177 //~| NOTE may outlive borrowed value `x`
179 //~| NOTE `y` is borrowed here
180 //~| NOTE may outlive borrowed value `y`
185 // (we don't call `g`; see above)
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>; }
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`)
195 //~| NOTE `x` is borrowed here
196 //~| NOTE may outlive borrowed value `x`
198 //~| NOTE `y` is borrowed here
199 //~| NOTE may outlive borrowed value `y`
203 // (we don't call `g`; see above)
206 fn move_of_trait_impl_params() {
207 trait T { fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a>; }
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 }
;
215 // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`)
219 // TRAIT DEFAULT METHODS
221 fn escaping_borrow_of_trait_default_params_1() {
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`)
227 //~| NOTE `x` is borrowed here
228 //~| NOTE may outlive borrowed value `x`
230 //~| NOTE `y` is borrowed here
231 //~| NOTE may outlive borrowed value `y`
236 // (we don't call `g`; see above)
239 fn escaping_borrow_of_trait_default_params_2() {
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`)
245 //~| NOTE `x` is borrowed here
246 //~| NOTE may outlive borrowed value `x`
248 //~| NOTE `y` is borrowed here
249 //~| NOTE may outlive borrowed value `y`
254 // (we don't call `g`; see above)
257 fn move_of_trait_default_params() {
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 }
;
266 // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`)