about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRemy Rakic <remy.rakic@gmail.com>2018-09-13 17:07:34 +0200
committerRemy Rakic <remy.rakic@gmail.com>2018-09-18 14:36:37 +0200
commitab236dfc86269e3f862c4a1ba6411ae34ee2fb64 (patch)
tree664df774c323b342656a49d98e361d7fd1cc2264
parentf5e310530a96ee1dc443e08c62e5a60e14234306 (diff)
downloadrust-ab236dfc86269e3f862c4a1ba6411ae34ee2fb64.tar.gz
rust-ab236dfc86269e3f862c4a1ba6411ae34ee2fb64.zip
Update NLL 3-point error message for fake reads in optimized let patterns
-rw-r--r--src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs28
-rw-r--r--src/test/ui/generator/borrowing.nll.stderr5
-rw-r--r--src/test/ui/regions/regions-steal-closure.nll.stderr5
-rw-r--r--src/test/ui/span/range-2.nll.stderr12
-rw-r--r--src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr12
-rw-r--r--src/test/ui/span/send-is-not-static-std-sync-2.nll.stderr12
-rw-r--r--src/test/ui/span/wf-method-late-bound-regions.nll.stderr6
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-region.nll.stderr5
8 files changed, 56 insertions, 29 deletions
diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
index 414cb1d6f05..a62e608a875 100644
--- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
@@ -11,7 +11,7 @@
 use borrow_check::borrow_set::BorrowData;
 use borrow_check::nll::region_infer::Cause;
 use borrow_check::{Context, MirBorrowckCtxt, WriteKind};
-use rustc::mir::{Local, Location, Place, TerminatorKind};
+use rustc::mir::{FakeReadCause, Local, Location, Place, StatementKind, TerminatorKind};
 use rustc_errors::DiagnosticBuilder;
 use rustc::ty::Region;
 
@@ -142,7 +142,31 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     if spans.for_closure() {
                         "borrow later captured here by closure"
                     } else {
-                        "borrow later used here"
+                        // Check if the location represents a `FakeRead`, and adapt the error
+                        // message to the `FakeReadCause` it is from: in particular,
+                        // the ones inserted in optimized `let var = <expr>` patterns.
+                        let is_fake_read_for_let = match self.mir.basic_blocks()[location.block]
+                            .statements
+                            .get(location.statement_index)
+                        {
+                            None => false,
+                            Some(stmt) => {
+                                if let StatementKind::FakeRead(ref cause, _) = stmt.kind {
+                                    match cause {
+                                        FakeReadCause::ForLet => true,
+                                        _ => false,
+                                    }
+                                } else {
+                                    false
+                                }
+                            }
+                        };
+
+                        if is_fake_read_for_let {
+                            "borrow later stored here"
+                        } else {
+                            "borrow later used here"
+                        }
                     }
                 };
                 err.span_label(spans.var_or_use(), message);
diff --git a/src/test/ui/generator/borrowing.nll.stderr b/src/test/ui/generator/borrowing.nll.stderr
index e03d72a02f0..2488df7772b 100644
--- a/src/test/ui/generator/borrowing.nll.stderr
+++ b/src/test/ui/generator/borrowing.nll.stderr
@@ -10,6 +10,9 @@ LL |     };
 error[E0597]: `a` does not live long enough
   --> $DIR/borrowing.rs:24:9
    |
+LL |       let _b = {
+   |           -- borrow later stored here
+LL |           let a = 3;
 LL | /         || {
 LL | |             yield &a
 LL | |             //~^ ERROR: `a` does not live long enough
@@ -17,8 +20,6 @@ LL | |         }
    | |_________^ borrowed value does not live long enough
 LL |       };
    |       - `a` dropped here while still borrowed
-LL |   }
-   |   - borrow later used here, when `_b` is dropped
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/regions/regions-steal-closure.nll.stderr b/src/test/ui/regions/regions-steal-closure.nll.stderr
index ed70e38362d..538903c5918 100644
--- a/src/test/ui/regions/regions-steal-closure.nll.stderr
+++ b/src/test/ui/regions/regions-steal-closure.nll.stderr
@@ -1,14 +1,15 @@
 error[E0597]: `i` does not live long enough
   --> $DIR/regions-steal-closure.rs:24:28
    |
+LL |     let mut cl_box = {
+   |         ---------- borrow later stored here
+LL |         let mut i = 3;
 LL |         box_it(Box::new(|| i += 1)) //~ ERROR `i` does not live long enough
    |                         -- ^ borrowed value does not live long enough
    |                         |
    |                         value captured here
 LL |     };
    |     - `i` dropped here while still borrowed
-LL |     cl_box.cl.call_mut(());
-   |     --------- borrow later used here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/range-2.nll.stderr b/src/test/ui/span/range-2.nll.stderr
index 2a82e1b8ada..fe2fa2887ed 100644
--- a/src/test/ui/span/range-2.nll.stderr
+++ b/src/test/ui/span/range-2.nll.stderr
@@ -1,24 +1,24 @@
 error[E0597]: `a` does not live long enough
   --> $DIR/range-2.rs:17:9
    |
