about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-12-12 06:11:33 +0000
committerbors <bors@rust-lang.org>2017-12-12 06:11:33 +0000
commit724500626bcc37db1e271a3c344550fcd4238148 (patch)
treeee57719a4879db24f4eabcfbc6efcab2604cad90
parent3a0b65284686a5d984994708596d029267e7bf7b (diff)
parent3dbc11bc6322a8d337ccdf79464e547abafe7f00 (diff)
downloadrust-724500626bcc37db1e271a3c344550fcd4238148.tar.gz
rust-724500626bcc37db1e271a3c344550fcd4238148.zip
Auto merge of #46598 - davidtwco:issue-46471, r=arielb1
MIR borrowck: error message confuses locals and temporaries

Fixes #46471 and fixes #46472 (see [this Gitter comment](https://gitter.im/rust-impl-period/WG-compiler-nll?at=5a2d5cb53ae2aa6b3facf0c2)).

r? @arielb1
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs94
-rw-r--r--src/librustc_mir/borrow_check/mod.rs1
-rw-r--r--src/librustc_mir/dataflow/impls/borrows.rs2
-rw-r--r--src/test/compile-fail/borrowck/borrowck-local-borrow-outlives-fn.rs5
-rw-r--r--src/test/compile-fail/borrowck/borrowck-local-borrow-with-panic-outlives-fn.rs5
-rw-r--r--src/test/compile-fail/issue-17954.rs10
-rw-r--r--src/test/compile-fail/region-borrow-params-issue-29793-big.rs4
-rw-r--r--src/test/ui/issue-46471-1.rs21
-rw-r--r--src/test/ui/issue-46471-1.stderr24
-rw-r--r--src/test/ui/issue-46471.rs20
-rw-r--r--src/test/ui/issue-46471.stderr24
-rw-r--r--src/test/ui/issue-46472.rs19
-rw-r--r--src/test/ui/issue-46472.stderr40
-rw-r--r--src/test/ui/nll/capture-ref-in-struct.rs2
-rw-r--r--src/test/ui/nll/capture-ref-in-struct.stderr14
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument.stderr16
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-nested.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr20
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-ref.rs3
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr18
21 files changed, 297 insertions, 51 deletions
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index e4d2d7228c2..186598001da 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -9,11 +9,14 @@
 // except according to those terms.
 
 use syntax_pos::Span;
+use rustc::middle::region::ScopeTree;
 use rustc::mir::{BorrowKind, Field, Local, Location, Operand};
 use rustc::mir::{Place, ProjectionElem, Rvalue, StatementKind};
-use rustc::ty;
+use rustc::ty::{self, RegionKind};
 use rustc_data_structures::indexed_vec::Idx;
 
+use std::rc::Rc;
+
 use super::{MirBorrowckCtxt, Context};
 use super::{InitializationRequiringAction, PrefixSet};
 use dataflow::{BorrowData, Borrows, FlowAtLocation, MovingOutStatements};
