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 414cb1d6f05c..a62e608a8758 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 = ` 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 e03d72a02f0a..2488df7772b3 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 ed70e38362da..538903c59186 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 2a82e1b8ada8..fe2fa2887ed4 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 c14cb7098933..80e2266896fa 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 58dad753ac4a..5b79b71dda0d 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 cc32eaaa9799..85eb348257bb 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 6ad57a15465d..7ba06b6ffb2d 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