+LL |     let r = {
+   |         - borrow later stored here
+...
 LL |         &a..&b
    |         ^^ borrowed value does not live long enough
 LL |     };
    |     - `a` dropped here while still borrowed
-...
-LL |     r.use_ref();
-   |     - borrow later used here
 
 error[E0597]: `b` does not live long enough
   --> $DIR/range-2.rs:17:13
    |
+LL |     let r = {
+   |         - borrow later stored here
+...
 LL |         &a..&b
    |             ^^ borrowed value does not live long enough
 LL |     };
    |     - `b` dropped here while still borrowed
-...
-LL |     r.use_ref();
-   |     - borrow later used here
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr b/src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr
index c14cb709893..80e2266896f 100644
--- a/src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr
+++ b/src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr
@@ -1,18 +1,21 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/send-is-not-static-ensures-scoping.rs:26:17
    |
+LL |     let bad = {
+   |         --- borrow later stored here
+LL |         let x = 1;
 LL |         let y = &x;
    |                 ^^ borrowed value does not live long enough
 ...
 LL |     };
    |     - `x` dropped here while still borrowed
-LL | 
-LL |     bad.join();
-   |     --- borrow later used here
 
 error[E0597]: `y` does not live long enough
   --> $DIR/send-is-not-static-ensures-scoping.rs:30:22
    |
+LL |     let bad = {
+   |         --- borrow later stored here
+...
 LL |         scoped(|| {
    |                -- value captured here
 LL |             let _z = y;
@@ -20,9 +23,6 @@ LL |             let _z = y;
 ...
 LL |     };
    |     - `y` dropped here while still borrowed
-LL | 
-LL |     bad.join();
-   |     --- borrow later used here
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/span/send-is-not-static-std-sync-2.nll.stderr b/src/test/ui/span/send-is-not-static-std-sync-2.nll.stderr
index 58dad753ac4..5b79b71dda0 100644
--- a/src/test/ui/span/send-is-not-static-std-sync-2.nll.stderr
+++ b/src/test/ui/span/send-is-not-static-std-sync-2.nll.stderr
@@ -1,24 +1,24 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/send-is-not-static-std-sync-2.rs:21:20
    |
+LL |     let lock = {
+   |         ---- borrow later stored here
+LL |         let x = 1;
 LL |         Mutex::new(&x)
    |                    ^^ borrowed value does not live long enough
 LL |     };
    |     - `x` dropped here while still borrowed
-...
-LL |     let _dangling = *lock.lock().unwrap();
-   |                      ---- borrow later used here
 
 error[E0597]: `x` does not live long enough
   --> $DIR/send-is-not-static-std-sync-2.rs:31:21
    |
+LL |     let lock = {
+   |         ---- borrow later stored here
+LL |         let x = 1;
 LL |         RwLock::new(&x)
    |                     ^^ borrowed value does not live long enough
 LL |     };
    |     - `x` dropped here while still borrowed
-LL |     //~^^ ERROR `x` does not live long enough
-LL |     let _dangling = *lock.read().unwrap();
-   |                      ---- borrow later used here
 
 error[E0597]: `x` does not live long enough
   --> $DIR/send-is-not-static-std-sync-2.rs:41:25
diff --git a/src/test/ui/span/wf-method-late-bound-regions.nll.stderr b/src/test/ui/span/wf-method-late-bound-regions.nll.stderr
index cc32eaaa979..85eb348257b 100644
--- a/src/test/ui/span/wf-method-late-bound-regions.nll.stderr
+++ b/src/test/ui/span/wf-method-late-bound-regions.nll.stderr
@@ -1,13 +1,13 @@
 error[E0597]: `pointer` does not live long enough
   --> $DIR/wf-method-late-bound-regions.rs:30:18
    |
+LL |     let dangling = {
+   |         -------- borrow later stored here
+LL |         let pointer = Box::new(42);
 LL |         f2.xmute(&pointer)
    |                  ^^^^^^^^ borrowed value does not live long enough
 LL |     };
    |     - `pointer` dropped here while still borrowed
-LL |     //~^^ ERROR `pointer` does not live long enough
-LL |     println!("{}", dangling);
-   |                    -------- borrow later used here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-region.nll.stderr b/src/test/ui/unboxed-closures/unboxed-closure-region.nll.stderr
index 6ad57a15465..7ba06b6ffb2 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-region.nll.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-region.nll.stderr
@@ -1,14 +1,15 @@
 error[E0597]: `x` does not live long enough
   --> $DIR/unboxed-closure-region.rs:18:12
    |
+LL |     let _f = {
+   |         -- borrow later stored here
+LL |         let x = 0;
 LL |         || x //~ ERROR `x` does not live long enough
    |         -- ^ borrowed value does not live long enough
    |         |
    |         value captured here
 LL |     };
    |     - `x` dropped here while still borrowed
-LL |     _f;
-   |     -- borrow later used here
 
 error: aborting due to previous error