about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-11-17 15:57:57 +0100
committerGitHub <noreply@github.com>2021-11-17 15:57:57 +0100
commitd7b86880d24ab7a7be60e6c3167142111c4d1970 (patch)
tree12bd0c80adfbd4904d23198315169ffc88472587
parent07342828c5066d6a7763535b9281b5cf021dea5c (diff)
parent130b9e9e3b058e76e43788fac67538c064fc8a97 (diff)
downloadrust-d7b86880d24ab7a7be60e6c3167142111c4d1970.tar.gz
rust-d7b86880d24ab7a7be60e6c3167142111c4d1970.zip
Rollup merge of #90667 - rukai:improve_static_lifetime_diagnostics, r=estebank
Improve diagnostics when a static lifetime is expected

Makes progress towards https://github.com/rust-lang/rust/issues/90600

The diagnostics here were previously entirely removed due to giving a misleading suggestion but if we instead provide an informative label in that same location it should better help the user understand the situation.

I included the example from the issue as it demonstrates an area where the diagnostics are still lacking.
Happy to remove that if its just adding noise atm.
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs65
-rw-r--r--src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr13
-rw-r--r--src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.rs2
-rw-r--r--src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr18
-rw-r--r--src/test/ui/generator/generator-region-requirements.nll.stderr11
-rw-r--r--src/test/ui/generator/generator-region-requirements.rs2
-rw-r--r--src/test/ui/generator/generator-region-requirements.stderr14
-rw-r--r--src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.nll.stderr26
-rw-r--r--src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs6
-rw-r--r--src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr26
-rw-r--r--src/test/ui/issues/issue-46983.nll.stderr10
-rw-r--r--src/test/ui/issues/issue-46983.rs2
-rw-r--r--src/test/ui/issues/issue-46983.stderr8
-rw-r--r--src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.nll.stderr24
-rw-r--r--src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.rs14
-rw-r--r--src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr14
-rw-r--r--src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr7
-rw-r--r--src/test/ui/nll/guarantor-issue-46974.rs2
-rw-r--r--src/test/ui/nll/guarantor-issue-46974.stderr10
-rw-r--r--src/test/ui/regions/regions-static-bound.ll.nll.stderr28
-rw-r--r--src/test/ui/regions/regions-static-bound.migrate.nll.stderr23
-rw-r--r--src/test/ui/regions/regions-static-bound.migrate.stderr29
-rw-r--r--src/test/ui/regions/regions-static-bound.nll.stderr31
-rw-r--r--src/test/ui/regions/regions-static-bound.rs12
-rw-r--r--src/test/ui/regions/regions-static-bound.stderr46
26 files changed, 269 insertions, 176 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index 0878f8550da..eb1c80ecb01 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -3,8 +3,6 @@
 use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
-use rustc_hir::intravisit::Visitor;
-use rustc_hir::FnRetTy;
 use rustc_middle::ty;
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
@@ -48,19 +46,24 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             return None; // inapplicable
         };
 
+        // Suggesting to add a `'static` lifetime to a parameter is nearly always incorrect,
+        // and can steer users down the wrong path.
+        if *named == ty::ReStatic {
+            return None;
+        }
+
         debug!("try_report_named_anon_conflict: named = {:?}", named);
         debug!("try_report_named_anon_conflict: anon_param_info = {:?}", anon_param_info);
         debug!("try_report_named_anon_conflict: region_info = {:?}", region_info);
 
