about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-05-29 18:05:20 -0700
committerEsteban Küber <esteban@kuber.com.ar>2020-06-15 09:06:57 -0700
commit4e90f177cc530371a314f51f522a4c2e70885e03 (patch)
tree5ffac59684f3b131f6a7539fae7341144d44f963
parent81c909488eebcba16610402349563380772e0d1d (diff)
downloadrust-4e90f177cc530371a314f51f522a4c2e70885e03.tar.gz
rust-4e90f177cc530371a314f51f522a4c2e70885e03.zip
When `'static` is explicit, suggest constraining argument with it
-rw-r--r--src/librustc_infer/infer/error_reporting/mod.rs3
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs115
-rw-r--r--src/librustc_middle/ty/diagnostics.rs5
-rw-r--r--src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs2
-rw-r--r--src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr75
-rw-r--r--src/test/ui/issues/issue-16922.stderr2
-rw-r--r--src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr2
-rw-r--r--src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr19
-rw-r--r--src/test/ui/regions/region-object-lifetime-in-coercion.rs5
-rw-r--r--src/test/ui/regions/region-object-lifetime-in-coercion.stderr61
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-2.stderr32
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-4.stderr32
-rw-r--r--src/test/ui/regions/regions-proc-bound-capture.nll.stderr11
-rw-r--r--src/test/ui/regions/regions-proc-bound-capture.rs4
-rw-r--r--src/test/ui/regions/regions-proc-bound-capture.stderr25
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr2
16 files changed, 237 insertions, 158 deletions
diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs
index 12f7a9c0ca5..9cfa11dd7c8 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/mod.rs
@@ -2035,8 +2035,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             self.tcx.sess,
             var_origin.span(),
             E0495,
-            "cannot infer an appropriate lifetime{} \
-             due to conflicting requirements",
+            "cannot infer an appropriate lifetime{} due to conflicting requirements",
             var_description
         )
     }
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 88d6c23d514..e24535bba5f 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -10,6 +10,7 @@ use rustc_middle::ty::RegionKind;
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// Print the error message for lifetime errors when the return type is a static impl Trait.
     pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
+        debug!("try_report_static_impl_trait(error={:?})", self.error);
         if let Some(ref error) = self.error {
             if let RegionResolutionError::SubSupConflict(
                 _,
@@ -18,19 +19,24 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                 sub_r,
                 sup_origin,
                 sup_r,
-            ) = error.clone()
+            ) = error
             {
+                debug!(
+                    "try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})",
+                    var_origin, sub_origin, sub_r, sup_origin, sup_r
+                );
                 let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?;
+                debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup);
                 let fn_return = self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?;
-                let is_dyn = matches!(fn_return.kind, TyKind::TraitObject(..));
-                let fn_return_span = fn_return.span;
-                if sub_r == &RegionKind::ReStatic {
+                debug!("try_report_static_impl_trait: fn_return={:?}", fn_return);
+                if **sub_r == RegionKind::ReStatic {
                     let sp = var_origin.span();
                     let return_sp = sub_origin.span();
+                    let param_info = self.find_param_with_region(sup_r, sub_r)?;
                     let mut err =
                         self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime");
-                    let param_info = self.find_param_with_region(sup_r, sub_r)?;
                     err.span_label(param_info.param_ty_span, "data with this lifetime...");
+                    debug!("try_report_static_impl_trait: param_info={:?}", param_info);
 
                     // We try to make the output have fewer overlapping spans if possible.
                     if (sp == sup_origin.span() || !return_sp.overlaps(sup_origin.span()))
@@ -60,14 +66,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                         if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() };
                     // only apply this suggestion onto functions with
                     // explicit non-desugar'able return.
-                    if fn_return_span.desugaring_kind().is_none() {
-                        let msg = format!(
-                            "to permit non-static references in {} `{} Trait` value, you can add \
-                             an explicit bound for {}",
-                            if is_dyn { "a" } else { "an" },
-                            if is_dyn { "dyn" } else { "impl" },
-                            lifetime,
-                        );
+                    if fn_return.span.desugaring_kind().is_none() {
                         // FIXME: account for the need of parens in `&(dyn Trait + '_)`
                         match fn_return.kind {
                             TyKind::Def(item_id, _) => {
@@ -78,7 +77,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                                     err.emit();
                                     return Some(ErrorReported);
                                 };
-                                let (span, sugg) = opaque
+
+                                if let Some(span) = opaque
                                     .bounds
                                     .iter()
                                     .filter_map(|arg| match arg {
@@ -86,38 +86,71 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                                             name: LifetimeName::Static,
                                             span,
                                             ..
-                                        }) => Some((*span, lifetime_name.clone())),
+                                        }) => Some(*span),
                                         _ => None,
                                     })
                                     .next()
