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+'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() {}