about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-12-05 12:52:30 +0000
committerbors <bors@rust-lang.org>2015-12-05 12:52:30 +0000
commitd75f861518cb3b43acd1ae774fd13605a5dfd2d9 (patch)
tree2c19d2cf04d30e0ab8a457d9143dc2ec26624987
parent427514f550e69798e5146de54aff8d7816c523c5 (diff)
parent829e8bf2a51b56681fc16bd71140668a1c93d9b4 (diff)
downloadrust-d75f861518cb3b43acd1ae774fd13605a5dfd2d9.tar.gz
rust-d75f861518cb3b43acd1ae774fd13605a5dfd2d9.zip
Auto merge of #30102 - jFransham:feature/better-lifetime-errors, r=Manishearth
Fixes #30086
-rw-r--r--src/librustc_typeck/astconv.rs25
-rw-r--r--src/test/compile-fail/issue-26638.rs6
2 files changed, 24 insertions, 7 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 7de262dfa5b..d8fc76c76f9 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -203,11 +203,15 @@ fn report_elision_failure(
 {
     let mut m = String::new();
     let len = params.len();
+    let mut any_lifetimes = false;
+
     for (i, info) in params.into_iter().enumerate() {
         let ElisionFailureInfo {
             name, lifetime_count: n, have_bound_regions
         } = info;
 
+        any_lifetimes = any_lifetimes || (n > 0);
+
         let help_name = if name.is_empty() {
             format!("argument {}", i + 1)
         } else {
@@ -229,17 +233,26 @@ fn report_elision_failure(
             m.push_str(", ");
         }
     }
-    if len == 1 {
-        fileline_help!(tcx.sess, default_span,
-                       "this function's return type contains a borrowed value, but \
-                        the signature does not say which {} it is borrowed from",
-                       m);
-    } else if len == 0 {
+
+    if len == 0 {
         fileline_help!(tcx.sess, default_span,
                        "this function's return type contains a borrowed value, but \
                         there is no value for it to be borrowed from");
         fileline_help!(tcx.sess, default_span,
                        "consider giving it a 'static lifetime");
+    } else if !any_lifetimes {
+        fileline_help!(tcx.sess, default_span,
+                       "this function's return type contains a borrowed value with \
+                        an elided lifetime, but the lifetime cannot be derived from \
+                        the arguments");
+        fileline_help!(tcx.sess, default_span,
+                       "consider giving it an explicit bounded or 'static \
+                        lifetime");
+    } else if len == 1 {
+        fileline_help!(tcx.sess, default_span,
+                       "this function's return type contains a borrowed value, but \
+                        the signature does not say which {} it is borrowed from",
+                       m);
     } else {
         fileline_help!(tcx.sess, default_span,
                        "this function's return type contains a borrowed value, but \
diff --git a/src/test/compile-fail/issue-26638.rs b/src/test/compile-fail/issue-26638.rs
index edb9ab47fc6..010803bf25b 100644
--- a/src/test/compile-fail/issue-26638.rs
+++ b/src/test/compile-fail/issue-26638.rs
@@ -14,6 +14,10 @@ fn parse_type(iter: Box<Iterator<Item=&str>+'static>) -> &str { iter.next() }
 
 fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
 //~^ ERROR missing lifetime specifier [E0106]
-//~^^ HELP 0 elided free lifetimes
+//~^^ HELP lifetime cannot be derived
+
+fn parse_type_3() -> &str { unimplemented!() }
+//~^ ERROR missing lifetime specifier [E0106]
+//~^^ HELP no value for it to be borrowed from
 
 fn main() {}