-                                    .unwrap_or_else(|| {
-                                        (
-                                            fn_return_span.shrink_to_hi(),
-                                            format!(" + {}", lifetime_name),
-                                        )
-                                    });
-
-                                err.span_suggestion_verbose(
-                                    span,
-                                    &msg,
-                                    sugg,
-                                    Applicability::MaybeIncorrect,
-                                );
-                            }
-                            TyKind::TraitObject(_, lt) => {
-                                let (span, sugg) = match lt.name {
-                                    LifetimeName::ImplicitObjectLifetimeDefault => (
-                                        fn_return_span.shrink_to_hi(),
+                                {
+                                    err.span_suggestion_verbose(
+                                        span,
+                                        "consider changing the `impl Trait`'s explicit \
+                                         `'static` bound",
+                                        lifetime_name,
+                                        Applicability::MaybeIncorrect,
+                                    );
+                                    err.span_suggestion_verbose(
+                                        param_info.param_ty_span,
+                                        "alternatively, set an explicit `'static` lifetime to \
+                                         this parameter",
+                                        param_info.param_ty.to_string(),
+                                        Applicability::MaybeIncorrect,
+                                    );
+                                } else {
+                                    err.span_suggestion_verbose(
+                                        fn_return.span.shrink_to_hi(),
+                                        &format!(
+                                            "to permit non-static references in an `impl Trait` \
+                                             value, you can add an explicit bound for {}",
+                                            lifetime,
+                                        ),
                                         format!(" + {}", lifetime_name),
-                                    ),
-                                    _ => (lt.span, lifetime_name),
+                                        Applicability::MaybeIncorrect,
+                                    );
                                 };
-                                err.span_suggestion_verbose(
-                                    span,
-                                    &msg,
-                                    sugg,
-                                    Applicability::MaybeIncorrect,
-                                );
+                            }
+                            TyKind::TraitObject(_, lt) => {
+                                match lt.name {
+                                    LifetimeName::ImplicitObjectLifetimeDefault => {
+                                        err.span_suggestion_verbose(
+                                            fn_return.span.shrink_to_hi(),
+                                            &format!(
+                                                "to permit non-static references in a trait object \
+                                                 value, you can add an explicit bound for {}",
+                                                lifetime,
+                                            ),
+                                            format!(" + {}", lifetime_name),
+                                            Applicability::MaybeIncorrect,
+                                        );
+                                    }
+                                    _ => {
+                                        err.span_suggestion_verbose(
+                                            lt.span,
+                                            "consider changing the trait object's explicit \
+                                             `'static` bound",
+                                            lifetime_name,
+                                            Applicability::MaybeIncorrect,
+                                        );
+                                        err.span_suggestion_verbose(
+                                            param_info.param_ty_span,
+                                            &format!(
+                                                "alternatively, set an explicit `'static` lifetime \
+                                                 in this parameter",
+                                            ),
+                                            param_info.param_ty.to_string(),
+                                            Applicability::MaybeIncorrect,
+                                        );
+                                    }
+                                }
                             }
                             _ => {}
                         }
diff --git a/src/librustc_middle/ty/diagnostics.rs b/src/librustc_middle/ty/diagnostics.rs
index 3ca506fe0d5..a2812e117ed 100644
--- a/src/librustc_middle/ty/diagnostics.rs
+++ b/src/librustc_middle/ty/diagnostics.rs
@@ -247,7 +247,10 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
     fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
         if let hir::TyKind::TraitObject(
             _,
-            hir::Lifetime { name: hir::LifetimeName::ImplicitObjectLifetimeDefault, .. },
+            hir::Lifetime {
+                name: hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static,
+                ..
+            },
         ) = ty.kind
         {
             self.0.push(ty);
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
index beafe925820..837244b0227 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
@@ -22,7 +22,7 @@ fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
 //~^ ERROR cannot infer an appropriate lifetime
 
 fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
-//~^ ERROR explicit lifetime required in the type of `x`
+//~^ ERROR cannot infer an appropriate lifetime
 
 fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
 //~^ ERROR cannot infer an appropriate lifetime
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
index 525e271bea9..96d4a121c16 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -35,10 +35,14 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
    |               |        ...is required to be `'static` by this...
    |               data with this lifetime...
    |
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 9:1
+help: consider changing the `impl Trait`'s explicit `'static` bound
    |
 LL | fn elided2(x: &i32) -> impl Copy + '_ { x }
    |                                    ^^
+help: alternatively, set an explicit `'static` lifetime to this parameter
+   |
+LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x }
+   |               ^^^^^^^^^^^^
 
 error: cannot infer an appropriate lifetime
   --> $DIR/must_outlive_least_region_or_bound.rs:12:55
