Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
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
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just let any_lifetimes = elided_len > 0.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better, replace !any_lifetimes below with elided_len == 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I've done this.


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
Original file line number Diff line number Diff line change
@@ -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!();
}