about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/resolve_lifetime.rs99
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr5
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr5
-rw-r--r--src/test/ui/foreign-fn-return-lifetime.stderr5
-rw-r--r--src/test/ui/issues/issue-13497.stderr5
-rw-r--r--src/test/ui/issues/issue-26638.stderr10
-rw-r--r--src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr20
-rw-r--r--src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr5
-rw-r--r--src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr5
9 files changed, 54 insertions, 105 deletions
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 86db74b78b9..7547e803915 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -2235,22 +2235,46 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         };
 
         let mut err = report_missing_lifetime_specifiers(self.tcx.sess, span, lifetime_refs.len());
+        let mut add_label = true;
 
         if let Some(params) = error {
             if lifetime_refs.len() == 1 {
-                self.report_elision_failure(&mut err, params, span);
+                add_label = add_label && self.report_elision_failure(&mut err, params, span);
             }
         }
+        if add_label {
+            add_missing_lifetime_specifiers_label(&mut err, span, lifetime_refs.len());
+        }
 
         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_with_applicability(span, msg, sugg, applicability);
+                false
+            }
+            Err(_) => {
+                db.help(msg);
+                true
+            }
+        }
+    }
+
     fn report_elision_failure(
         &mut self,
         db: &mut DiagnosticBuilder<'_>,
         params: &[ElisionFailureInfo],
         span: Span,
-    ) {
+    ) -> bool {
         let mut m = String::new();
         let len = params.len();
 
@@ -2305,29 +2329,7 @@ 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"
             );
-            let msg = "consider giving it a 'static lifetime";
-            match self.tcx.sess.source_map().span_to_snippet(span) {
-                Ok(ref snippet) if snippet == "&" => db.span_suggestion_with_applicability(
-                    span,
-                    msg,
-                    "&'static ".to_owned(),
-                    Applicability::MachineApplicable,
-                ),
-                Ok(ref snippet)
-                if snippet == "'_" => db.span_suggestion_with_applicability(
-                    span,
-                    msg,
-                    "'static".to_owned(),
-                    Applicability::MachineApplicable,
-                ),
-                Ok(ref snippet) => db.span_suggestion_with_applicability(
-                    span,
-                    msg,
-                    format!("{} + 'static", snippet),
-                    Applicability::MaybeIncorrect,
-                ),
-                Err(_) => db.help(msg),
-            };
+            self.suggest_lifetime(db, span, "consider giving it a 'static lifetime")
         } else if elided_len == 0 {
             help!(
                 db,
@@ -2336,28 +2338,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                  the arguments"
             );
             let msg = "consider giving it an explicit bounded or 'static lifetime";
-            match self.tcx.sess.source_map().span_to_snippet(span) {
-                Ok(ref snippet) if snippet == "&" => db.span_suggestion_with_applicability(
-                    span,
-                    msg,
-                     "&'static ".to_owned(),
-                    Applicability::MachineApplicable,
-                ),
-                Ok(ref snippet)
-                if snippet == "'_" => db.span_suggestion_with_applicability(
-                    span,
-                    msg,
-                    "'static".to_owned(),
-                    Applicability::MachineApplicable,
-                ),
-                Ok(ref snippet) => db.span_suggestion_with_applicability(
-                    span,
-                    msg,
-                    format!("{} + 'static", snippet),
-                    Applicability::MaybeIncorrect,
-                ),
-                Err(_) => db.help(msg),
-            };
+            self.suggest_lifetime(db, span, msg)
         } else if elided_len == 1 {
             help!(
                 db,
@@ -2365,6 +2346,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                  the signature does not say which {} it is borrowed from",
                 m
             );
+            true
         } else {
             help!(
                 db,
@@ -2372,6 +2354,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                  the signature does not say whether it is borrowed from {}",
                 m
             );
+            true
         }
     }
 
@@ -2785,26 +2768,28 @@ fn insert_late_bound_lifetimes(
     }
 }
 
-pub fn report_missing_lifetime_specifiers(
+fn report_missing_lifetime_specifiers(
     sess: &Session,
     span: Span,
     count: usize,
 ) -> DiagnosticBuilder<'_> {
-    let mut err = struct_span_err!(
+    struct_span_err!(
         sess,
         span,
         E0106,
         "missing lifetime specifier{}",
         if count > 1 { "s" } else { "" }
-    );
+    )
+}
 