@@ -324,6 +327,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         borrows: &Borrows<'cx, 'gcx, 'tcx>
     ) {
         let end_span = borrows.opt_region_end_span(&borrow.region);
+        let scope_tree = borrows.scope_tree();
         let root_place = self.prefixes(&borrow.place, PrefixSet::All).last().unwrap();
 
         match root_place {
@@ -347,21 +351,103 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 unreachable!("root_place is an unreachable???")
         };
 
+        let borrow_span = self.mir.source_info(borrow.location).span;
         let proper_span = match *root_place {
             Place::Local(local) => self.mir.local_decls[local].source_info.span,
             _ => drop_span,
         };
 
-        let mut err = self.tcx
-            .path_does_not_live_long_enough(drop_span, "borrowed value", Origin::Mir);
+        match (borrow.region, &self.describe_place(&borrow.place)) {
+            (RegionKind::ReScope(_), Some(name)) => {
+                self.report_scoped_local_value_does_not_live_long_enough(
+                    name, &scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
+            },
+            (RegionKind::ReScope(_), None) => {
+                self.report_scoped_temporary_value_does_not_live_long_enough(
+                    &scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
+            },
+            (RegionKind::ReEarlyBound(_), Some(name)) |
+            (RegionKind::ReFree(_), Some(name)) |
+            (RegionKind::ReStatic, Some(name)) |
+            (RegionKind::ReEmpty, Some(name)) |
+            (RegionKind::ReVar(_), Some(name)) => {
+                self.report_unscoped_local_value_does_not_live_long_enough(
+                    name, &scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
+            },
+            (RegionKind::ReEarlyBound(_), None) |
+            (RegionKind::ReFree(_), None) |
+            (RegionKind::ReStatic, None) |
+            (RegionKind::ReEmpty, None) |
+            (RegionKind::ReVar(_), None) => {
+                self.report_unscoped_temporary_value_does_not_live_long_enough(
+                    &scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
+            },
+            (RegionKind::ReLateBound(_, _), _) |
+            (RegionKind::ReSkolemized(_, _), _) |
+            (RegionKind::ReErased, _) => {
+                span_bug!(drop_span, "region does not make sense in this context");
+            },
+        }
+    }
+
+    fn report_scoped_local_value_does_not_live_long_enough(
+        &mut self, name: &String, _scope_tree: &Rc<ScopeTree>, _borrow: &BorrowData<'tcx>,
+        drop_span: Span, borrow_span: Span, _proper_span: Span, end_span: Option<Span>
+    ) {
+        let mut err = self.tcx.path_does_not_live_long_enough(drop_span,
+                                                              &format!("`{}`", name),
+                                                              Origin::Mir);
+        err.span_label(borrow_span, "borrow occurs here");
+        err.span_label(drop_span, format!("`{}` dropped here while still borrowed", name));
+        if let Some(end) = end_span {
+            err.span_label(end, "borrowed value needs to live until here");
+        }
+        err.emit();
+    }
+
+    fn report_scoped_temporary_value_does_not_live_long_enough(
+        &mut self, _scope_tree: &Rc<ScopeTree>, _borrow: &BorrowData<'tcx>,
+        drop_span: Span, borrow_span: Span, proper_span: Span, end_span: Option<Span>
+    ) {
+        let mut err = self.tcx.path_does_not_live_long_enough(borrow_span,
+                                                              "borrowed value",
+                                                              Origin::Mir);
         err.span_label(proper_span, "temporary value created here");
         err.span_label(drop_span, "temporary value dropped here while still borrowed");
         err.note("consider using a `let` binding to increase its lifetime");
-
         if let Some(end) = end_span {
             err.span_label(end, "temporary value needs to live until here");
         }
+        err.emit();
+    }
+
+    fn report_unscoped_local_value_does_not_live_long_enough(
+        &mut self, name: &String, scope_tree: &Rc<ScopeTree>, borrow: &BorrowData<'tcx>,
+        drop_span: Span, borrow_span: Span, _proper_span: Span, _end_span: Option<Span>
+    ) {
+        let mut err = self.tcx.path_does_not_live_long_enough(borrow_span,
+                                                              &format!("`{}`", name),
+                                                              Origin::Mir);
+        err.span_label(borrow_span, "does not live long enough");
+        err.span_label(drop_span, "borrowed value only lives until here");
+        self.tcx.note_and_explain_region(scope_tree, &mut err,
+                                         "borrowed value must be valid for ",
+                                         borrow.region, "...");
+        err.emit();
+    }
 
+    fn report_unscoped_temporary_value_does_not_live_long_enough(
+        &mut self, scope_tree: &Rc<ScopeTree>, borrow: &BorrowData<'tcx>,
+        drop_span: Span, _borrow_span: Span, proper_span: Span, _end_span: Option<Span>
+    ) {
+        let mut err = self.tcx.path_does_not_live_long_enough(proper_span,
+                                                              "borrowed value",
+                                                              Origin::Mir);
+        err.span_label(proper_span, "does not live long enough");
+        err.span_label(drop_span, "temporary value only lives until here");
+        self.tcx.note_and_explain_region(scope_tree, &mut err,
+                                         "borrowed value must be valid for ",
+                                         borrow.region, "...");
         err.emit();
     }
 
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 358f96abe72..128052e5894 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -1800,7 +1800,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
     }
 }
 
-
 impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
     // FIXME (#16118): function intended to allow the borrow checker
     // to be less precise in its handling of Box while still allowing
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index b3299b943ba..25bc702764a 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -160,6 +160,8 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
 
     pub fn borrows(&self) -> &IndexVec<BorrowIndex, BorrowData<'tcx>> { &self.borrows }
 
+    pub fn scope_tree(&self) -> &Rc<region::ScopeTree> { &self.scope_tree }
+
     pub fn location(&self, idx: BorrowIndex) -> &Location {
         &self.borrows[idx].location
     }
diff --git a/src/test/compile-fail/borrowck/borrowck-local-borrow-outlives-fn.rs b/src/test/compile-fail/borrowck/borrowck-local-borrow-outlives-fn.rs
index fa80a2efdf8..0d5feb6b9cc 100644
--- a/src/test/compile-fail/borrowck/borrowck-local-borrow-outlives-fn.rs
+++ b/src/test/compile-fail/borrowck/borrowck-local-borrow-outlives-fn.rs
@@ -12,8 +12,9 @@
 //[mir]compile-flags: -Z borrowck=mir
 
 fn cplusplus_mode(x: isize) -> &'static isize {
-    &x //[ast]~ ERROR `x` does not live long enough
+    &x
+    //[ast]~^ ERROR `x` does not live long enough [E0597]
+    //[mir]~^^ ERROR `x` does not live long enough [E0597]
 }
-//[mir]~^ ERROR borrowed value does not live long enough
 
 fn main() {}
diff --git a/src/test/compile-fail/borrowck/borrowck-local-borrow-with-panic-outlives-fn.rs b/src/test/compile-fail/borrowck/borrowck-local-borrow-with-panic-outlives-fn.rs
index 78f0d321e0d..2c9ace4825d 100644
--- a/src/test/compile-fail/borrowck/borrowck-local-borrow-with-panic-outlives-fn.rs
+++ b/src/test/compile-fail/borrowck/borrowck-local-borrow-with-panic-outlives-fn.rs
@@ -13,10 +13,11 @@
 
 fn cplusplus_mode_exceptionally_unsafe(x: &mut Option<&'static mut isize>) {
     let mut z = (0, 0);
-    *x = Some(&mut z.1); //[ast]~ ERROR [E0597]
+    *x = Some(&mut z.1);
+    //[ast]~^ ERROR `z.1` does not live long enough [E0597]
+    //[mir]~^^ ERROR `z.1` does not live long enough [E0597]
     panic!("catch me for a dangling pointer!")
 }
-//[mir]~^ ERROR [E0597]
 
 fn main() {
     cplusplus_mode_exceptionally_unsafe(&mut None);
diff --git a/src/test/compile-fail/issue-17954.rs b/src/test/compile-fail/issue-17954.rs
index 3e14525250d..4211057610b 100644
--- a/src/test/compile-fail/issue-17954.rs
+++ b/src/test/compile-fail/issue-17954.rs
@@ -18,12 +18,16 @@ static FOO: u8 = 3;
 
 fn main() {
     let a = &FOO;
-    //[ast]~^ ERROR borrowed value does not live long enough
+    //[mir]~^ ERROR `FOO` does not live long enough [E0597]
+    //[mir]~| does not live long enough
+    //[mir]~| NOTE borrowed value must be valid for the static lifetime
+    //[ast]~^^^^ ERROR borrowed value does not live long enough
     //[ast]~| does not live long enough
     //[ast]~| NOTE borrowed value must be valid for the static lifetime
 
     std::thread::spawn(move || {
         println!("{}", a);
     });
-} //[ast]~ temporary value only lives until here
-  //[mir]~^ ERROR borrowed value does not live long enough
+}
+//[mir]~^ borrowed value only lives until here
+//[ast]~^^ temporary value only lives until here
diff --git a/src/test/compile-fail/region-borrow-params-issue-29793-big.rs b/src/test/compile-fail/region-borrow-params-issue-29793-big.rs
index a4dc00bd2b1..2e2dfdb03d9 100644
--- a/src/test/compile-fail/region-borrow-params-issue-29793-big.rs
+++ b/src/test/compile-fail/region-borrow-params-issue-29793-big.rs
@@ -82,8 +82,8 @@ fn main() {
             //[ast]~^ ERROR `x` does not live long enough
             //[ast]~| ERROR `y` does not live long enough
     });
