diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 267d84cc531..9b01f8899b5 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -914,13 +914,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { new_trait_ref.to_predicate()); if selcx.evaluate_obligation(&new_obligation) { + let sp = self.tcx.sess.codemap() + .span_take_while(span, |c| c.is_whitespace() || *c == '&'); + let remove_refs = refs_remaining + 1; + let format_str = format!("consider removing {} leading `&`-references", + remove_refs); - err.span_suggestion_short(span, - &format!("consider removing {} leading `&`-references", - remove_refs), - String::from("")); - + err.span_suggestion_short(sp, &format_str, String::from("")); break; } } else { diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index a1aec052088..324d57c1194 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -697,6 +697,22 @@ impl CodeMap { sp } + /// Given a `Span`, get a shorter one until `predicate` yields false. + pub fn span_take_while

(&self, sp: Span, predicate: P) -> Span + where P: for <'r> FnMut(&'r char) -> bool + { + if let Ok(snippet) = self.span_to_snippet(sp) { + let offset = snippet.chars() + .take_while(predicate) + .map(|c| c.len_utf8()) + .sum::(); + + sp.with_hi(BytePos(sp.lo().0 + (offset as u32))) + } else { + sp + } + } + pub fn def_span(&self, sp: Span) -> Span { self.span_until_char(sp, '{') } diff --git a/src/test/ui/suggest-remove-refs-1.stderr b/src/test/ui/suggest-remove-refs-1.stderr index fe4ab2c4ee0..c47b4d283d7 100644 --- a/src/test/ui/suggest-remove-refs-1.stderr +++ b/src/test/ui/suggest-remove-refs-1.stderr @@ -2,10 +2,10 @@ error[E0277]: the trait bound `&std::iter::Enumerate $DIR/suggest-remove-refs-1.rs:14:19 | LL | for (i, n) in &v.iter().enumerate() { - | ^^^^^^^^^^^^^^^^^^^^^ + | -^^^^^^^^^^^^^^^^^^^^ | | | `&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method - | help: consider removing 1 references `&`: `v.iter().enumerate()` + | help: consider removing 1 leading `&`-references | = help: the trait `std::iter::Iterator` is not implemented for `&std::iter::Enumerate>` = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/suggest-remove-refs-2.stderr b/src/test/ui/suggest-remove-refs-2.stderr index 243ddcfe125..fdd654ea392 100644 --- a/src/test/ui/suggest-remove-refs-2.stderr +++ b/src/test/ui/suggest-remove-refs-2.stderr @@ -2,10 +2,10 @@ error[E0277]: the trait bound `&&&&&std::iter::Enumerate $DIR/suggest-remove-refs-2.rs:14:19 | LL | for (i, n) in & & & & &v.iter().enumerate() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ---------^^^^^^^^^^^^^^^^^^^^ | | | `&&&&&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method - | help: consider removing 5 references `&`: `v.iter().enumerate()` + | help: consider removing 5 leading `&`-references | = help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate>` = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/suggest-remove-refs-3.stderr b/src/test/ui/suggest-remove-refs-3.stderr index 83f3826642b..b0920a0fa52 100644 --- a/src/test/ui/suggest-remove-refs-3.stderr +++ b/src/test/ui/suggest-remove-refs-3.stderr @@ -1,21 +1,18 @@ error[E0277]: the trait bound `&&&&&std::iter::Enumerate>: std::iter::Iterator` is not satisfied --> $DIR/suggest-remove-refs-3.rs:14:19 | -LL | for (i, n) in & & & - | ___________________^ -LL | | & &v -LL | | .iter() -LL | | .enumerate() { - | |____________________^ `&&&&&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method +LL | for (i, n) in & & & + | ___________________^ + | |___________________| + | || +LL | || & &v + | ||___________- help: consider removing 5 leading `&`-references +LL | | .iter() +LL | | .enumerate() { + | |_____________________^ `&&&&&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method | = help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate>` = note: required by `std::iter::IntoIterator::into_iter` -help: consider removing 5 references `&` - | -LL | for (i, n) in v -LL | .iter() -LL | .enumerate() { - | error: aborting due to previous error