@@ -49,10 +53,14 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
    |                     |           ...is required to be `'static` by this...
    |                     data with this lifetime...
    |
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:14
+help: consider changing the `impl Trait`'s explicit `'static` bound
    |
 LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x }
    |                                             ^^
+help: alternatively, set an explicit `'static` lifetime to this parameter
+   |
+LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x }
+   |                     ^^^^^^^^^^^^
 
 error[E0621]: explicit lifetime required in the type of `x`
   --> $DIR/must_outlive_least_region_or_bound.rs:15:24
@@ -71,10 +79,14 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
    |                      |           ...is required to be `'static` by this...
    |                      data with this lifetime...
    |
-help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 33:15
+help: consider changing the `impl Trait`'s explicit `'static` bound
    |
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x }
    |                                                           ^^
+help: alternatively, set an explicit `'static` lifetime to this parameter
+   |
+LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x }
+   |                      ^^^^^^^^^^^^
 
 error[E0623]: lifetime mismatch
   --> $DIR/must_outlive_least_region_or_bound.rs:38:61
@@ -103,7 +115,7 @@ LL | fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
    |               |                         ...is required to be `'static` by this...
    |               data with this lifetime...
    |
-help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 18:1
    |
 LL | fn elided3(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) }
    |                                      ^^^^
@@ -118,47 +130,48 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
    |                     |                            ...is required to be `'static` by this...
    |                     data with this lifetime...
    |
-help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14
+help: to permit non-static references in a trait object value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 21:14
    |
 LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) }
    |                                               ^^^^
 
-error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/must_outlive_least_region_or_bound.rs:24:51
+error: cannot infer an appropriate lifetime
+  --> $DIR/must_outlive_least_region_or_bound.rs:24:60
    |
 LL | fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
-   |               ----                                ^^^^^^^^^^^ lifetime `'static` required
-   |               |
-   |               help: add explicit lifetime `'static` to the type of `x`: `&'static i32`
-
-error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
-  --> $DIR/must_outlive_least_region_or_bound.rs:27:69
+   |               ----                                ---------^-
+   |               |                                   |        |
+   |               |                                   |        ...and is captured here
+   |               data with this lifetime...          ...is required to be `'static` by this...
    |
-LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
-   |                                                                     ^
+help: consider changing the trait object's explicit `'static` bound
    |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 27:14...
-  --> $DIR/must_outlive_least_region_or_bound.rs:27:14
+LL | fn elided4(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) }
+   |                                        ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
    |
-LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
-   |              ^^
-note: ...so that the expression is assignable
+LL | fn elided4(x: &'static i32) -> Box<dyn Debug + 'static> { Box::new(x) }
+   |               ^^^^^^^^^^^^
+
+error: cannot infer an appropriate lifetime
   --> $DIR/must_outlive_least_region_or_bound.rs:27:69
    |
 LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
-   |                                                                     ^
-   = note: expected  `&i32`
-              found  `&'a i32`
-   = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that the expression is assignable
-  --> $DIR/must_outlive_least_region_or_bound.rs:27:60
+   |                     -------                                ---------^-
+   |                     |                                      |        |
+   |                     |                                      |        ...and is captured here
+   |                     data with this lifetime...             ...is required to be `'static` by this...
    |
-LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
-   |                                                            ^^^^^^^^^^^
-   = note: expected  `std::boxed::Box<(dyn std::fmt::Debug + 'static)>`
-              found  `std::boxed::Box<dyn std::fmt::Debug>`
+help: consider changing the trait object's explicit `'static` bound
+   |
+LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) }
+   |                                                 ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
+   |
+LL | fn explicit4<'a>(x: &'static i32) -> Box<dyn Debug + 'static> { Box::new(x) }
+   |                     ^^^^^^^^^^^^
 
 error: aborting due to 12 previous errors
 
-Some errors have detailed explanations: E0310, E0495, E0621, E0623.
+Some errors have detailed explanations: E0310, E0621, E0623.
 For more information about an error, try `rustc --explain E0310`.
diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr
index 02d33aae023..038df47e1bd 100644
--- a/src/test/ui/issues/issue-16922.stderr
+++ b/src/test/ui/issues/issue-16922.stderr
@@ -9,7 +9,7 @@ LL |     Box::new(value) as Box<dyn Any>
    |     |        ...and is captured here
    |     ...is required to be `'static` by this...
    |