-    //[mir]~^ ERROR borrowed value does not live long enough
-    //[mir]~| ERROR borrowed value does not live long enough
+    //[mir]~^ ERROR `x` does not live long enough
+    //[mir]~| ERROR `y` does not live long enough
 
     w.handle(); // This works
     // w.handle_ref(); // This doesn't
diff --git a/src/test/ui/issue-46471-1.rs b/src/test/ui/issue-46471-1.rs
new file mode 100644
index 00000000000..977ea785fe6
--- /dev/null
+++ b/src/test/ui/issue-46471-1.rs
@@ -0,0 +1,21 @@
+// Copyright 2016 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.
+
+// compile-flags: -Z emit-end-regions -Z borrowck=compare
+
+fn main() {
+    let y = {
+        let mut z = 0;
+        &mut z
+    };
+    //~^ ERROR `z` does not live long enough (Ast) [E0597]
+    //~| ERROR `z` does not live long enough (Mir) [E0597]
+    println!("{}", y);
+}
diff --git a/src/test/ui/issue-46471-1.stderr b/src/test/ui/issue-46471-1.stderr
new file mode 100644
index 00000000000..c33b9a7ba7b
--- /dev/null
+++ b/src/test/ui/issue-46471-1.stderr
@@ -0,0 +1,24 @@
+error[E0597]: `z` does not live long enough (Ast)
+  --> $DIR/issue-46471-1.rs:17:5
+   |
+16 |         &mut z
+   |              - borrow occurs here
+17 |     };
+   |     ^ `z` dropped here while still borrowed
+...
+21 | }
+   | - borrowed value needs to live until here
+
+error[E0597]: `z` does not live long enough (Mir)
+  --> $DIR/issue-46471-1.rs:17:6
+   |
+16 |         &mut z
+   |         ------ borrow occurs here
+17 |     };
+   |      ^ `z` dropped here while still borrowed
+...
+21 | }
+   | - borrowed value needs to live until here
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/issue-46471.rs b/src/test/ui/issue-46471.rs
new file mode 100644
index 00000000000..8faedb73842
--- /dev/null
+++ b/src/test/ui/issue-46471.rs
@@ -0,0 +1,20 @@
+// Copyright 2016 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.
+
+// compile-flags: -Z emit-end-regions -Z borrowck=compare
+
+fn foo() -> &'static u32 {
+    let x = 0;
+    &x
+    //~^ ERROR `x` does not live long enough (Ast) [E0597]
+    //~| ERROR `x` does not live long enough (Mir) [E0597]
+}
+
+fn main() { }
diff --git a/src/test/ui/issue-46471.stderr b/src/test/ui/issue-46471.stderr
new file mode 100644
index 00000000000..dd361841de1
--- /dev/null
+++ b/src/test/ui/issue-46471.stderr
@@ -0,0 +1,24 @@
+error[E0597]: `x` does not live long enough (Ast)
+  --> $DIR/issue-46471.rs:15:6
+   |
+15 |     &x
+   |      ^ does not live long enough
+...
+18 | }
+   | - borrowed value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: `x` does not live long enough (Mir)
+  --> $DIR/issue-46471.rs:15:5
+   |
+15 |     &x
+   |     ^^ does not live long enough
+...
+18 | }
+   |  - borrowed value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/issue-46472.rs b/src/test/ui/issue-46472.rs
new file mode 100644
index 00000000000..02c4dd7cb21
--- /dev/null
+++ b/src/test/ui/issue-46472.rs
@@ -0,0 +1,19 @@
+// Copyright 2016 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.
+
+// compile-flags: -Z emit-end-regions -Z borrowck=compare
+
+fn bar<'a>() -> &'a mut u32 {
+    &mut 4
+    //~^ ERROR borrowed value does not live long enough (Ast) [E0597]
+    //~| ERROR borrowed value does not live long enough (Mir) [E0597]
+}
+
+fn main() { }
diff --git a/src/test/ui/issue-46472.stderr b/src/test/ui/issue-46472.stderr
new file mode 100644
index 00000000000..ab35874fbb9
--- /dev/null
+++ b/src/test/ui/issue-46472.stderr
@@ -0,0 +1,40 @@
+error[E0597]: borrowed value does not live long enough (Ast)
+  --> $DIR/issue-46472.rs:14:10
+   |
+14 |     &mut 4
+   |          ^ does not live long enough
+...
+17 | }
+   | - temporary value only lives until here
+   |
+note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:1...
+  --> $DIR/issue-46472.rs:13:1
+   |
+13 | / fn bar<'a>() -> &'a mut u32 {
+14 | |     &mut 4
+15 | |     //~^ ERROR borrowed value does not live long enough (Ast) [E0597]
+16 | |     //~| ERROR borrowed value does not live long enough (Mir) [E0597]
+17 | | }
+   | |_^
+
+error[E0597]: borrowed value does not live long enough (Mir)
+  --> $DIR/issue-46472.rs:14:10
+   |
+14 |     &mut 4
+   |          ^ does not live long enough
+...
+17 | }
+   |  - temporary value only lives until here
+   |
+note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:1...
+  --> $DIR/issue-46472.rs:13:1
+   |
+13 | / fn bar<'a>() -> &'a mut u32 {
+14 | |     &mut 4
+15 | |     //~^ ERROR borrowed value does not live long enough (Ast) [E0597]
+16 | |     //~| ERROR borrowed value does not live long enough (Mir) [E0597]
+17 | | }
+   | |_^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/nll/capture-ref-in-struct.rs b/src/test/ui/nll/capture-ref-in-struct.rs
index 00a0c94d221..5eae5d92471 100644
--- a/src/test/ui/nll/capture-ref-in-struct.rs
+++ b/src/test/ui/nll/capture-ref-in-struct.rs
@@ -30,11 +30,11 @@ fn test() {
         let closure = SomeStruct {
             p: &mut p,
             y: &y,
+            //~^ ERROR `y` does not live long enough [E0597]
         };
 
         closure.invoke();
     }
