about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2016-05-19 21:21:06 +0530
committerManish Goregaokar <manishsmail@gmail.com>2016-05-19 21:21:06 +0530
commit14661aeb0a3f78acc0f406f93a329e870af5f0b0 (patch)
treeaec8ca9655c21af6b4929b67f2f939be93bc45ee
parent355d9f98f584891610d6ba4f4df35501b981c011 (diff)
parenta50c82bc3bde5988a8f32ef2b593f0b051545e8a (diff)
downloadrust-14661aeb0a3f78acc0f406f93a329e870af5f0b0.tar.gz
rust-14661aeb0a3f78acc0f406f93a329e870af5f0b0.zip
Rollup merge of #33708 - nham:zero-elided-lifetimes, r=sanxiyn
Only print parameters with elided lifetimes in elision error messages.

When displaying the function parameters for a lifetime elision error message,
this changes it to first filter out the parameters that don't have elided
lifetimes.

Fixes #30255.
-rw-r--r--src/librustc_typeck/astconv.rs22
-rw-r--r--src/test/compile-fail/issue-30255.rs35
2 files changed, 48 insertions, 9 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 9944f453f0a..1df12b63e0a 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -215,15 +215,18 @@ 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 elided_params: Vec<_> = params.into_iter()
+                                       .filter(|info| info.lifetime_count > 0)
+                                       .collect();
+
+    let elided_len = elided_params.len();
+
+    for (i, info) in elided_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 {
@@ -237,13 +240,14 @@ fn report_elision_failure(
                     if have_bound_regions { "free " } else { "" } )
         })[..]);
 
-        if len == 2 && i == 0 {
+        if elided_len == 2 && i == 0 {
             m.push_str(" or ");
-        } else if i + 2 == len {
+        } else if i + 2 == elided_len {
             m.push_str(", or ");
-        } else if i + 1 != len {
+        } else if i != elided_len - 1 {
             m.push_str(", ");
         }
+
     }
 
     if len == 0 {
@@ -252,7 +256,7 @@ fn report_elision_failure(
                     there is no value for it to be borrowed from");
         help!(db,
                    "consider giving it a 'static lifetime");
-    } else if !any_lifetimes {
+    } else if elided_len == 0 {
         help!(db,
                    "this function's return type contains a borrowed value with \
                     an elided lifetime, but the lifetime cannot be derived from \
@@ -260,7 +264,7 @@ fn report_elision_failure(
         help!(db,
                    "consider giving it an explicit bounded or 'static \
                     lifetime");
-    } else if len == 1 {
+    } else if elided_len == 1 {
         help!(db,
                    "this function's return type contains a borrowed value, but \
                     the signature does not say which {} it is borrowed from",
diff --git a/src/test/compile-fail/issue-30255.rs b/src/test/compile-fail/issue-30255.rs
new file mode 100644
index 00000000000..1daa6a61f77
--- /dev/null
+++ b/src/test/compile-fail/issue-30255.rs
@@ -0,0 +1,35 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// Test that lifetime elision error messages correctly omit parameters
+// with no elided lifetimes
+
+struct S<'a> {
+    field: &'a i32,
+}
+
+fn f(a: &S, b: i32) -> &i32 {
+//~^ ERROR missing lifetime specifier [E0106]
+//~^^ HELP does not say which one of `a`'s 2 elided lifetimes it is borrowed from
+    panic!();
+}
+
+fn g(a: &S, b: bool, c: &i32) -> &i32 {
+//~^ ERROR missing lifetime specifier [E0106]
+//~^^ HELP does not say whether it is borrowed from one of `a`'s 2 elided lifetimes or `c`
+    panic!();
+}
+
+fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 {
+//~^ ERROR missing lifetime specifier [E0106]
+//~^^ HELP does not say whether it is borrowed from `a`, one of `c`'s 2 elided lifetimes, or `d`
+    panic!();
+}
+