-    let msg: Cow<'static, str> = if count > 1 {
-        format!("expected {} lifetime parameters", count).into()
+fn add_missing_lifetime_specifiers_label(
+    err: &mut DiagnosticBuilder<'_>,
+    span: Span,
+    count: usize,
+) {
+    if count > 1 {
+        err.span_label(span, format!("expected {} lifetime parameters", count));
     } else {
-        "expected lifetime parameter".into()
+        err.span_label(span, "expected lifetime parameter");
     };
-
-    err.span_label(span, msg);
-
-    err
 }
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 4336aaf71ba..6b9d4ebb298 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,10 +2,7 @@ error[E0106]: missing lifetime specifier
   --> $DIR/bound-lifetime-in-binding-only.rs:62:23
    |
 LL | fn elision<T: Fn() -> &i32>() {
-   |                       ^
-   |                       |
-   |                       expected lifetime parameter
-   |                       help: consider giving it a 'static lifetime: `&'static`
+   |                       ^ help: consider giving it a 'static lifetime: `&'static`
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
 
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 fbc4df54225..7906f0a30e4 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,10 +2,7 @@ error[E0106]: missing lifetime specifier
   --> $DIR/bound-lifetime-in-return-only.rs:44:23
    |
 LL | fn elision(_: fn() -> &i32) {
-   |                       ^
-   |                       |
-   |                       expected lifetime parameter
-   |                       help: consider giving it a 'static lifetime: `&'static`
+   |                       ^ help: consider giving it a 'static lifetime: `&'static`
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
 
diff --git a/src/test/ui/foreign-fn-return-lifetime.stderr b/src/test/ui/foreign-fn-return-lifetime.stderr
index 4e52d6044c4..583487656f2 100644
--- a/src/test/ui/foreign-fn-return-lifetime.stderr
+++ b/src/test/ui/foreign-fn-return-lifetime.stderr
@@ -2,10 +2,7 @@ error[E0106]: missing lifetime specifier
   --> $DIR/foreign-fn-return-lifetime.rs:15:19
    |
 LL |     pub fn f() -> &u8; //~ ERROR missing lifetime specifier
-   |                   ^
-   |                   |
-   |                   expected lifetime parameter
-   |                   help: consider giving it a 'static lifetime: `&'static`
+   |                   ^ help: consider giving it a 'static lifetime: `&'static`
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
 
diff --git a/src/test/ui/issues/issue-13497.stderr b/src/test/ui/issues/issue-13497.stderr
index 88b6a831d7e..e592452b899 100644
--- a/src/test/ui/issues/issue-13497.stderr
+++ b/src/test/ui/issues/issue-13497.stderr
@@ -2,10 +2,7 @@ error[E0106]: missing lifetime specifier
   --> $DIR/issue-13497.rs:12:5
    |
 LL |     &str //~ ERROR missing lifetime specifier
-   |     ^
-   |     |
-   |     expected lifetime parameter
-   |     help: consider giving it a 'static lifetime: `&'static`
+   |     ^ help: consider giving it a 'static lifetime: `&'static`
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
 
diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr
index e4464b2dd31..0ac6316f0dc 100644
--- a/src/test/ui/issues/issue-26638.stderr
+++ b/src/test/ui/issues/issue-26638.stderr
@@ -10,10 +10,7 @@ error[E0106]: missing lifetime specifier
   --> $DIR/issue-26638.rs:14:40
    |
 LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
-   |                                        ^
-   |                                        |
-   |                                        expected lifetime parameter
-   |                                        help: consider giving it an explicit bounded or 'static lifetime: `&'static`
+   |                                        ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
    |
    = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
 
@@ -21,10 +18,7 @@ error[E0106]: missing lifetime specifier
   --> $DIR/issue-26638.rs:17:22
    |
 LL | fn parse_type_3() -> &str { unimplemented!() }
-   |                      ^
-   |                      |
-   |                      expected lifetime parameter
-   |                      help: consider giving it a 'static lifetime: `&'static`
+   |                      ^ help: consider giving it a 'static lifetime: `&'static`
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
 
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 9962dbc9812..4c7a1b5ea9f 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,10 +2,7 @@ error[E0106]: missing lifetime specifier
   --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:12:11
    |
 LL | fn f() -> &isize {    //~ ERROR missing lifetime specifier
-   |           ^
-   |           |
-   |           expected lifetime parameter
-   |           help: consider giving it a 'static lifetime: `&'static`
+   |           ^ help: consider giving it a 'static lifetime: `&'static`
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
 
@@ -29,10 +26,7 @@ error[E0106]: missing lifetime specifier
   --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:31:20
    |
 LL | fn i(_x: isize) -> &isize { //~ ERROR missing lifetime specifier
-   |                    ^
-   |                    |
-   |                    expected lifetime parameter
-   |                    help: consider giving it an explicit bounded or 'static lifetime: `&'static`
+   |                    ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
    |
    = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
 
@@ -40,10 +34,7 @@ error[E0106]: missing lifetime specifier
   --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:44:24
    |
 LL | fn j(_x: StaticStr) -> &isize { //~ ERROR missing lifetime specifier
-   |                        ^
-   |                        |
-   |                        expected lifetime parameter
-   |                        help: consider giving it an explicit bounded or 'static lifetime: `&'static`
+   |                        ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
    |
    = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
 
@@ -51,10 +42,7 @@ error[E0106]: missing lifetime specifier
   --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:50:49
    |
 LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize {
-   |                                                 ^
-   |                                                 |
-   |                                                 expected lifetime parameter
-   |                                                 help: consider giving it an explicit bounded or 'static lifetime: `&'static`
+   |                                                 ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
    |
    = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
 
diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr
index 426941b949d..ab429b9df06 100644
--- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr
+++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr
@@ -6,10 +6,7 @@ error[E0106]: missing lifetime specifier
   --> $DIR/lifetime-elision-return-type-trait.rs:8:44
    |
 LL | fn foo() -> impl Future<Item=(), Error=Box<Error>> {
-   |                                            ^^^^^
-   |                                            |
-   |                                            expected lifetime parameter
-   |                                            help: consider giving it a 'static lifetime: `Error + 'static`
+   |                                            ^^^^^ help: consider giving it a 'static lifetime: `Error + 'static`
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
 
diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
index b0da67a7c34..4319843291a 100644
--- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
+++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
@@ -26,10 +26,7 @@ error[E0106]: missing lifetime specifier
   --> $DIR/underscore-lifetime-binders.rs:24:29
    |
 LL | fn meh() -> Box<for<'_> Meh<'_>> //~ ERROR cannot be used here
-   |                             ^^
-   |                             |
-   |                             expected lifetime parameter
-   |                             help: consider giving it a 'static lifetime: `'static`
+   |                             ^^ help: consider giving it a 'static lifetime: `'static`
    |
    = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from