-    //~^ ERROR borrowed value does not live long enough [E0597]
 
     deref(p);
 }
diff --git a/src/test/ui/nll/capture-ref-in-struct.stderr b/src/test/ui/nll/capture-ref-in-struct.stderr
index f10e52e05f1..6b57f91987b 100644
--- a/src/test/ui/nll/capture-ref-in-struct.stderr
+++ b/src/test/ui/nll/capture-ref-in-struct.stderr
@@ -1,13 +1,13 @@
-error[E0597]: borrowed value does not live long enough
-  --> $DIR/capture-ref-in-struct.rs:36:6
+error[E0597]: `y` does not live long enough
+  --> $DIR/capture-ref-in-struct.rs:32:16
    |
-28 |         let y = 22;
-   |             - temporary value created here
+32 |             y: &y,
+   |                ^^ does not live long enough
 ...
-36 |     }
-   |      ^ temporary value dropped here while still borrowed
+37 |     }
+   |      - borrowed value only lives until here
    |
-   = note: consider using a `let` binding to increase its lifetime
+   = note: borrowed value must be valid for lifetime '_#4r...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/escape-argument.rs b/src/test/ui/nll/closure-requirements/escape-argument.rs
index 1d8a916345e..7e918c6431d 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument.rs
+++ b/src/test/ui/nll/closure-requirements/escape-argument.rs
@@ -35,8 +35,8 @@ fn test() {
         let y = 22;
         let mut closure = expect_sig(|p, y| *p = y);
         closure(&mut p, &y);
+        //~^ ERROR `y` does not live long enough [E0597]
     }