-        let (param, new_ty, new_ty_span, br, is_first, scope_def_id, is_impl_item) = (
-            anon_param_info.param,
-            anon_param_info.param_ty,
-            anon_param_info.param_ty_span,
-            anon_param_info.bound_region,
-            anon_param_info.is_first,
-            region_info.def_id,
-            region_info.is_impl_item,
-        );
+        let param = anon_param_info.param;
+        let new_ty = anon_param_info.param_ty;
+        let new_ty_span = anon_param_info.param_ty_span;
+        let br = anon_param_info.bound_region;
+        let is_first = anon_param_info.is_first;
+        let scope_def_id = region_info.def_id;
+        let is_impl_item = region_info.is_impl_item;
+
         match br {
             ty::BrAnon(_) => {}
             _ => {
@@ -75,26 +78,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             return None;
         }
 
-        if let Some((_, fndecl)) = find_anon_type(self.tcx(), anon, &br) {
-            if self.is_self_anon(is_first, scope_def_id) {
-                return None;
-            }
-
-            if let FnRetTy::Return(ty) = &fndecl.output {
-                let mut v = ty::TraitObjectVisitor(vec![], self.tcx().hir());
-                v.visit_ty(ty);
-
-                debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
-                if sub == &ty::ReStatic
-                    && v.0.into_iter().any(|t| t.span.desugaring_kind().is_none())
-                {
-                    // If the failure is due to a `'static` requirement coming from a `dyn` or
-                    // `impl` Trait that *isn't* caused by `async fn` desugaring, handle this case
-                    // better in `static_impl_trait`.
-                    debug!("try_report_named_anon_conflict: impl Trait + 'static");
-                    return None;
-                }
-            }
+        if find_anon_type(self.tcx(), anon, &br).is_some()
+            && self.is_self_anon(is_first, scope_def_id)
+        {
+            return None;
         }
 
         let (error_var, span_label_var) = match param.pat.simple_ident() {
@@ -114,16 +101,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         );
 
         diag.span_label(span, format!("lifetime `{}` required", named));
-        // Suggesting `'static` is nearly always incorrect, and can steer users
-        // down the wrong path.
-        if *named != ty::ReStatic {
-            diag.span_suggestion(
-                new_ty_span,
-                &format!("add explicit lifetime `{}` to {}", named, span_label_var),
-                new_ty.to_string(),
-                Applicability::Unspecified,
-            );
-        }
+        diag.span_suggestion(
+            new_ty_span,
+            &format!("add explicit lifetime `{}` to {}", named, span_label_var),
+            new_ty.to_string(),
+            Applicability::Unspecified,
+        );
 
         Some(diag)
     }
diff --git a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr
index e7d9664ec50..af3810e91ae 100644
--- a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr
+++ b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr
@@ -1,11 +1,18 @@
-error[E0621]: explicit lifetime required in the type of `x`
+error[E0521]: borrowed data escapes outside of function
   --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:5
    |
+LL |   fn foo(x: &()) {
+   |          -  - let's call the lifetime of this reference `'1`
+   |          |
+   |          `x` is a reference that is only valid in the function body
 LL | /     bar(|| {
 LL | |
 LL | |         let _ = x;
 LL | |     })
-   | |______^ lifetime `'static` required
+   | |      ^
+   | |      |
+   | |______`x` escapes the function body here
+   |        argument requires that `'1` must outlive `'static`
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:9
@@ -31,5 +38,5 @@ LL |     bar(move || {
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0373, E0621.
+Some errors have detailed explanations: E0373, E0521.
 For more information about an error, try `rustc --explain E0373`.
diff --git a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.rs b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.rs
index 4fa5d54431c..cbdc8b7deef 100644
--- a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.rs
+++ b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.rs
@@ -3,7 +3,7 @@ fn bar<F>(blk: F) where F: FnOnce() + 'static {
 
 fn foo(x: &()) {
     bar(|| {
-        //~^ ERROR explicit lifetime required in the type of `x` [E0621]
+        //~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
         let _ = x;
     })
 }
diff --git a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr
index a9add6184f1..d761abdfc6a 100644
--- a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr
+++ b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr
@@ -1,9 +1,21 @@
-error[E0621]: explicit lifetime required in the type of `x`
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:9
+   |
+LL |   fn foo(x: &()) {
+   |             --- this data with an anonymous lifetime `'_`...
+LL |       bar(|| {
+   |  _________^
+LL | |
+LL | |         let _ = x;
+LL | |     })
+   | |_____^ ...is captured here...
+   |
+note: ...and is required to live as long as `'static` here
   --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:5
    |
 LL |     bar(|| {
-   |     ^^^ lifetime `'static` required
+   |     ^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0621`.
+For more information about this error, try `rustc --explain E0759`.
diff --git a/src/test/ui/generator/generator-region-requirements.nll.stderr b/src/test/ui/generator/generator-region-requirements.nll.stderr
new file mode 100644
index 00000000000..b4530cfda2b
--- /dev/null
+++ b/src/test/ui/generator/generator-region-requirements.nll.stderr
@@ -0,0 +1,11 @@
+error: lifetime may not live long enough
+  --> $DIR/generator-region-requirements.rs:13:51
+   |
+LL | fn dangle(x: &mut i32) -> &'static mut i32 {
+   |              - let's call the lifetime of this reference `'1`
+...
+LL |             GeneratorState::Complete(c) => return c,
+   |                                                   ^ returning this value requires that `'1` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/generator/generator-region-requirements.rs b/src/test/ui/generator/generator-region-requirements.rs
index 5f0a6bb09b7..cec68509a66 100644
--- a/src/test/ui/generator/generator-region-requirements.rs
+++ b/src/test/ui/generator/generator-region-requirements.rs
@@ -6,11 +6,11 @@ fn dangle(x: &mut i32) -> &'static mut i32 {
     let mut g = || {
         yield;
         x
+        //~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
     };
     loop {
         match Pin::new(&mut g).resume(()) {
             GeneratorState::Complete(c) => return c,
-            //~^ ERROR explicit lifetime required
             GeneratorState::Yielded(_) => (),
         }
     }
diff --git a/src/test/ui/generator/generator-region-requirements.stderr b/src/test/ui/generator/generator-region-requirements.stderr
index de90a599e76..b6b9db22426 100644
--- a/src/test/ui/generator/generator-region-requirements.stderr
+++ b/src/test/ui/generator/generator-region-requirements.stderr
@@ -1,9 +1,15 @@
-error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/generator-region-requirements.rs:12:51
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/generator-region-requirements.rs:8:9
    |
+LL | fn dangle(x: &mut i32) -> &'static mut i32 {
+   |              -------- this data with an anonymous lifetime `'_`...
+...
+LL |         x
+   |         ^ ...is captured here...
+...
 LL |             GeneratorState::Complete(c) => return c,
-   |                                                   ^ lifetime `'static` required
+   |                                                   - ...and is required to live as long as `'static` here
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0621`.
+For more information about this error, try `rustc --explain E0759`.
diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.nll.stderr b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.nll.stderr
new file mode 100644
index 00000000000..4620aa34e84
--- /dev/null
+++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.nll.stderr
@@ -0,0 +1,26 @@
+error: lifetime may not live long enough
+  --> $DIR/projection-type-lifetime-mismatch.rs:17:5
+   |
+LL | fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () {
+   |         - let's call the lifetime of this reference `'1`
+LL |     x.m()
+   |     ^^^^^ returning this value requires that `'1` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/projection-type-lifetime-mismatch.rs:22:5
+   |
+LL | fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () {
+   |                                       - let's call the lifetime of this reference `'1`
+LL |     x.m()
+   |     ^^^^^ returning this value requires that `'1` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/projection-type-lifetime-mismatch.rs:27:5
+   |
+LL | fn h(x: &()) -> &'static () {
+   |         - let's call the lifetime of this reference `'1`
+LL |     x.m()
+   |     ^^^^^ returning this value requires that `'1` must outlive `'static`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs
index bcbcfc18996..9b04fe23320 100644
--- a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs
+++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs
@@ -15,17 +15,17 @@ impl X for () {
 
 fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () {
     x.m()
-    //~^ ERROR explicit lifetime required
+    //~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
 }
 
 fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () {
     x.m()
-    //~^ ERROR explicit lifetime required
+    //~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
 }
 
 fn h(x: &()) -> &'static () {
     x.m()
-    //~^ ERROR explicit lifetime required
+    //~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
 }
 
 fn main() {
diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr
index 315bef16c5f..1ffd205652f 100644
--- a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr
+++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr
@@ -1,21 +1,27 @@
-error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/projection-type-lifetime-mismatch.rs:17:5
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/projection-type-lifetime-mismatch.rs:17:7
    |
+LL | fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () {
+   |         ------------------------------- this data with an anonymous lifetime `'_`...
 LL |     x.m()
-   |     ^^^^^ lifetime `'static` required
+   |     --^-- ...is captured and required to live as long as `'static` here
 
-error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/projection-type-lifetime-mismatch.rs:22:5
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/projection-type-lifetime-mismatch.rs:22:7
    |
+LL | fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () {
+   |                                       -- this data with an anonymous lifetime `'_`...
 LL |     x.m()
-   |     ^^^^^ lifetime `'static` required
+   |     --^-- ...is captured and required to live as long as `'static` here
 
-error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/projection-type-lifetime-mismatch.rs:27:5
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/projection-type-lifetime-mismatch.rs:27:7
    |
+LL | fn h(x: &()) -> &'static () {
+   |         --- this data with an anonymous lifetime `'_`...
 LL |     x.m()
-   |     ^^^^^ lifetime `'static` required
+   |     --^-- ...is captured and required to live as long as `'static` here
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0621`.
+For more information about this error, try `rustc --explain E0759`.
diff --git a/src/test/ui/issues/issue-46983.nll.stderr b/src/test/ui/issues/issue-46983.nll.stderr
new file mode 100644
index 00000000000..38a219bbd7b
--- /dev/null
+++ b/src/test/ui/issues/issue-46983.nll.stderr
@@ -0,0 +1,10 @@
+error: lifetime may not live long enough
+  --> $DIR/issue-46983.rs:2:5
+   |
+LL | fn foo(x: &u32) -> &'static u32 {
+   |           - let's call the lifetime of this reference `'1`
+LL |     &*x
+   |     ^^^ returning this value requires that `'1` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issues/issue-46983.rs b/src/test/ui/issues/issue-46983.rs
index c1fd7729bde..87ed8928944 100644
--- a/src/test/ui/issues/issue-46983.rs
+++ b/src/test/ui/issues/issue-46983.rs
@@ -1,6 +1,6 @@
 fn foo(x: &u32) -> &'static u32 {
     &*x
-    //~^ ERROR explicit lifetime required in the type of `x` [E0621]
+    //~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
 }
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-46983.stderr b/src/test/ui/issues/issue-46983.stderr
index d328329edad..77fb130f519 100644
--- a/src/test/ui/issues/issue-46983.stderr
+++ b/src/test/ui/issues/issue-46983.stderr
@@ -1,9 +1,11 @@
-error[E0621]: explicit lifetime required in the type of `x`
+error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> $DIR/issue-46983.rs:2:5
    |
+LL | fn foo(x: &u32) -> &'static u32 {
+   |           ---- this data with an anonymous lifetime `'_`...
 LL |     &*x
-   |     ^^^ lifetime `'static` required
+   |     ^^^ ...is captured and required to live as long as `'static` here
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0621`.
+For more information about this error, try `rustc --explain E0759`.
diff --git a/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.nll.stderr b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.nll.stderr
new file mode 100644
index 00000000000..99e1e7217b4
--- /dev/null
+++ b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.nll.stderr
@@ -0,0 +1,24 @@
+error[E0597]: `foo` does not live long enough
+  --> $DIR/issue-90600-expected-return-static-indirect.rs:7:32
+   |
+LL |     let refcell = RefCell::new(&mut foo);
+   |                                ^^^^^^^^ borrowed value does not live long enough
+LL |
+LL |     let read = &refcell as &RefCell<dyn Read>;
+   |                -------- cast requires that `foo` is borrowed for `'static`
+...
+LL | }
+   | - `foo` dropped here while still borrowed
+
+error: lifetime may not live long enough
+  --> $DIR/issue-90600-expected-return-static-indirect.rs:9:16
+   |
+LL | fn inner(mut foo: &[u8]) {
+   |                   - let's call the lifetime of this reference `'1`
+...
+LL |     let read = &refcell as &RefCell<dyn Read>;
+   |                ^^^^^^^^ cast requires that `'1` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.rs b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.rs
new file mode 100644
index 00000000000..39996bbf43b
--- /dev/null
+++ b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.rs
@@ -0,0 +1,14 @@
+use std::cell::RefCell;
+use std::io::Read;
+
+fn main() {}
+
+fn inner(mut foo: &[u8]) {
+    let refcell = RefCell::new(&mut foo);
+    //~^ ERROR `foo` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
+    let read = &refcell as &RefCell<dyn Read>;
+
+    read_thing(read);
+}
+
+fn read_thing(refcell: &RefCell<dyn Read>) {}
diff --git a/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr
new file mode 100644
index 00000000000..3f65d3af725
--- /dev/null
+++ b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr
@@ -0,0 +1,14 @@
+error[E0759]: `foo` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/issue-90600-expected-return-static-indirect.rs:7:32
+   |
+LL | fn inner(mut foo: &[u8]) {
+   |                   ----- this data with an anonymous lifetime `'_`...
+LL |     let refcell = RefCell::new(&mut foo);
+   |                                ^^^^^^^^ ...is captured here...
+...
+LL |     read_thing(read);
+   |                ---- ...and is required to live as long as `'static` here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0759`.
diff --git a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs
index ac2943fc3a5..c8f226f5238 100644
--- a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs
+++ b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs
@@ -7,7 +7,7 @@
 
 fn foo(x: &u32) -> &'static u32 {
     &*x
-        //~^ ERROR explicit lifetime required in the type of `x`
+    //~^ ERROR lifetime may not live long enough
 }
 
 fn main() { }
diff --git a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr
index 4c302d935db..7034492cee0 100644
--- a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr
+++ b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr
@@ -1,9 +1,10 @@
-error[E0621]: explicit lifetime required in the type of `x`
+error: lifetime may not live long enough
   --> $DIR/region-lbr-anon-does-not-outlive-static.rs:9:5
    |
+LL | fn foo(x: &u32) -> &'static u32 {
+   |           - let's call the lifetime of this reference `'1`
 LL |     &*x
-   |     ^^^ lifetime `ReStatic` required
+   |     ^^^ returning this value requires that `'1` must outlive `'static`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0621`.
diff --git a/src/test/ui/nll/guarantor-issue-46974.rs b/src/test/ui/nll/guarantor-issue-46974.rs
index d0af468cff6..87ed0e642e9 100644
--- a/src/test/ui/nll/guarantor-issue-46974.rs
+++ b/src/test/ui/nll/guarantor-issue-46974.rs
@@ -12,7 +12,7 @@ fn foo(s: &mut (i32,)) -> i32 {
 
 fn bar(s: &Box<(i32,)>) -> &'static i32 {
     // FIXME(#46983): error message should be better
-    &s.0 //~ ERROR explicit lifetime required in the type of `s` [E0621]
+    &s.0 //~ ERROR lifetime may not live long enough
 }
 
 fn main() {
diff --git a/src/test/ui/nll/guarantor-issue-46974.stderr b/src/test/ui/nll/guarantor-issue-46974.stderr
index eabc3105c02..8245aadf826 100644
--- a/src/test/ui/nll/guarantor-issue-46974.stderr
+++ b/src/test/ui/nll/guarantor-issue-46974.stderr
@@ -9,13 +9,15 @@ LL |     *s = (2,);
 LL |     *x
    |     -- borrow later used here
 
-error[E0621]: explicit lifetime required in the type of `s`
+error: lifetime may not live long enough
   --> $DIR/guarantor-issue-46974.rs:15:5
    |
+LL | fn bar(s: &Box<(i32,)>) -> &'static i32 {
+   |           - let's call the lifetime of this reference `'1`
+LL |     // FIXME(#46983): error message should be better
 LL |     &s.0
-   |     ^^^^ lifetime `'static` required
+   |     ^^^^ returning this value requires that `'1` must outlive `'static`
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0506, E0621.
-For more information about an error, try `rustc --explain E0506`.
+For more information about this error, try `rustc --explain E0506`.
diff --git a/src/test/ui/regions/regions-static-bound.ll.nll.stderr b/src/test/ui/regions/regions-static-bound.ll.nll.stderr
deleted file mode 100644
index d6cec03e0ff..00000000000
--- a/src/test/ui/regions/regions-static-bound.ll.nll.stderr
+++ /dev/null
@@ -1,28 +0,0 @@
-error: lifetime may not live long enough
-  --> $DIR/regions-static-bound.rs:9:5
-   |
-LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
-   |                        -- lifetime `'a` defined here
-LL |     t //[ll]~ ERROR E0312
-   |     ^ returning this value requires that `'a` must outlive `'static`
-
-error[E0621]: explicit lifetime required in the type of `u`
-  --> $DIR/regions-static-bound.rs:14:5
-   |
-LL | fn error(u: &(), v: &()) {
-   |             --- help: add explicit lifetime `'static` to the type of `u`: `&'static ()`
-LL |     static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621]
-   |     ^^^^^^^^^^^^^ lifetime `'static` required
-
-error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/regions-static-bound.rs:16:5
-   |
-LL | fn error(u: &(), v: &()) {
-   |                     --- help: add explicit lifetime `'static` to the type of `v`: `&'static ()`
-...
-LL |     static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621]
-   |     ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0621`.
diff --git a/src/test/ui/regions/regions-static-bound.migrate.nll.stderr b/src/test/ui/regions/regions-static-bound.migrate.nll.stderr
deleted file mode 100644
index a280c6f0a02..00000000000
--- a/src/test/ui/regions/regions-static-bound.migrate.nll.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error: lifetime may not live long enough
-  --> $DIR/regions-static-bound.rs:9:5
-   |
-LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
-   |                        -- lifetime `'a` defined here
-LL |     t
-   |     ^ returning this value requires that `'a` must outlive `'static`
-
-error[E0621]: explicit lifetime required in the type of `u`
-  --> $DIR/regions-static-bound.rs:14:5
-   |
-LL |     static_id(&u);
-   |     ^^^^^^^^^^^^^ lifetime `'static` required
-
-error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/regions-static-bound.rs:16:5
-   |
-LL |     static_id_indirect(&v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0621`.
diff --git a/src/test/ui/regions/regions-static-bound.migrate.stderr b/src/test/ui/regions/regions-static-bound.migrate.stderr
deleted file mode 100644
index 8f11e148220..00000000000
--- a/src/test/ui/regions/regions-static-bound.migrate.stderr
+++ /dev/null
@@ -1,29 +0,0 @@
-error[E0312]: lifetime of reference outlives lifetime of borrowed content...
-  --> $DIR/regions-static-bound.rs:9:5
-   |
-LL |     t
-   |     ^
-   |
-   = note: ...the reference is valid for the static lifetime...
-note: ...but the borrowed content is only valid for the lifetime `'a` as defined here
-  --> $DIR/regions-static-bound.rs:8:24
-   |
-LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
-   |                        ^^
-
-error[E0621]: explicit lifetime required in the type of `u`
-  --> $DIR/regions-static-bound.rs:14:5
-   |
-LL |     static_id(&u);
-   |     ^^^^^^^^^ lifetime `'static` required
-
-error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/regions-static-bound.rs:16:5
-   |
-LL |     static_id_indirect(&v);
-   |     ^^^^^^^^^^^^^^^^^^ lifetime `'static` required
-
-error: aborting due to 3 previous errors
-
-Some errors have detailed explanations: E0312, E0621.
-For more information about an error, try `rustc --explain E0312`.
diff --git a/src/test/ui/regions/regions-static-bound.nll.stderr b/src/test/ui/regions/regions-static-bound.nll.stderr
index a280c6f0a02..699638c7ef9 100644
--- a/src/test/ui/regions/regions-static-bound.nll.stderr
+++ b/src/test/ui/regions/regions-static-bound.nll.stderr
@@ -1,23 +1,38 @@
 error: lifetime may not live long enough
-  --> $DIR/regions-static-bound.rs:9:5
+  --> $DIR/regions-static-bound.rs:6:5
    |
 LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
    |                        -- lifetime `'a` defined here
 LL |     t
    |     ^ returning this value requires that `'a` must outlive `'static`
 
-error[E0621]: explicit lifetime required in the type of `u`
-  --> $DIR/regions-static-bound.rs:14:5
+error[E0521]: borrowed data escapes outside of function
+  --> $DIR/regions-static-bound.rs:10:5
    |
+LL | fn error(u: &(), v: &()) {
+   |          -  - let's call the lifetime of this reference `'1`
+   |          |
+   |          `u` is a reference that is only valid in the function body
 LL |     static_id(&u);
-   |     ^^^^^^^^^^^^^ lifetime `'static` required
+   |     ^^^^^^^^^^^^^
+   |     |
+   |     `u` escapes the function body here
+   |     argument requires that `'1` must outlive `'static`
 
-error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/regions-static-bound.rs:16:5
+error[E0521]: borrowed data escapes outside of function
+  --> $DIR/regions-static-bound.rs:11:5
    |
+LL | fn error(u: &(), v: &()) {
+   |                  -  - let's call the lifetime of this reference `'2`
+   |                  |
+   |                  `v` is a reference that is only valid in the function body
+LL |     static_id(&u);
 LL |     static_id_indirect(&v);
-   |     ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     `v` escapes the function body here
+   |     argument requires that `'2` must outlive `'static`
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0621`.
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/regions/regions-static-bound.rs b/src/test/ui/regions/regions-static-bound.rs
index 1db54881d3e..a977a8b36d0 100644
--- a/src/test/ui/regions/regions-static-bound.rs
+++ b/src/test/ui/regions/regions-static-bound.rs
@@ -1,20 +1,14 @@
-// revisions: migrate nll
-//[nll] compile-flags:-Zborrowck=mir
-
 fn static_id<'a,'b>(t: &'a ()) -> &'static ()
     where 'a: 'static { t }
 fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
     where 'a: 'b, 'b: 'static { t }
 fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
-    t //[migrate]~ ERROR E0312
-        //[nll]~^ ERROR lifetime may not live long enough
+    t //~ ERROR E0312
 }
 
 fn error(u: &(), v: &()) {
-    static_id(&u); //[migrate]~ ERROR explicit lifetime required in the type of `u` [E0621]
-    //[nll]~^ ERROR explicit lifetime required in the type of `u` [E0621]
-    static_id_indirect(&v); //[migrate]~ ERROR explicit lifetime required in the type of `v` [E0621]
-    //[nll]~^ ERROR explicit lifetime required in the type of `v` [E0621]
+    static_id(&u); //~ ERROR `u` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
+    static_id_indirect(&v); //~ ERROR `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
 }
 
 fn main() {}
diff --git a/src/test/ui/regions/regions-static-bound.stderr b/src/test/ui/regions/regions-static-bound.stderr
new file mode 100644
index 00000000000..51fe16ca9da
--- /dev/null
+++ b/src/test/ui/regions/regions-static-bound.stderr
@@ -0,0 +1,46 @@
+error[E0312]: lifetime of reference outlives lifetime of borrowed content...
+  --> $DIR/regions-static-bound.rs:6:5
+   |
+LL |     t
+   |     ^
+   |
+   = note: ...the reference is valid for the static lifetime...
+note: ...but the borrowed content is only valid for the lifetime `'a` as defined here
+  --> $DIR/regions-static-bound.rs:5:24
+   |
+LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
+   |                        ^^
+
+error[E0759]: `u` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/regions-static-bound.rs:10:5
+   |
+LL | fn error(u: &(), v: &()) {
+   |             --- this data with an anonymous lifetime `'_`...
+LL |     static_id(&u);
+   |     ^^^^^^^^^ -- ...is captured here...
+   |
+note: ...and is required to live as long as `'static` here
+  --> $DIR/regions-static-bound.rs:10:5
+   |
+LL |     static_id(&u);
+   |     ^^^^^^^^^
+
+error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/regions-static-bound.rs:11:5
+   |
+LL | fn error(u: &(), v: &()) {
+   |                     --- this data with an anonymous lifetime `'_`...
+LL |     static_id(&u);
+LL |     static_id_indirect(&v);
+   |     ^^^^^^^^^^^^^^^^^^ -- ...is captured here...
+   |
+note: ...and is required to live as long as `'static` here
+  --> $DIR/regions-static-bound.rs:11:5
+   |
+LL |     static_id_indirect(&v);
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0312, E0759.
+For more information about an error, try `rustc --explain E0312`.