about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-04-24 13:14:19 +0200
committerGitHub <noreply@github.com>2020-04-24 13:14:19 +0200
commit7d8a3ad128381bbabb18f975130cfd7a92c1ceca (patch)
tree48c374d86740c79d489970198fb61c1687e5794c
parent5a59527516a917738c2e5f5d9f5e9a3533a6a5bc (diff)
parent25f8966b5a93dcd4a1f7e06907a63f7547ef2a96 (diff)
downloadrust-7d8a3ad128381bbabb18f975130cfd7a92c1ceca.tar.gz
rust-7d8a3ad128381bbabb18f975130cfd7a92c1ceca.zip
Rollup merge of #71235 - estebank:lt-sugg-2, r=ecstatic-morse
Tweak `'static` suggestion code

Fix #71196.
-rw-r--r--src/librustc_ast_lowering/path.rs5
-rw-r--r--src/librustc_resolve/late/diagnostics.rs198
-rw-r--r--src/librustc_resolve/late/lifetimes.rs55
-rw-r--r--src/librustc_span/lib.rs3
-rw-r--r--src/librustc_typeck/astconv.rs13
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr6
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr6
-rw-r--r--src/test/ui/async-await/issues/issue-63388-2.stderr6
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-6.stderr6
-rw-r--r--src/test/ui/foreign-fn-return-lifetime.stderr6
-rw-r--r--src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr25
-rw-r--r--src/test/ui/issues/issue-13497.stderr6
-rw-r--r--src/test/ui/issues/issue-26638.stderr12
-rw-r--r--src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr24
-rw-r--r--src/test/ui/specialization/defaultimpl/validation.stderr4
-rw-r--r--src/test/ui/suggestions/missing-lifetime-specifier.rs65
-rw-r--r--src/test/ui/suggestions/missing-lifetime-specifier.stderr256
-rw-r--r--src/test/ui/suggestions/return-without-lifetime.stderr19
-rw-r--r--src/test/ui/traits/negative-impls/negative-default-impls.stderr2
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-feature-gate.stderr2
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr4
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-sugar-region.stderr2
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr2
-rw-r--r--src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr13
-rw-r--r--src/test/ui/unspecified-self-in-trait-ref.stderr2
25 files changed, 572 insertions, 170 deletions
diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs
index dde73475651..cf6dde81309 100644
--- a/src/librustc_ast_lowering/path.rs
+++ b/src/librustc_ast_lowering/path.rs
@@ -273,7 +273,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             .next();
         if !generic_args.parenthesized && !has_lifetimes {
             generic_args.args = self
-                .elided_path_lifetimes(path_span, expected_lifetimes)
+                .elided_path_lifetimes(
+                    first_generic_span.map(|s| s.shrink_to_lo()).unwrap_or(segment.ident.span),
+                    expected_lifetimes,
+                )
                 .map(GenericArg::Lifetime)
                 .chain(generic_args.args.into_iter())
                 .collect();
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index e7fa88bff97..c25a3524dc1 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -1034,101 +1034,125 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
         lifetime_names: &FxHashSet<ast::Ident>,
         params: &[ElisionFailureInfo],
     ) {
-        if count > 1 {
-            err.span_label(span, format!("expected {} lifetime parameters", count));
-        } else {
-            let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok();
-            let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| {
-                err.span_suggestion(
-                    span,
-                    "consider using the named lifetime",
-                    sugg,
-                    Applicability::MaybeIncorrect,
-                );
-            };
-            let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg: &str| {
-                err.span_label(span, "expected named lifetime parameter");
+        let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok();
 
-                for missing in self.missing_named_lifetime_spots.iter().rev() {
-                    let mut introduce_suggestion = vec![];
-                    let msg;
-                    let should_break;
-                    introduce_suggestion.push(match missing {
-                        MissingLifetimeSpot::Generics(generics) => {
-                            msg = "consider introducing a named lifetime parameter".to_string();
-                            should_break = true;
-                            if let Some(param) = generics.params.iter().find(|p| match p.kind {
-                                hir::GenericParamKind::Type {
-                                    synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
-                                    ..
-                                } => false,
-                                _ => true,
-                            }) {
-                                (param.span.shrink_to_lo(), "'a, ".to_string())
-                            } else {
-                                (generics.span, "<'a>".to_string())
-                            }
-                        }
-                        MissingLifetimeSpot::HigherRanked { span, span_type } => {
-                            msg = format!(
-                                "consider making the {} lifetime-generic with a new `'a` lifetime",
-                                span_type.descr(),
-                            );
-                            should_break = false;
-                            err.note(
-                                "for more information on higher-ranked polymorphism, visit \
-                             https://doc.rust-lang.org/nomicon/hrtb.html",
-                            );
-                            (*span, span_type.suggestion("'a"))
-                        }
-                    });
-                    for param in params {
-                        if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span)
-                        {
-                            if snippet.starts_with('&') && !snippet.starts_with("&'") {
-                                introduce_suggestion
-                                    .push((param.span, format!("&'a {}", &snippet[1..])));
-                            } else if snippet.starts_with("&'_ ") {
-                                introduce_suggestion
-                                    .push((param.span, format!("&'a {}", &snippet[4..])));
-                            }
+        err.span_label(
+            span,
+            &format!(
+                "expected {} lifetime parameter{}",
+                if count == 1 { "named".to_string() } else { count.to_string() },
+                pluralize!(count)
+            ),
+        );
+
+        let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| {
+            err.span_suggestion_verbose(
+                span,
+                &format!("consider using the `{}` lifetime", lifetime_names.iter().next().unwrap()),
+                sugg,
+                Applicability::MaybeIncorrect,
+            );
+        };
+        let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg: &str| {
+            for missing in self.missing_named_lifetime_spots.iter().rev() {
+                let mut introduce_suggestion = vec![];
+                let msg;
+                let should_break;
+                introduce_suggestion.push(match missing {
+                    MissingLifetimeSpot::Generics(generics) => {
+                        msg = "consider introducing a named lifetime parameter".to_string();
+                        should_break = true;
+                        if let Some(param) = generics.params.iter().find(|p| match p.kind {
+                            hir::GenericParamKind::Type {
+                                synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
+                                ..
+                            } => false,
+                            _ => true,
+                        }) {
+                            (param.span.shrink_to_lo(), "'a, ".to_string())
+                        } else {
+                            (generics.span, "<'a>".to_string())
                         }
                     }
-                    introduce_suggestion.push((span, sugg.to_string()));
-                    err.multipart_suggestion(
-                        &msg,
-                        introduce_suggestion,
-                        Applicability::MaybeIncorrect,
-                    );
-                    if should_break {
-                        break;
+                    MissingLifetimeSpot::HigherRanked { span, span_type } => {
+                        msg = format!(
+                            "consider making the {} lifetime-generic with a new `'a` lifetime",
+                            span_type.descr(),
+                        );
+                        should_break = false;
+                        err.note(
+                            "for more information on higher-ranked polymorphism, visit \
+                            https://doc.rust-lang.org/nomicon/hrtb.html",
+                        );
+                        (*span, span_type.suggestion("'a"))
+                    }
+                });
+                for param in params {
+                    if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span) {
+                        if snippet.starts_with('&') && !snippet.starts_with("&'") {
+                            introduce_suggestion
+                                .push((param.span, format!("&'a {}", &snippet[1..])));
+                        } else if snippet.starts_with("&'_ ") {
+                            introduce_suggestion
+                                .push((param.span, format!("&'a {}", &snippet[4..])));
+                        }
                     }
                 }
-            };
-
-            match (lifetime_names.len(), lifetime_names.iter().next(), snippet.as_deref()) {
-                (1, Some(name), Some("&")) => {
-                    suggest_existing(err, format!("&{} ", name));
-                }
-                (1, Some(name), Some("'_")) => {
-                    suggest_existing(err, name.to_string());
-                }
-                (1, Some(name), Some(snippet)) if !snippet.ends_with('>') => {
-                    suggest_existing(err, format!("{}<{}>", snippet, name));
-                }
-                (0, _, Some("&")) => {
-                    suggest_new(err, "&'a ");
-                }
-                (0, _, Some("'_")) => {
-                    suggest_new(err, "'a");
-                }
-                (0, _, Some(snippet)) if !snippet.ends_with('>') => {
-                    suggest_new(err, &format!("{}<'a>", snippet));
+                introduce_suggestion.push((span, sugg.to_string()));
+                err.multipart_suggestion(&msg, introduce_suggestion, Applicability::MaybeIncorrect);
+                if should_break {
+                    break;
                 }
-                _ => {
-                    err.span_label(span, "expected lifetime parameter");
+            }
+        };
+
+        match (lifetime_names.len(), lifetime_names.iter().next(), snippet.as_deref()) {
+            (1, Some(name), Some("&")) => {
+                suggest_existing(err, format!("&{} ", name));
+            }
+            (1, Some(name), Some("'_")) => {
+                suggest_existing(err, name.to_string());
+            }
+            (1, Some(name), Some("")) => {
+                suggest_existing(err, format!("{}, ", name).repeat(count));
+            }
+            (1, Some(name), Some(snippet)) if !snippet.ends_with('>') => {
+                suggest_existing(
+                    err,
+                    format!(
+                        "{}<{}>",
+                        snippet,
+                        std::iter::repeat(name.to_string())
+                            .take(count)
+                            .collect::<Vec<_>>()
+                            .join(", ")
+                    ),
+                );
+            }
+            (0, _, Some("&")) if count == 1 => {
+                suggest_new(err, "&'a ");
+            }
+            (0, _, Some("'_")) if count == 1 => {
+                suggest_new(err, "'a");
+            }
+            (0, _, Some(snippet)) if !snippet.ends_with('>') && count == 1 => {
+                suggest_new(err, &format!("{}<'a>", snippet));
+            }
+            (n, ..) if n > 1 => {
+                let spans: Vec<Span> = lifetime_names.iter().map(|lt| lt.span).collect();
+                err.span_note(spans, "these named lifetimes are available to use");
+                if Some("") == snippet.as_deref() {
+                    // This happens when we have `Foo<T>` where we point at the space before `T`,
+                    // but this can be confusing so we give a suggestion with placeholders.
+                    err.span_suggestion_verbose(
+                        span,
+                        "consider using one of the available lifetimes here",
+                        "'lifetime, ".repeat(count),
+                        Applicability::HasPlaceholders,
+                    );
                 }
             }
+            _ => {}
         }
     }
 }
diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs
index a988c5829b5..0deb0af448e 100644
--- a/src/librustc_resolve/late/lifetimes.rs
+++ b/src/librustc_resolve/late/lifetimes.rs
@@ -2393,52 +2393,28 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         };
 
         let mut err = self.report_missing_lifetime_specifiers(span, lifetime_refs.len());
-        let mut add_label = true;
 
         if let Some(params) = error {
-            if lifetime_refs.len() == 1 {
-                add_label = add_label && self.report_elision_failure(&mut err, params, span);
+            // If there's no lifetime available, suggest `'static`.
+            if self.report_elision_failure(&mut err, params) && lifetime_names.is_empty() {
+                lifetime_names.insert(ast::Ident::from_str("'static"));
             }
         }
-        if add_label {
-            self.add_missing_lifetime_specifiers_label(
-                &mut err,
-                span,
-                lifetime_refs.len(),
-                &lifetime_names,
-                error.map(|p| &p[..]).unwrap_or(&[]),
-            );
-        }
-
+        self.add_missing_lifetime_specifiers_label(
+            &mut err,
+            span,
+            lifetime_refs.len(),
+            &lifetime_names,
+            error.map(|p| &p[..]).unwrap_or(&[]),
+        );
         err.emit();
     }
 
-    fn suggest_lifetime(&self, db: &mut DiagnosticBuilder<'_>, span: Span, msg: &str) -> bool {
-        match self.tcx.sess.source_map().span_to_snippet(span) {
-            Ok(ref snippet) => {
-                let (sugg, applicability) = if snippet == "&" {
-                    ("&'static ".to_owned(), Applicability::MachineApplicable)
-                } else if snippet == "'_" {
-                    ("'static".to_owned(), Applicability::MachineApplicable)
-                } else {
-                    (format!("{} + 'static", snippet), Applicability::MaybeIncorrect)
-                };
-                db.span_suggestion(span, msg, sugg, applicability);
-                false
-            }
-            Err(_) => {
-                db.help(msg);
-                true
-            }
-        }
-    }
-
     fn report_elision_failure(
         &mut self,
         db: &mut DiagnosticBuilder<'_>,
         params: &[ElisionFailureInfo],
-        span: Span,
-    ) -> bool {
+    ) -> bool /* add `'static` lifetime to lifetime list */ {
         let mut m = String::new();
         let len = params.len();
 
@@ -2487,29 +2463,28 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 "this function's return type contains a borrowed value, \
                  but there is no value for it to be borrowed from",
             );
-            self.suggest_lifetime(db, span, "consider giving it a 'static lifetime")
+            true
         } else if elided_len == 0 {
             db.help(
                 "this function's return type contains a borrowed value with \
                  an elided lifetime, but the lifetime cannot be derived from \
                  the arguments",
             );
-            let msg = "consider giving it an explicit bounded or 'static lifetime";
-            self.suggest_lifetime(db, span, msg)
+            true
         } else if elided_len == 1 {
             db.help(&format!(
                 "this function's return type contains a borrowed value, \
                  but the signature does not say which {} it is borrowed from",
                 m
             ));
-            true
+            false
         } else {
             db.help(&format!(
                 "this function's return type contains a borrowed value, \
                  but the signature does not say whether it is borrowed from {}",
                 m
             ));
-            true
+            false
         }
     }
 
diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs
index 85a870ae34c..e8252d96350 100644
--- a/src/librustc_span/lib.rs
+++ b/src/librustc_span/lib.rs
@@ -657,7 +657,8 @@ impl MultiSpan {
         MultiSpan { primary_spans: vec![primary_span], span_labels: vec![] }
     }
 
-    pub fn from_spans(vec: Vec<Span>) -> MultiSpan {
+    pub fn from_spans(mut vec: Vec<Span>) -> MultiSpan {
+        vec.sort();
         MultiSpan { primary_spans: vec, span_labels: vec![] }
     }
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 63b8eb224ce..706dca999fa 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1017,18 +1017,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
 
-        let path_span = if let [segment] = &trait_ref.path.segments[..] {
-            // FIXME: `trait_ref.path.span` can point to a full path with multiple
-            // segments, even though `trait_ref.path.segments` is of length `1`. Work
-            // around that bug here, even though it should be fixed elsewhere.
-            // This would otherwise cause an invalid suggestion. For an example, look at
-            // `src/test/ui/issues/issue-28344.rs`.
-            segment.ident.span
-        } else {
-            trait_ref.path.span
-        };
         let (substs, assoc_bindings, arg_count_correct) = self.create_substs_for_ast_trait_ref(
-            path_span,
+            trait_ref.path.span,
             trait_def_id,
             self_ty,
             trait_ref.path.segments.last().unwrap(),
@@ -1729,6 +1719,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     self.ast_region_to_region(lifetime, None)
                 } else {
                     self.re_infer(None, span).unwrap_or_else(|| {
+                        // FIXME: these can be redundant with E0106, but not always.
                         struct_span_err!(
                             tcx.sess,
                             span,
diff --git a/src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr b/src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr
index 2745e44ac0c..00f44129cc8 100644
--- a/src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr
+++ b/src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr
@@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
   --> $DIR/bound-lifetime-in-binding-only.rs:52:23
    |
 LL | fn elision<T: Fn() -> &i32>() {
-   |                       ^ help: consider giving it a 'static lifetime: `&'static`
+   |                       ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL | fn elision<T: Fn() -> &'static i32>() {
+   |                       ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr b/src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr
index 96f0cb85c8c..a5242707c71 100644
--- a/src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr
+++ b/src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr
@@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
   --> $DIR/bound-lifetime-in-return-only.rs:34:23
    |
 LL | fn elision(_: fn() -> &i32) {
-   |                       ^ help: consider giving it a 'static lifetime: `&'static`
+   |                       ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL | fn elision(_: fn() -> &'static i32) {
+   |                       ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr
index 6edb9e63d48..ca42263dfed 100644
--- a/src/test/ui/async-await/issues/issue-63388-2.stderr
+++ b/src/test/ui/async-await/issues/issue-63388-2.stderr
@@ -4,9 +4,13 @@ error[E0106]: missing lifetime specifier
 LL |         foo: &dyn Foo, bar: &'a dyn Foo
    |              --------       -----------
 LL |     ) -> &dyn Foo
-   |          ^ help: consider using the named lifetime: `&'a`
+   |          ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`
+help: consider using the `'a` lifetime
+   |
+LL |     ) -> &'a dyn Foo
+   |          ^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/c-variadic/variadic-ffi-6.stderr b/src/test/ui/c-variadic/variadic-ffi-6.stderr
index 882e7f89f2a..4626a4bc2dc 100644
--- a/src/test/ui/c-variadic/variadic-ffi-6.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-6.stderr
@@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
   --> $DIR/variadic-ffi-6.rs:7:6
    |
 LL | ) -> &usize {
-   |      ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
+   |      ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
+help: consider using the `'static` lifetime
+   |
+LL | ) -> &'static usize {
+   |      ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/foreign-fn-return-lifetime.stderr b/src/test/ui/foreign-fn-return-lifetime.stderr
index 575da18f240..feecb6d80e7 100644
--- a/src/test/ui/foreign-fn-return-lifetime.stderr
+++ b/src/test/ui/foreign-fn-return-lifetime.stderr
@@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
   --> $DIR/foreign-fn-return-lifetime.rs:5:19
    |
 LL |     pub fn f() -> &u8;
-   |                   ^ help: consider giving it a 'static lifetime: `&'static`
+   |                   ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     pub fn f() -> &'static u8;
+   |                   ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr b/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr
index 9f410c0dbbb..1106a067822 100644
--- a/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr
+++ b/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr
@@ -5,16 +5,33 @@ LL | fn should_error<T>() where T : Into<&u32> {}
    |                                     ^ explicit lifetime name needed here
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:9:19
+  --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:9:21
    |
 LL |     fn foo<'b, L: X<&'b Nested<K>>>();
-   |                   ^^^^^^^^^^^^^^^^ expected lifetime parameter
+   |                     ^ expected named lifetime parameter
+   |
+note: these named lifetimes are available to use
+  --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:8:9
+   |
+LL | trait X<'a, K: 'a> {
+   |         ^^
+LL |     fn foo<'b, L: X<&'b Nested<K>>>();
+   |            ^^
+help: consider using one of the available lifetimes here
+   |
+LL |     fn foo<'b, L: X<'lifetime, &'b Nested<K>>>();
+   |                     ^^^^^^^^^^
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:13:15
+  --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:13:17
    |
 LL | fn bar<'b, L: X<&'b Nested<i32>>>(){}
-   |               ^^^^^^^^^^^^^^^^^^ expected lifetime parameter
+   |                 ^ expected named lifetime parameter
+   |
+help: consider using the `'b` lifetime
+   |
+LL | fn bar<'b, L: X<'b, &'b Nested<i32>>>(){}
+   |                 ^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-13497.stderr b/src/test/ui/issues/issue-13497.stderr
index b72f0277052..a231f73d067 100644
--- a/src/test/ui/issues/issue-13497.stderr
+++ b/src/test/ui/issues/issue-13497.stderr
@@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
   --> $DIR/issue-13497.rs:2:5
    |
 LL |     &str
-   |     ^ help: consider giving it a 'static lifetime: `&'static`
+   |     ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     &'static str
+   |     ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr
index 1d8fbdc63c5..3df58d66d1f 100644
--- a/src/test/ui/issues/issue-26638.stderr
+++ b/src/test/ui/issues/issue-26638.stderr
@@ -14,17 +14,25 @@ error[E0106]: missing lifetime specifier
   --> $DIR/issue-26638.rs:4:40
    |
 LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
-   |                                        ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
+   |                                        ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
+help: consider using the `'static` lifetime
+   |
+LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &'static str { iter() }
+   |                                        ^^^^^^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/issue-26638.rs:7:22
    |
 LL | fn parse_type_3() -> &str { unimplemented!() }
-   |                      ^ help: consider giving it a 'static lifetime: `&'static`
+   |                      ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL | fn parse_type_3() -> &'static str { unimplemented!() }
+   |                      ^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
index 461c1832e9a..5809b5bd661 100644
--- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
+++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
@@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
   --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:2:11
    |
 LL | fn f() -> &isize {
-   |           ^ help: consider giving it a 'static lifetime: `&'static`
+   |           ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL | fn f() -> &'static isize {
+   |           ^^^^^^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:33
@@ -34,25 +38,37 @@ error[E0106]: missing lifetime specifier
   --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:21:20
    |
 LL | fn i(_x: isize) -> &isize {
-   |                    ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
+   |                    ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
+help: consider using the `'static` lifetime
+   |
+LL | fn i(_x: isize) -> &'static isize {
+   |                    ^^^^^^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:34:24
    |
 LL | fn j(_x: StaticStr) -> &isize {
-   |                        ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
+   |                        ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
+help: consider using the `'static` lifetime
+   |
+LL | fn j(_x: StaticStr) -> &'static isize {
+   |                        ^^^^^^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:40:49
    |
 LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize {
-   |                                                 ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
+   |                                                 ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
+help: consider using the `'a` lifetime
+   |
+LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &'a isize {
+   |                                                 ^^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/specialization/defaultimpl/validation.stderr b/src/test/ui/specialization/defaultimpl/validation.stderr
index 9bf59bd4f63..254eaf51a64 100644
--- a/src/test/ui/specialization/defaultimpl/validation.stderr
+++ b/src/test/ui/specialization/defaultimpl/validation.stderr
@@ -25,13 +25,13 @@ LL | default impl !Send for Z {}
    | default because of this
 
 error[E0750]: negative impls cannot be default impls
-  --> $DIR/validation.rs:10:14
+  --> $DIR/validation.rs:10:1
    |
 LL | default impl !Send for Z {}
    | ^^^^^^^      ^
 
 error[E0750]: negative impls cannot be default impls
-  --> $DIR/validation.rs:14:14
+  --> $DIR/validation.rs:14:1
    |
 LL | default impl !Tr for S {}
    | ^^^^^^^      ^
diff --git a/src/test/ui/suggestions/missing-lifetime-specifier.rs b/src/test/ui/suggestions/missing-lifetime-specifier.rs
new file mode 100644
index 00000000000..b09c1879d70
--- /dev/null
+++ b/src/test/ui/suggestions/missing-lifetime-specifier.rs
@@ -0,0 +1,65 @@
+#![allow(bare_trait_objects)]
+use std::collections::HashMap;
+use std::cell::RefCell;
+
+pub union Foo<'t, 'k> {
+    i: &'t i64,
+    f: &'k f64,
+}
+trait Bar<'t, 'k> {}
+
+pub union Qux<'t, 'k, I> {
+    i: &'t I,
+    f: &'k I,
+}
+trait Tar<'t, 'k, I> {}
+
+thread_local! {
+    static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
+    //~^ ERROR missing lifetime specifier
+    //~| ERROR missing lifetime specifier
+}
+thread_local! {
+    static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
+    //~^ ERROR missing lifetime specifier
+    //~| ERROR missing lifetime specifier
+    //~| ERROR missing lifetime specifier
+    //~| ERROR missing lifetime specifier
+    //~| ERROR the lifetime bound for this object type cannot be deduced from context
+    //~| ERROR the lifetime bound for this object type cannot be deduced from context
+}
+thread_local! {
+    static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
+    //~^ ERROR missing lifetime specifier
+    //~| ERROR missing lifetime specifier
+}
+thread_local! {
+    static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
+    //~^ ERROR missing lifetime specifier
+    //~| ERROR missing lifetime specifier
+    //~| ERROR missing lifetime specifier
+    //~| ERROR missing lifetime specifier
+    //~| ERROR the lifetime bound for this object type cannot be deduced from context
+    //~| ERROR the lifetime bound for this object type cannot be deduced from context
+}
+
+thread_local! {
+    static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
+    //~^ ERROR wrong number of lifetime arguments: expected 2, found 1
+    //~| ERROR wrong number of lifetime arguments: expected 2, found 1
+    //~| ERROR wrong number of lifetime arguments: expected 2, found 1
+    //~| ERROR wrong number of lifetime arguments: expected 2, found 1
+}
+thread_local! {
+    static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
+    //~^ ERROR the lifetime bound for this object type cannot be deduced from context
+    //~| ERROR the lifetime bound for this object type cannot be deduced from context
+    //~| ERROR wrong number of lifetime arguments: expected 2, found 1
+    //~| ERROR wrong number of lifetime arguments: expected 2, found 1
+    //~| ERROR wrong number of lifetime arguments: expected 2, found 1
+    //~| ERROR wrong number of lifetime arguments: expected 2, found 1
+    //~| ERROR missing lifetime specifier
+    //~| ERROR missing lifetime specifier
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/missing-lifetime-specifier.stderr b/src/test/ui/suggestions/missing-lifetime-specifier.stderr
new file mode 100644
index 00000000000..f5ff54cc916
--- /dev/null
+++ b/src/test/ui/suggestions/missing-lifetime-specifier.stderr
@@ -0,0 +1,256 @@
+error[E0106]: missing lifetime specifiers
+  --> $DIR/missing-lifetime-specifier.rs:18:44
+   |
+LL |     static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^ expected 2 lifetime parameters
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static a: RefCell<HashMap<i32, Vec<Vec<Foo<'static, 'static>>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0106]: missing lifetime specifiers
+  --> $DIR/missing-lifetime-specifier.rs:18:44
+   |
+LL |     static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^ expected 2 lifetime parameters
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static a: RefCell<HashMap<i32, Vec<Vec<Foo<'static, 'static>>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/missing-lifetime-specifier.rs:23:44
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
+   |                                            ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&'static Bar>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^^^^^^
+
+error[E0106]: missing lifetime specifiers
+  --> $DIR/missing-lifetime-specifier.rs:23:45
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^ expected 2 lifetime parameters
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar<'static, 'static>>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/missing-lifetime-specifier.rs:23:44
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
+   |                                            ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&'static Bar>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^^^^^^
+
+error[E0106]: missing lifetime specifiers
+  --> $DIR/missing-lifetime-specifier.rs:23:45
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^ expected 2 lifetime parameters
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar<'static, 'static>>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0106]: missing lifetime specifiers
+  --> $DIR/missing-lifetime-specifier.rs:32:48
+   |
+LL |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
+   |                                                ^ expected 2 lifetime parameters
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                                ^^^^^^^^^^^^^^^^^
+
+error[E0106]: missing lifetime specifiers
+  --> $DIR/missing-lifetime-specifier.rs:32:48
+   |
+LL |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
+   |                                                ^ expected 2 lifetime parameters
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                                ^^^^^^^^^^^^^^^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/missing-lifetime-specifier.rs:37:44
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
+   |                                            ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<i32>>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^^^^^^
+
+error[E0106]: missing lifetime specifiers
+  --> $DIR/missing-lifetime-specifier.rs:37:49
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
+   |                                                 ^ expected 2 lifetime parameters
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                                 ^^^^^^^^^^^^^^^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/missing-lifetime-specifier.rs:37:44
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
+   |                                            ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<i32>>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^^^^^^
+
+error[E0106]: missing lifetime specifiers
+  --> $DIR/missing-lifetime-specifier.rs:37:49
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
+   |                                                 ^ expected 2 lifetime parameters
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                                 ^^^^^^^^^^^^^^^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/missing-lifetime-specifier.rs:54:44
+   |
+LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                            ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^^^^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/missing-lifetime-specifier.rs:54:44
+   |
+LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                            ^ expected named lifetime parameter
+   |
+   = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL |     static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^^^^^^
+
+error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
+  --> $DIR/missing-lifetime-specifier.rs:23:45
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^
+
+error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
+  --> $DIR/missing-lifetime-specifier.rs:23:45
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^
+
+error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
+  --> $DIR/missing-lifetime-specifier.rs:37:45
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^^^^^^
+
+error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
+  --> $DIR/missing-lifetime-specifier.rs:37:45
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^^^^^^
+
+error[E0107]: wrong number of lifetime arguments: expected 2, found 1
+  --> $DIR/missing-lifetime-specifier.rs:47:44
+   |
+LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
+
+error[E0107]: wrong number of lifetime arguments: expected 2, found 1
+  --> $DIR/missing-lifetime-specifier.rs:47:44
+   |
+LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
+
+error[E0107]: wrong number of lifetime arguments: expected 2, found 1
+  --> $DIR/missing-lifetime-specifier.rs:47:44
+   |
+LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
+
+error[E0107]: wrong number of lifetime arguments: expected 2, found 1
+  --> $DIR/missing-lifetime-specifier.rs:47:44
+   |
+LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                            ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
+
+error[E0107]: wrong number of lifetime arguments: expected 2, found 1
+  --> $DIR/missing-lifetime-specifier.rs:54:45
+   |
+LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
+
+error[E0107]: wrong number of lifetime arguments: expected 2, found 1
+  --> $DIR/missing-lifetime-specifier.rs:54:45
+   |
+LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
+
+error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
+  --> $DIR/missing-lifetime-specifier.rs:54:45
+   |
+LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^^^^^^^^^^^^^^^
+
+error[E0107]: wrong number of lifetime arguments: expected 2, found 1
+  --> $DIR/missing-lifetime-specifier.rs:54:45
+   |
+LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
+
+error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
+  --> $DIR/missing-lifetime-specifier.rs:54:45
+   |
+LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^^^^^^^^^^^^^^^
+
+error[E0107]: wrong number of lifetime arguments: expected 2, found 1
+  --> $DIR/missing-lifetime-specifier.rs:54:45
+   |
+LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
+   |                                             ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
+
+error: aborting due to 28 previous errors
+
+Some errors have detailed explanations: E0106, E0107.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr
index ce3b1748da4..2a237d61f50 100644
--- a/src/test/ui/suggestions/return-without-lifetime.stderr
+++ b/src/test/ui/suggestions/return-without-lifetime.stderr
@@ -2,23 +2,36 @@ error[E0106]: missing lifetime specifier
   --> $DIR/return-without-lifetime.rs:2:16
    |
 LL | struct Foo<'a>(&usize);
-   |                ^ help: consider using the named lifetime: `&'a`
+   |                ^ expected named lifetime parameter
+   |
+help: consider using the `'a` lifetime
+   |
+LL | struct Foo<'a>(&'a usize);
+   |                ^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/return-without-lifetime.rs:5:34
    |
 LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() }
-   |                    ---------     ^ help: consider using the named lifetime: `&'a`
+   |                    ---------     ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from
+help: consider using the `'a` lifetime
+   |
+LL | fn func1<'a>(_arg: &'a Thing) -> &'a () { unimplemented!() }
+   |                                  ^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/return-without-lifetime.rs:7:35
    |
 LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() }
-   |                    ----------     ^ help: consider using the named lifetime: `&'a`
+   |                    ----------     ^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from
+help: consider using the `'a` lifetime
+   |
+LL | fn func2<'a>(_arg: &Thing<'a>) -> &'a () { unimplemented!() }
+   |                                   ^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/traits/negative-impls/negative-default-impls.stderr b/src/test/ui/traits/negative-impls/negative-default-impls.stderr
index d2423d01a9a..a70bbe6b948 100644
--- a/src/test/ui/traits/negative-impls/negative-default-impls.stderr
+++ b/src/test/ui/traits/negative-impls/negative-default-impls.stderr
@@ -1,5 +1,5 @@
 error[E0750]: negative impls cannot be default impls
-  --> $DIR/negative-default-impls.rs:8:14
+  --> $DIR/negative-default-impls.rs:8:1
    |
 LL | default impl !MyTrait for u32 {}
    | ^^^^^^^      ^
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-feature-gate.stderr b/src/test/ui/unboxed-closures/unboxed-closure-feature-gate.stderr
index 7af9c57a830..b824d160d71 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-feature-gate.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-feature-gate.stderr
@@ -2,7 +2,7 @@ error[E0658]: parenthetical notation is only stable when used with `Fn`-family t
   --> $DIR/unboxed-closure-feature-gate.rs:13:20
    |
 LL |     let x: Box<dyn Foo(isize)>;
-   |                    ^^^
+   |                    ^^^^^^^^^^
    |
    = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr
index 9a3bdd2bd5e..9da36906d55 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.stderr
@@ -2,7 +2,7 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
   --> $DIR/unboxed-closure-sugar-not-used-on-fn.rs:3:17
    |
 LL | fn bar1(x: &dyn Fn<(), Output=()>) {
-   |                 ^^ help: use parenthetical notation instead: `Fn() -> ()`
+   |                 ^^^^^^^^^^^^^^^^^ help: use parenthetical notation instead: `Fn() -> ()`
    |
    = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
@@ -11,7 +11,7 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
   --> $DIR/unboxed-closure-sugar-not-used-on-fn.rs:7:28
    |
 LL | fn bar2<T>(x: &T) where T: Fn<()> {
-   |                            ^^ help: use parenthetical notation instead: `Fn() -> ()`
+   |                            ^^^^^^ help: use parenthetical notation instead: `Fn() -> ()`
    |
    = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-region.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-region.stderr
index b92f054498b..e9d51983a7a 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-region.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-region.stderr
@@ -2,7 +2,7 @@ error[E0107]: wrong number of lifetime arguments: expected 1, found 0
   --> $DIR/unboxed-closure-sugar-region.rs:30:51
    |
 LL | fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) {
-   |                                                   ^^^ expected 1 lifetime argument
+   |                                                   ^^^^^^^^^^ expected 1 lifetime argument
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr
index f482098cbff..f42ac38d370 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr
@@ -2,7 +2,7 @@ error[E0107]: wrong number of type arguments: expected 3, found 1
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs:5:16
    |
 LL | fn foo(_: &dyn Three())
-   |                ^^^^^ expected 3 type arguments
+   |                ^^^^^^^ expected 3 type arguments
 
 error[E0220]: associated type `Output` not found for `Three<(), [type error], [type error]>`
   --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs:5:16
diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
index ada4551baef..594cdd245b3 100644
--- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
+++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
@@ -14,15 +14,24 @@ error[E0106]: missing lifetime specifier
   --> $DIR/underscore-lifetime-binders.rs:2:17
    |
 LL | struct Baz<'a>(&'_ &'a u8);
-   |                 ^^ help: consider using the named lifetime: `'a`
+   |                 ^^ expected named lifetime parameter
+   |
+help: consider using the `'a` lifetime
+   |
+LL | struct Baz<'a>(&'a &'a u8);
+   |                 ^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/underscore-lifetime-binders.rs:10:33
    |
 LL | fn meh() -> Box<dyn for<'_> Meh<'_>>
-   |                                 ^^ help: consider giving it a 'static lifetime: `'static`
+   |                                 ^^ expected named lifetime parameter
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+   |
+LL | fn meh() -> Box<dyn for<'_> Meh<'static>>
+   |                                 ^^^^^^^
 
 error[E0106]: missing lifetime specifier
   --> $DIR/underscore-lifetime-binders.rs:16:35
diff --git a/src/test/ui/unspecified-self-in-trait-ref.stderr b/src/test/ui/unspecified-self-in-trait-ref.stderr
index e057a7842b2..9310b3d7ede 100644
--- a/src/test/ui/unspecified-self-in-trait-ref.stderr
+++ b/src/test/ui/unspecified-self-in-trait-ref.stderr
@@ -31,7 +31,7 @@ LL | | }
    | |_- type parameter `A` must be specified for this
 ...
 LL |       let e = Bar::<usize>::lol();
-   |               ^^^ missing reference to `A`
+   |               ^^^^^^^^^^^^^^^^^ missing reference to `A`
    |
    = note: because of the default `Self` reference, type parameters must be specified on object types