-    //~^ ERROR borrowed value does not live long enough [E0597]
 
     deref(p);
 }
diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr
index e5c7139573e..0ec671997e7 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr
@@ -24,16 +24,16 @@ note: No external requirements
    |
    = note: defining type: DefId(0/0:3 ~ escape_argument[317d]::test[0]) with substs []
 
-error[E0597]: borrowed value does not live long enough
-  --> $DIR/escape-argument.rs:38:6
+error[E0597]: `y` does not live long enough
+  --> $DIR/escape-argument.rs:37:25
    |
-35 |         let y = 22;
-   |             - temporary value created here
-...
-38 |     }
-   |      ^ temporary value dropped here while still borrowed
+37 |         closure(&mut p, &y);
+   |                         ^^ does not live long enough
+38 |         //~^ ERROR `y` does not live long enough [E0597]
+39 |     }
+   |      - borrowed value only lives until here
    |
-   = note: consider using a `let` binding to increase its lifetime
+   = note: borrowed value must be valid for lifetime '_#5r...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs b/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs
index 9f4585bfbab..05700ae00ad 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs
@@ -27,13 +27,13 @@ fn test() {
     {
         let y = 22;
 
-        let mut closure = || {
+        let mut closure = || { //~ ERROR `y` does not live long enough [E0597]
             let mut closure1 = || p = &y;
             closure1();
         };
 
         closure();
-    } //~ ERROR borrowed value does not live long enough
+    }
 
     deref(p);
 }
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
index 201590f01f3..6c70afa0c9c 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
@@ -16,7 +16,7 @@ note: External requirements
 note: External requirements
   --> $DIR/escape-upvar-nested.rs:30:27
    |
