Skip to content

Commit

Permalink
Only print parameters with elided lifetimes in elision error messages.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Nick Hamann committed May 18, 2016
1 parent 0667ae9 commit 7fef162
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 8 deletions.
26 changes: 18 additions & 8 deletions src/librustc_typeck/astconv.rs
Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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",
Expand Down
35 changes: 35 additions & 0 deletions 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!();
}

0 comments on commit 7fef162

Please sign in to comment.