about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-01-22 05:30:37 +0000
committerbors <bors@rust-lang.org>2018-01-22 05:30:37 +0000
commitbc072ed0ca8e2e9f8c79fb04e85b47b5c0e8d6ae (patch)
tree2f4b8f1a04496f95c61c20a355b7b247052f5138 /src/test
parentff2a7c85757542f454934e00605355bbca7bc196 (diff)
parent6f9ecaa7cf0a15db46d13d72932acb2d678c29f1 (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')
-rw-r--r--src/test/ui/borrowck/issue-45983.rs19
-rw-r--r--src/test/ui/borrowck/issue-45983.stderr12
-rw-r--r--src/test/ui/borrowck/issue-7573.rs (renamed from src/test/compile-fail/issue-7573.rs)7
-rw-r--r--src/test/ui/borrowck/issue-7573.stderr16
-rw-r--r--src/test/ui/borrowck/regions-escape-bound-fn-2.rs (renamed from src/test/compile-fail/regions-escape-bound-fn-2.rs)2
-rw-r--r--src/test/ui/borrowck/regions-escape-bound-fn-2.stderr12
-rw-r--r--src/test/ui/borrowck/regions-escape-bound-fn.rs (renamed from src/test/compile-fail/regions-escape-bound-fn.rs)3
-rw-r--r--src/test/ui/borrowck/regions-escape-bound-fn.stderr12
-rw-r--r--src/test/ui/borrowck/regions-escape-unboxed-closure.rs (renamed from src/test/compile-fail/regions-escape-unboxed-closure.rs)3
-rw-r--r--src/test/ui/borrowck/regions-escape-unboxed-closure.stderr12
-rw-r--r--src/test/ui/closure-expected-type/expect-region-supply-region.rs (renamed from src/test/compile-fail/closure-expected-type/expect-region-supply-region.rs)6
-rw-r--r--src/test/ui/closure-expected-type/expect-region-supply-region.stderr98
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
+