-30 |           let mut closure = || {
+30 |           let mut closure = || { //~ ERROR `y` does not live long enough [E0597]
    |  ___________________________^
 31 | |             let mut closure1 = || p = &y;
 32 | |             closure1();
@@ -46,16 +46,20 @@ note: No external requirements
    |
    = note: defining type: DefId(0/0:3 ~ escape_upvar_nested[317d]::test[0]) with substs []
 
-error[E0597]: borrowed value does not live long enough
-  --> $DIR/escape-upvar-nested.rs:36:6
+error[E0597]: `y` does not live long enough
+  --> $DIR/escape-upvar-nested.rs:30:27
    |
-28 |         let y = 22;
-   |             - temporary value created here
+30 |           let mut closure = || { //~ ERROR `y` does not live long enough [E0597]
+   |  ___________________________^
+31 | |             let mut closure1 = || p = &y;
+32 | |             closure1();
+33 | |         };
+   | |_________^ does not live long enough
 ...
-36 |     } //~ ERROR borrowed value does not live long enough
-   |      ^ temporary value dropped here while still borrowed
+36 |       }
+   |        - borrowed value only lives until here
    |
-   = note: consider using a `let` binding to increase its lifetime
+   = note: borrowed value must be valid for lifetime '_#3r...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.rs b/src/test/ui/nll/closure-requirements/escape-upvar-ref.rs
index 548a5ae5969..93d8bfafcba 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.rs
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.rs
@@ -31,8 +31,9 @@ fn test() {
     {
         let y = 22;
         let mut closure = || p = &y;
+        //~^ ERROR `y` does not live long enough [E0597]
         closure();
-    } //~ ERROR borrowed value does not live long enough
+    }
 
     deref(p);
 }
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
index 47ba66ade65..0b982dd812b 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
@@ -21,22 +21,22 @@ note: No external requirements
 29 | |     let mut p = &x;
 30 | |
 ...  |
-37 | |     deref(p);
-38 | | }
+38 | |     deref(p);
+39 | | }
    | |_^
    |
    = note: defining type: DefId(0/0:3 ~ escape_upvar_ref[317d]::test[0]) with substs []
 
-error[E0597]: borrowed value does not live long enough
-  --> $DIR/escape-upvar-ref.rs:35:6
+error[E0597]: `y` does not live long enough
+  --> $DIR/escape-upvar-ref.rs:33:27
    |
-32 |         let y = 22;
-   |             - temporary value created here
+33 |         let mut closure = || p = &y;
+   |                           ^^^^^^^^^ does not live long enough
 ...
-35 |     } //~ ERROR borrowed value does not live long enough
-   |      ^ temporary value dropped here while still borrowed
+36 |     }
+   |      - borrowed value only lives until here
    |
-   = note: consider using a `let` binding to increase its lifetime
+   = note: borrowed value must be valid for lifetime '_#3r...
 
 error: aborting due to previous error