about summary refs log tree commit diff
diff options
context:
space:
mode:
-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
+