-help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1
    |
 LL | fn foo<T: Any>(value: &T) -> Box<dyn Any + '_> {
    |                                          ^^^^
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
index 70a9bf22b8d..555622c9d13 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
@@ -7,7 +7,7 @@ LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
 LL |     ss.r
    |     ^^^^ ...is captured and required to be `'static` here
    |
-help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1
    |
 LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait + '_> {
    |                                                   ^^^^
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
index bf02ba8eb91..7e8f78067e0 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
@@ -1,21 +1,21 @@
-error[E0621]: explicit lifetime required in the type of `v`
+error: lifetime may not live long enough
   --> $DIR/region-object-lifetime-in-coercion.rs:8:12
    |
 LL | fn a(v: &[u8]) -> Box<dyn Foo + 'static> {
-   |         ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+   |         - let's call the lifetime of this reference `'1`
 LL |     let x: Box<dyn Foo + 'static> = Box::new(v);
-   |            ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
+   |            ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
 
-error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/region-object-lifetime-in-coercion.rs:14:5
+error: lifetime may not live long enough
+  --> $DIR/region-object-lifetime-in-coercion.rs:13:5
    |
 LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
-   |         ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+   |         - let's call the lifetime of this reference `'1`
 LL |     Box::new(v)
-   |     ^^^^^^^^^^^ lifetime `'static` required
+   |     ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/region-object-lifetime-in-coercion.rs:20:5
+  --> $DIR/region-object-lifetime-in-coercion.rs:19:5
    |
 LL | fn c(v: &[u8]) -> Box<dyn Foo> {
    |         - let's call the lifetime of this reference `'1`
@@ -24,7 +24,7 @@ LL |     Box::new(v)
    |     ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/region-object-lifetime-in-coercion.rs:24:5
+  --> $DIR/region-object-lifetime-in-coercion.rs:23:5
    |
 LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
    |      -- -- lifetime `'b` defined here
@@ -37,4 +37,3 @@ LL |     Box::new(v)
 
 error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0621`.
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.rs b/src/test/ui/regions/region-object-lifetime-in-coercion.rs
index d56eaf77b66..5d199149c39 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.rs
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.rs
@@ -5,13 +5,12 @@ trait Foo {}
 impl<'a> Foo for &'a [u8] {}
 
 fn a(v: &[u8]) -> Box<dyn Foo + 'static> {
-    let x: Box<dyn Foo + 'static> = Box::new(v);
-    //~^ ERROR explicit lifetime required in the type of `v` [E0621]
+    let x: Box<dyn Foo + 'static> = Box::new(v); //~ ERROR cannot infer an appropriate lifetime
     x
 }
 
 fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
-    Box::new(v) //~ ERROR explicit lifetime required in the type of `v` [E0621]
+    Box::new(v) //~ ERROR cannot infer an appropriate lifetime
 }
 
 fn c(v: &[u8]) -> Box<dyn Foo> {
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
index 1462af44cb1..673300cebc2 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
@@ -1,21 +1,45 @@
-error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/region-object-lifetime-in-coercion.rs:8:37
+error: cannot infer an appropriate lifetime
+  --> $DIR/region-object-lifetime-in-coercion.rs:8:46
    |
 LL | fn a(v: &[u8]) -> Box<dyn Foo + 'static> {
-   |         ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+   |         ----- data with this lifetime...
 LL |     let x: Box<dyn Foo + 'static> = Box::new(v);
-   |                                     ^^^^^^^^^^^ lifetime `'static` required
+   |                                     ---------^-
+   |                                     |        |
+   |                                     |        ...and is captured here
+   |                                     ...is required to be `'static` by this...
+   |
+help: consider changing the trait object's explicit `'static` bound
+   |
+LL | fn a(v: &[u8]) -> Box<dyn Foo + '_> {
+   |                                 ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
+   |
+LL | fn a(v: &'static [u8]) -> Box<dyn Foo + 'static> {
+   |         ^^^^^^^^^^^^^
 
-error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/region-object-lifetime-in-coercion.rs:14:5
+error: cannot infer an appropriate lifetime
+  --> $DIR/region-object-lifetime-in-coercion.rs:13:14
    |
 LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
-   |         ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+   |         ----- data with this lifetime...
 LL |     Box::new(v)
-   |     ^^^^^^^^^^^ lifetime `'static` required
+   |     ---------^-
+   |     |        |
+   |     |        ...and is captured here
+   |     ...is required to be `'static` by this...
+   |
+help: consider changing the trait object's explicit `'static` bound
+   |
+LL | fn b(v: &[u8]) -> Box<dyn Foo + '_> {
+   |                                 ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
+   |
+LL | fn b(v: &'static [u8]) -> Box<dyn Foo + 'static> {
+   |         ^^^^^^^^^^^^^
 
 error: cannot infer an appropriate lifetime
-  --> $DIR/region-object-lifetime-in-coercion.rs:20:14
+  --> $DIR/region-object-lifetime-in-coercion.rs:19:14
    |
 LL | fn c(v: &[u8]) -> Box<dyn Foo> {
    |         ----- data with this lifetime...
@@ -26,36 +50,36 @@ LL |     Box::new(v)
    |     |        ...and is captured here
    |     ...is required to be `'static` by this...
    |
-help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 17:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 16:1
    |
 LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> {
    |                               ^^^^
 
 error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
-  --> $DIR/region-object-lifetime-in-coercion.rs:24:14
+  --> $DIR/region-object-lifetime-in-coercion.rs:23:14
    |
 LL |     Box::new(v)
    |              ^
    |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 23:6...
-  --> $DIR/region-object-lifetime-in-coercion.rs:23:6
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 22:6...
+  --> $DIR/region-object-lifetime-in-coercion.rs:22:6
    |
 LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
    |      ^^
 note: ...so that the expression is assignable
-  --> $DIR/region-object-lifetime-in-coercion.rs:24:14
+  --> $DIR/region-object-lifetime-in-coercion.rs:23:14
    |
 LL |     Box::new(v)
    |              ^
    = note: expected `&[u8]`
               found `&'a [u8]`
-note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 23:9...
-  --> $DIR/region-object-lifetime-in-coercion.rs:23:9
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 22:9...
+  --> $DIR/region-object-lifetime-in-coercion.rs:22:9
    |
 LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
    |         ^^
 note: ...so that the expression is assignable
-  --> $DIR/region-object-lifetime-in-coercion.rs:24:5
+  --> $DIR/region-object-lifetime-in-coercion.rs:23:5
    |
 LL |     Box::new(v)
    |     ^^^^^^^^^^^
@@ -64,5 +88,4 @@ LL |     Box::new(v)
 
 error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0495, E0621.
-For more information about an error, try `rustc --explain E0495`.
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr
index 147f7f35418..982ed07232a 100644
--- a/src/test/ui/regions/regions-close-object-into-object-2.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr
@@ -1,28 +1,22 @@
-error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
+error: cannot infer an appropriate lifetime
   --> $DIR/regions-close-object-into-object-2.rs:10:11
    |
+LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
+   |                         ------------------ data with this lifetime...
 LL |     box B(&*v) as Box<dyn X>
-   |           ^^^
-   |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6...
-  --> $DIR/regions-close-object-into-object-2.rs:9:6
+   |     ------^^^---------------
+   |     |     |
+   |     |     ...and is captured here
+   |     ...is required to be `'static` by this...
    |
-LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
-   |      ^^
-note: ...so that the type `(dyn A<T> + 'a)` is not borrowed for too long
-  --> $DIR/regions-close-object-into-object-2.rs:10:11
+help: consider changing the trait object's explicit `'static` bound
    |
-LL |     box B(&*v) as Box<dyn X>
-   |           ^^^
-   = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that the expression is assignable
-  --> $DIR/regions-close-object-into-object-2.rs:10:5
+LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'a> {
+   |                                                            ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
    |
-LL |     box B(&*v) as Box<dyn X>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: expected `std::boxed::Box<(dyn X + 'static)>`
-              found `std::boxed::Box<dyn X>`
+LL | fn g<'a, T: 'static>(v: std::boxed::Box<(dyn A<T> + 'static)>) -> Box<dyn X + 'static> {
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr
index 6e7d6152cd0..1b82098ee13 100644
--- a/src/test/ui/regions/regions-close-object-into-object-4.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr
@@ -1,28 +1,22 @@
-error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
+error: cannot infer an appropriate lifetime
   --> $DIR/regions-close-object-into-object-4.rs:10:11
    |
+LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
+   |                   ---------------- data with this lifetime...
 LL |     box B(&*v) as Box<dyn X>
-   |           ^^^
-   |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6...
-  --> $DIR/regions-close-object-into-object-4.rs:9:6
+   |     ------^^^---------------
+   |     |     |
+   |     |     ...and is captured here
+   |     ...is required to be `'static` by this...
    |
-LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
-   |      ^^
-note: ...so that the type `(dyn A<U> + 'a)` is not borrowed for too long
-  --> $DIR/regions-close-object-into-object-4.rs:10:11
+help: consider changing the trait object's explicit `'static` bound
    |
-LL |     box B(&*v) as Box<dyn X>
-   |           ^^^
-   = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that the expression is assignable
-  --> $DIR/regions-close-object-into-object-4.rs:10:5
+LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'a> {
+   |                                                    ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
    |
-LL |     box B(&*v) as Box<dyn X>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: expected `std::boxed::Box<(dyn X + 'static)>`
-              found `std::boxed::Box<dyn X>`
+LL | fn i<'a, T, U>(v: std::boxed::Box<(dyn A<U> + 'static)>) -> Box<dyn X + 'static> {
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-proc-bound-capture.nll.stderr b/src/test/ui/regions/regions-proc-bound-capture.nll.stderr
new file mode 100644
index 00000000000..75890b85815
--- /dev/null
+++ b/src/test/ui/regions/regions-proc-bound-capture.nll.stderr
@@ -0,0 +1,11 @@
+error: lifetime may not live long enough
+  --> $DIR/regions-proc-bound-capture.rs:9:5
+   |
+LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> {
+   |                   - let's call the lifetime of this reference `'1`
+LL |     // This is illegal, because the region bound on `proc` is 'static.
+LL |     Box::new(move || { *x })
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/regions/regions-proc-bound-capture.rs b/src/test/ui/regions/regions-proc-bound-capture.rs
index 0c903b73849..8617c0e9da8 100644
--- a/src/test/ui/regions/regions-proc-bound-capture.rs
+++ b/src/test/ui/regions/regions-proc-bound-capture.rs
@@ -4,9 +4,9 @@ fn borrowed_proc<'a>(x: &'a isize) -> Box<dyn FnMut()->(isize) + 'a> {
     Box::new(move|| { *x })
 }
 
-fn static_proc(x: &isize) -> Box<dyn FnMut()->(isize) + 'static> {
+fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> {
     // This is illegal, because the region bound on `proc` is 'static.
-    Box::new(move|| { *x }) //~ ERROR explicit lifetime required in the type of `x` [E0621]
+    Box::new(move || { *x }) //~ ERROR cannot infer an appropriate lifetime
 }
 
 fn main() { }
diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr
index c53af34456e..e7bbfaababe 100644
--- a/src/test/ui/regions/regions-proc-bound-capture.stderr
+++ b/src/test/ui/regions/regions-proc-bound-capture.stderr
@@ -1,12 +1,23 @@
-error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/regions-proc-bound-capture.rs:9:5
+error: cannot infer an appropriate lifetime
+  --> $DIR/regions-proc-bound-capture.rs:9:14
    |
-LL | fn static_proc(x: &isize) -> Box<dyn FnMut()->(isize) + 'static> {
-   |                   ------ help: add explicit lifetime `'static` to the type of `x`: `&'static isize`
+LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> {
+   |                   ------ data with this lifetime...
 LL |     // This is illegal, because the region bound on `proc` is 'static.
-LL |     Box::new(move|| { *x })
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
+LL |     Box::new(move || { *x })
+   |     ---------^^^^^^^^^^^^^^-
+   |     |        |
+   |     |        ...and is captured here
+   |     ...is required to be `'static` by this...
+   |
+help: consider changing the trait object's explicit `'static` bound
+   |
+LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + '_> {
+   |                                                           ^^
+help: alternatively, set an explicit `'static` lifetime in this parameter
+   |
+LL | fn static_proc(x: &'static isize) -> Box<dyn FnMut() -> (isize) + 'static> {
+   |                   ^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0621`.
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
index 3577dd59289..4dc4aac6cea 100644
--- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
@@ -7,7 +7,7 @@ LL |     //                      ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to
 LL |     Box::new(items.iter())
    |     ---------------^^^^--- ...is captured and required to be `'static` here
    |
-help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1
+help: to permit non-static references in a trait object value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1
    |
 LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {
    |                                                   ^^^^