2015-12-10 18:30:37 +00:00
|
|
|
// 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`)
|
2019-04-22 07:40:08 +00:00
|
|
|
//~^ ERROR E0373
|
|
|
|
//~| ERROR E0373
|
2015-12-10 18:30:37 +00:00
|
|
|
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`)
|
2019-04-22 07:40:08 +00:00
|
|
|
//~^ ERROR E0373
|
|
|
|
//~| ERROR E0373
|
2015-12-10 18:30:37 +00:00
|
|
|
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() {
|
2019-05-28 18:46:13 +00:00
|
|
|
fn g<'a>(x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a> {
|
2015-12-10 18:30:37 +00:00
|
|
|
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() {
|
2019-05-28 18:46:13 +00:00
|
|
|
fn g<'a>(x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a> {
|
2015-12-10 18:30:37 +00:00
|
|
|
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() {
|
2019-05-28 18:46:13 +00:00
|
|
|
fn g<'a>(x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a> {
|
2015-12-10 18:30:37 +00:00
|
|
|
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 {
|
2019-05-28 18:46:13 +00:00
|
|
|
fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a> {
|
2015-12-10 18:30:37 +00:00
|
|
|
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 {
|
2019-05-28 18:46:13 +00:00
|
|
|
fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a> {
|
2015-12-10 18:30:37 +00:00
|
|
|
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 {
|
2019-05-28 18:46:13 +00:00
|
|
|
fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a> {
|
2015-12-10 18:30:37 +00:00
|
|
|
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() {
|
2019-05-28 18:46:13 +00:00
|
|
|
trait T { fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a>; }
|
2015-12-10 18:30:37 +00:00
|
|
|
struct S;
|
|
|
|
impl T for S {
|
2019-05-28 18:46:13 +00:00
|
|
|
fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a> {
|
2015-12-10 18:30:37 +00:00
|
|
|
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() {
|
2019-05-28 18:46:13 +00:00
|
|
|
trait T { fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a>; }
|
2015-12-10 18:30:37 +00:00
|
|
|
struct S;
|
|
|
|
impl T for S {
|
2019-05-28 18:46:13 +00:00
|
|
|
fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a> {
|
2015-12-10 18:30:37 +00:00
|
|
|
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() {
|
2019-05-28 18:46:13 +00:00
|
|
|
trait T { fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a>; }
|
2015-12-10 18:30:37 +00:00
|
|
|
struct S;
|
|
|
|
impl T for S {
|
2019-05-28 18:46:13 +00:00
|
|
|
fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a> {
|
2015-12-10 18:30:37 +00:00
|
|
|
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 {
|
2019-05-28 18:46:13 +00:00
|
|
|
fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a> {
|
2015-12-10 18:30:37 +00:00
|
|
|
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 {
|
2019-05-28 18:46:13 +00:00
|
|
|
fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a> {
|
2015-12-10 18:30:37 +00:00
|
|
|
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 {
|
2019-05-28 18:46:13 +00:00
|
|
|
fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> usize + 'a> {
|
2015-12-10 18:30:37 +00:00
|
|
|
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() { }
|