summaryrefslogtreecommitdiffstats
path: root/tests/ui/regions/region-borrow-params-issue-29793-small.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/regions/region-borrow-params-issue-29793-small.rs')
-rw-r--r--tests/ui/regions/region-borrow-params-issue-29793-small.rs212
1 files changed, 212 insertions, 0 deletions
diff --git a/tests/ui/regions/region-borrow-params-issue-29793-small.rs b/tests/ui/regions/region-borrow-params-issue-29793-small.rs
new file mode 100644
index 000000000..5f1c2ed08
--- /dev/null
+++ b/tests/ui/regions/region-borrow-params-issue-29793-small.rs
@@ -0,0 +1,212 @@
+// 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 E0373
+ //~| ERROR E0373
+ 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 E0373
+ //~| ERROR E0373
+ 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<dyn Fn(bool) -> 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<dyn Fn(bool) -> 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<dyn Fn(bool) -> 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<dyn Fn(bool) -> 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<dyn Fn(bool) -> 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<dyn Fn(bool) -> 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<dyn Fn(bool) -> usize + 'a>; }
+ struct S;
+ impl T for S {
+ fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> 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<dyn Fn(bool) -> usize + 'a>; }
+ struct S;
+ impl T for S {
+ fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> 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<dyn Fn(bool) -> usize + 'a>; }
+ struct S;
+ impl T for S {
+ fn g<'a>(&self, x: usize, y:usize) -> Box<dyn Fn(bool) -> 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<dyn Fn(bool) -> 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<dyn Fn(bool) -> 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<dyn Fn(bool) -> 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() { }