diff options
| author | bors <bors@rust-lang.org> | 2018-01-22 05:30:37 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-01-22 05:30:37 +0000 |
| commit | bc072ed0ca8e2e9f8c79fb04e85b47b5c0e8d6ae (patch) | |
| tree | 2f4b8f1a04496f95c61c20a355b7b247052f5138 /src/test | |
| parent | ff2a7c85757542f454934e00605355bbca7bc196 (diff) | |
| parent | 6f9ecaa7cf0a15db46d13d72932acb2d678c29f1 (diff) | |
Auto merge of #47144 - estebank:moved-closure-arg, r=nikomatsakis
Custom error when moving arg outside of its closure
When given the following code:
```rust
fn give_any<F: for<'r> FnOnce(&'r ())>(f: F) {
f(&());
}
fn main() {
let mut x = None;
give_any(|y| x = Some(y));
}
```
provide a custom error:
```
error: borrowed data cannot be moved outside of its closure
--> file.rs:7:27
|
6 | let mut x = None;
| ----- borrowed data cannot be moved into here...
7 | give_any(|y| x = Some(y));
| --- ^ cannot be moved outside of its closure
| |
| ...because it cannot outlive this closure
```
instead of the generic lifetime error:
```
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> file.rs:7:27
|
7 | give_any(|y| x = Some(y));
| ^
|
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 7:14...
--> file.rs:7:14
|
7 | give_any(|y| x = Some(y));
| ^^^^^^^^^^^^^^^
note: ...so that expression is assignable (expected &(), found &())
--> file.rs:7:27
|
7 | give_any(|y| x = Some(y));
| ^
note: but, the lifetime must be valid for the block suffix following statement 0 at 6:5...
--> file.rs:6:5
|
6 | / let mut x = None;
7 | | give_any(|y| x = Some(y));
8 | | }
| |_^
note: ...so that variable is valid at time of its declaration
--> file.rs:6:9
|
6 | let mut x = None;
| ^^^^^
```
Fix #45983.
Diffstat (limited to 'src/test')
12 files changed, 195 insertions, 7 deletions
diff --git a/src/test/ui/borrowck/issue-45983.rs b/src/test/ui/borrowck/issue-45983.rs new file mode 100644 index 00000000000..a6e5067195f --- /dev/null +++ b/src/test/ui/borrowck/issue-45983.rs @@ -0,0 +1,19 @@ +// Copyright 2018 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn give_any<F: for<'r> FnOnce(&'r ())>(f: F) { + f(&()); +} + +fn main() { + let x = None; + give_any(|y| x = Some(y)); + //~^ ERROR borrowed data cannot be stored outside of its closure +} diff --git a/src/test/ui/borrowck/issue-45983.stderr b/src/test/ui/borrowck/issue-45983.stderr new file mode 100644 index 00000000000..496f15c289c --- /dev/null +++ b/src/test/ui/borrowck/issue-45983.stderr @@ -0,0 +1,12 @@ +error: borrowed data cannot be stored outside of its closure + --> $DIR/issue-45983.rs:17:27 + | +16 | let x = None; + | - borrowed data cannot be stored into here... +17 | give_any(|y| x = Some(y)); + | --- ^ cannot be stored outside of its closure + | | + | ...because it cannot outlive this closure + +error: aborting due to previous error + diff --git a/src/test/compile-fail/issue-7573.rs b/src/test/ui/borrowck/issue-7573.rs index d13da1d9fd9..8f1545fa009 100644 --- a/src/test/compile-fail/issue-7573.rs +++ b/src/test/ui/borrowck/issue-7573.rs @@ -24,9 +24,14 @@ impl CrateId { } pub fn remove_package_from_database() { - let mut lines_to_use: Vec<&CrateId> = Vec::new(); //~ ERROR E0495 + let mut lines_to_use: Vec<&CrateId> = Vec::new(); + //~^ NOTE cannot infer an appropriate lifetime let push_id = |installed_id: &CrateId| { + //~^ NOTE borrowed data cannot outlive this closure + //~| NOTE ...so that variable is valid at time of its declaration lines_to_use.push(installed_id); + //~^ ERROR borrowed data cannot be stored outside of its closure + //~| NOTE cannot be stored outside of its closure }; list_database(push_id); diff --git a/src/test/ui/borrowck/issue-7573.stderr b/src/test/ui/borrowck/issue-7573.stderr new file mode 100644 index 00000000000..99b48d9276c --- /dev/null +++ b/src/test/ui/borrowck/issue-7573.stderr @@ -0,0 +1,16 @@ +error: borrowed data cannot be stored outside of its closure + --> $DIR/issue-7573.rs:32:27 + | +27 | let mut lines_to_use: Vec<&CrateId> = Vec::new(); + | - cannot infer an appropriate lifetime... +28 | //~^ NOTE cannot infer an appropriate lifetime +29 | let push_id = |installed_id: &CrateId| { + | ------- ------------------------ borrowed data cannot outlive this closure + | | + | ...so that variable is valid at time of its declaration +... +32 | lines_to_use.push(installed_id); + | ^^^^^^^^^^^^ cannot be stored outside of its closure + +error: aborting due to previous error + diff --git a/src/test/compile-fail/regions-escape-bound-fn-2.rs b/src/test/ui/borrowck/regions-escape-bound-fn-2.rs index 1329d05a0f6..1c38dee99a7 100644 --- a/src/test/compile-fail/regions-escape-bound-fn-2.rs +++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.rs @@ -16,5 +16,5 @@ fn with_int<F>(f: F) where F: FnOnce(&isize) { fn main() { let mut x = None; with_int(|y| x = Some(y)); - //~^ ERROR cannot infer + //~^ ERROR borrowed data cannot be stored outside of its closure } diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr b/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr new file mode 100644 index 00000000000..3d88f4fd52e --- /dev/null +++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr @@ -0,0 +1,12 @@ +error: borrowed data cannot be stored outside of its closure + --> $DIR/regions-escape-bound-fn-2.rs:18:27 + | +17 | let mut x = None; + | ----- borrowed data cannot be stored into here... +18 | with_int(|y| x = Some(y)); + | --- ^ cannot be stored outside of its closure + | | + | ...because it cannot outlive this closure + +error: aborting due to previous error + diff --git a/src/test/compile-fail/regions-escape-bound-fn.rs b/src/test/ui/borrowck/regions-escape-bound-fn.rs index 02e62ffddfd..c22742371ac 100644 --- a/src/test/compile-fail/regions-escape-bound-fn.rs +++ b/src/test/ui/borrowck/regions-escape-bound-fn.rs @@ -15,5 +15,6 @@ fn with_int<F>(f: F) where F: FnOnce(&isize) { fn main() { let mut x: Option<&isize> = None; - with_int(|y| x = Some(y)); //~ ERROR cannot infer + with_int(|y| x = Some(y)); + //~^ ERROR borrowed data cannot be stored outside of its closure } diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.stderr b/src/test/ui/borrowck/regions-escape-bound-fn.stderr new file mode 100644 index 00000000000..a2ad7c3f768 --- /dev/null +++ b/src/test/ui/borrowck/regions-escape-bound-fn.stderr @@ -0,0 +1,12 @@ +error: borrowed data cannot be stored outside of its closure + --> $DIR/regions-escape-bound-fn.rs:18:27 + | +17 | let mut x: Option<&isize> = None; + | ----- borrowed data cannot be stored into here... +18 | with_int(|y| x = Some(y)); + | --- ^ cannot be stored outside of its closure + | | + | ...because it cannot outlive this closure + +error: aborting due to previous error + diff --git a/src/test/compile-fail/regions-escape-unboxed-closure.rs b/src/test/ui/borrowck/regions-escape-unboxed-closure.rs index cf41fad2708..5a214504df4 100644 --- a/src/test/compile-fail/regions-escape-unboxed-closure.rs +++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.rs @@ -13,5 +13,6 @@ fn with_int(f: &mut FnMut(&isize)) { fn main() { let mut x: Option<&isize> = None; - with_int(&mut |y| x = Some(y)); //~ ERROR cannot infer + with_int(&mut |y| x = Some(y)); + //~^ ERROR borrowed data cannot be stored outside of its closure } diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr b/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr new file mode 100644 index 00000000000..4b01e42fa67 --- /dev/null +++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr @@ -0,0 +1,12 @@ +error: borrowed data cannot be stored outside of its closure + --> $DIR/regions-escape-unboxed-closure.rs:16:32 + | +15 | let mut x: Option<&isize> = None; + | ----- borrowed data cannot be stored into here... +16 | with_int(&mut |y| x = Some(y)); + | --- ^ cannot be stored outside of its closure + | | + | ...because it cannot outlive this closure + +error: aborting due to previous error + diff --git a/src/test/compile-fail/closure-expected-type/expect-region-supply-region.rs b/src/test/ui/closure-expected-type/expect-region-supply-region.rs index 9da12dc901f..a464c5853e1 100644 --- a/src/test/compile-fail/closure-expected-type/expect-region-supply-region.rs +++ b/src/test/ui/closure-expected-type/expect-region-supply-region.rs @@ -25,7 +25,7 @@ fn expect_bound_supply_nothing() { // it to escape into `f`: let mut f: Option<&u32> = None; closure_expecting_bound(|x| { - f = Some(x); //~ ERROR E0495 + f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure }); } @@ -35,7 +35,7 @@ fn expect_bound_supply_bound() { // closure: let mut f: Option<&u32> = None; closure_expecting_bound(|x: &u32| { - f = Some(x); //~ ERROR E0495 + f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure }); } @@ -50,7 +50,7 @@ fn expect_bound_supply_named<'x>() { // And we still cannot let `x` escape into `f`. f = Some(x); - //~^ ERROR cannot infer + //~^ ERROR borrowed data cannot be stored outside of its closure }); } diff --git a/src/test/ui/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr new file mode 100644 index 00000000000..ebb1e561e57 --- /dev/null +++ b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr @@ -0,0 +1,98 @@ +error: borrowed data cannot be stored outside of its closure + --> $DIR/expect-region-supply-region.rs:28:18 + | +26 | let mut f: Option<&u32> = None; + | ----- borrowed data cannot be stored into here... +27 | closure_expecting_bound(|x| { + | --- ...because it cannot outlive this closure +28 | f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure + | ^ cannot be stored outside of its closure + +error: borrowed data cannot be stored outside of its closure + --> $DIR/expect-region-supply-region.rs:38:18 + | +36 | let mut f: Option<&u32> = None; + | ----- borrowed data cannot be stored into here... +37 | closure_expecting_bound(|x: &u32| { + | --------- ...because it cannot outlive this closure +38 | f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure + | ^ cannot be stored outside of its closure + +error[E0308]: mismatched types + --> $DIR/expect-region-supply-region.rs:47:33 + | +47 | closure_expecting_bound(|x: &'x u32| { + | ^^^^^^^ lifetime mismatch + | + = note: expected type `&u32` + found type `&'x u32` +note: the anonymous lifetime #2 defined on the body at 47:29... + --> $DIR/expect-region-supply-region.rs:47:29 + | +47 | closure_expecting_bound(|x: &'x u32| { + | _____________________________^ +48 | | //~^ ERROR mismatched types +49 | | //~| ERROR mismatched types +50 | | +... | +53 | | //~^ ERROR borrowed data cannot be stored outside of its closure +54 | | }); + | |_____^ +note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 42:1 + --> $DIR/expect-region-supply-region.rs:42:1 + | +42 | / fn expect_bound_supply_named<'x>() { +43 | | let mut f: Option<&u32> = None; +44 | | +45 | | // Here we give a type annotation that `x` should be free. We get +... | +54 | | }); +55 | | } + | |_^ + +error[E0308]: mismatched types + --> $DIR/expect-region-supply-region.rs:47:33 + | +47 | closure_expecting_bound(|x: &'x u32| { + | ^^^^^^^ lifetime mismatch + | + = note: expected type `&u32` + found type `&'x u32` +note: the lifetime 'x as defined on the function body at 42:1... + --> $DIR/expect-region-supply-region.rs:42:1 + | +42 | / fn expect_bound_supply_named<'x>() { +43 | | let mut f: Option<&u32> = None; +44 | | +45 | | // Here we give a type annotation that `x` should be free. We get +... | +54 | | }); +55 | | } + | |_^ +note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 47:29 + --> $DIR/expect-region-supply-region.rs:47:29 + | +47 | closure_expecting_bound(|x: &'x u32| { + | _____________________________^ +48 | | //~^ ERROR mismatched types +49 | | //~| ERROR mismatched types +50 | | +... | +53 | | //~^ ERROR borrowed data cannot be stored outside of its closure +54 | | }); + | |_____^ + +error: borrowed data cannot be stored outside of its closure + --> $DIR/expect-region-supply-region.rs:52:18 + | +43 | let mut f: Option<&u32> = None; + | ----- borrowed data cannot be stored into here... +... +47 | closure_expecting_bound(|x: &'x u32| { + | ------------ ...because it cannot outlive this closure +... +52 | f = Some(x); + | ^ cannot be stored outside of its closure + +error: aborting due to 5 previous errors + |
