// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // Issue #29793, small regression tests: do not let borrows of // parameters to ever be returned (expanded with exploration of // variations). // CLOSURES fn escaping_borrow_of_closure_params_1() { let g = |x: usize, y:usize| { let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) //~^ ERROR `x` does not live long enough //~| ERROR `y` does not live long enough return f; }; // We delberately do not call `g`; this small version of the test, // after adding such a call, was (properly) rejected even when the // system still suffered from issue #29793. // g(10, 20)(true); } fn escaping_borrow_of_closure_params_2() { let g = |x: usize, y:usize| { let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) //~^ ERROR `x` does not live long enough //~| ERROR `y` does not live long enough f }; // (we don't call `g`; see above) } fn move_of_closure_params() { let g = |x: usize, y:usize| { let f = move |t: bool| if t { x } else { y }; f; }; // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) (g(1,2)); } fn ok_borrow_of_fn_params(a: usize, b:usize) { let g = |x: usize, y:usize| { let f = |t: bool| if t { a } else { b }; return f; }; // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) (g(1,2))(true); } // TOP-LEVEL FN'S fn escaping_borrow_of_fn_params_1() { fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 return Box::new(f); }; // (we don't call `g`; see above) } fn escaping_borrow_of_fn_params_2() { fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 Box::new(f) }; // (we don't call `g`; see above) } fn move_of_fn_params() { fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { let f = move |t: bool| if t { x } else { y }; return Box::new(f); }; // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) (g(1,2))(true); } // INHERENT METHODS fn escaping_borrow_of_method_params_1() { struct S; impl S { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 return Box::new(f); } } // (we don't call `g`; see above) } fn escaping_borrow_of_method_params_2() { struct S; impl S { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 Box::new(f) } } // (we don't call `g`; see above) } fn move_of_method_params() { struct S; impl S { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { let f = move |t: bool| if t { x } else { y }; return Box::new(f); } } // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) (S.g(1,2))(true); } // TRAIT IMPL METHODS fn escaping_borrow_of_trait_impl_params_1() { trait T { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a>; } struct S; impl T for S { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 return Box::new(f); } } // (we don't call `g`; see above) } fn escaping_borrow_of_trait_impl_params_2() { trait T { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a>; } struct S; impl T for S { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 Box::new(f) } } // (we don't call `g`; see above) } fn move_of_trait_impl_params() { trait T { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a>; } struct S; impl T for S { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { let f = move |t: bool| if t { x } else { y }; return Box::new(f); } } // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) (S.g(1,2))(true); } // TRAIT DEFAULT METHODS fn escaping_borrow_of_trait_default_params_1() { struct S; trait T { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 return Box::new(f); } } impl T for S {} // (we don't call `g`; see above) } fn escaping_borrow_of_trait_default_params_2() { struct S; trait T { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) //~^ ERROR E0373 //~| ERROR E0373 Box::new(f) } } impl T for S {} // (we don't call `g`; see above) } fn move_of_trait_default_params() { struct S; trait T { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { let f = move |t: bool| if t { x } else { y }; return Box::new(f); } } impl T for S {} // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) (S.g(1,2))(true); } fn main() { }