summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2018-01-23 14:58:39 -0800
committerEsteban Küber <esteban@kuber.com.ar>2018-01-23 17:05:12 -0800
commit3a530baec9df99ed62a5b792da92baa6009842e2 (patch)
treef1991a811bca047b237d59e1936df2bab1b1da02
parent3a39b2aa5a68dd07aacab2106db3927f666a485a (diff)
downloadrust-3a530baec9df99ed62a5b792da92baa6009842e2.tar.gz
For E0277 on `for` loops, point at first line
When E0277's span points at a `for` loop, the actual issue is in the element being iterated. Instead of pointing at the entire loop, point only at the first line (when possible) so that the span ends in the element for which E0277 was triggered.
-rw-r--r--src/librustc/traits/error_reporting.rs18
-rw-r--r--src/test/ui/suggestions/for-c-in-str.rs21
-rw-r--r--src/test/ui/suggestions/for-c-in-str.stderr11
3 files changed, 50 insertions, 0 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index e649f1b49df..61456b3b003 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -551,6 +551,24 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let OnUnimplementedNote { message, label }
= self.on_unimplemented_note(trait_ref, obligation);
let have_alt_message = message.is_some() || label.is_some();
+ let span = match self.tcx.sess.codemap().span_to_snippet(span) {
+ Ok(ref s) if s.starts_with("for ") => {
+ // On for loops, this error is caused by the element being iterated
+ // on, but the span points at the entire for loop. Instead of:
+ //
+ // / for c in "asdf" {
+ // | ...
+ // | }
+ // |_^ `&str` is not an iterator
+ //
+ // lets point at:
+ //
+ // for c in "asdf" {
+ // ^^^^^^^^^^^^^^^ `&str` is not an iterator
+ self.tcx.sess.codemap().span_until_char(span, '{')
+ }
+ _ => span,
+ };
let mut err = struct_span_err!(
self.tcx.sess,
diff --git a/src/test/ui/suggestions/for-c-in-str.rs b/src/test/ui/suggestions/for-c-in-str.rs
new file mode 100644
index 00000000000..011886e8073
--- /dev/null
+++ b/src/test/ui/suggestions/for-c-in-str.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 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.
+
+// E0277 should point exclusively at line 14, not the entire for loop span
+
+fn main() {
+ for c in "asdf" {
+ //~^ ERROR the trait bound `&str: std::iter::Iterator` is not satisfied
+ //~| NOTE `&str` is not an iterator
+ //~| HELP the trait `std::iter::Iterator` is not implemented for `&str`
+ //~| NOTE required by `std::iter::IntoIterator::into_iter`
+ println!("");
+ }
+}
diff --git a/src/test/ui/suggestions/for-c-in-str.stderr b/src/test/ui/suggestions/for-c-in-str.stderr
new file mode 100644
index 00000000000..e99a7d7fe55
--- /dev/null
+++ b/src/test/ui/suggestions/for-c-in-str.stderr
@@ -0,0 +1,11 @@
+error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied
+ --> $DIR/for-c-in-str.rs:14:5
+ |
+14 | for c in "asdf" {
+ | ^^^^^^^^^^^^^^^ `&str` is not an iterator; maybe try calling `.iter()` or a similar method
+ |
+ = help: the trait `std::iter::Iterator` is not implemented for `&str`
+ = note: required by `std::iter::IntoIterator::into_iter`
+
+error: aborting due to previous error
+