about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Hamann <nick@wabbo.org>2016-05-18 00:02:04 -0500
committerNick Hamann <nick@wabbo.org>2016-05-18 01:50:21 -0500
commit7fef1628735622ad005245ea2294449720ba7c5c (patch)
treeed567d9c8b1fded86268c913cf9cdc75431512af
parent0667ae93fb72eb25594258e55de9b4ae8f9f02a8 (diff)
downloadrust-7fef1628735622ad005245ea2294449720ba7c5c.tar.gz
rust-7fef1628735622ad005245ea2294449720ba7c5c.zip
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.rs26
-rw-r--r--src/test/compile-fail/issue-30255.rs35
2 files changed, 53 insertions, 8 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 4faefb61056..c3633625436 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -215,15 +215,24 @@ 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();
+
+    let any_lifetimes = if elided_len > 0 {
+        true
+    } else {
+        false
+    };
+
+    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 +246,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 {
@@ -260,7 +270,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!();
+}
+