about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2017-04-11 04:40:31 -0700
committerEsteban Küber <esteban@kuber.com.ar>2017-04-12 01:10:48 -0700
commit439ff69d909a0add54b1ea1e093bc838693d1e4e (patch)
tree3a779dd6ae7d0fd40ad34002289b888285642c30
parentd616f47cd03a65fed13be2ee5527f24f6a4f7f92 (diff)
downloadrust-439ff69d909a0add54b1ea1e093bc838693d1e4e.tar.gz
rust-439ff69d909a0add54b1ea1e093bc838693d1e4e.zip
Add a way to get shorter spans until `char` for pointing at defs
```rust
error[E0072]: recursive type `X` has infinite size
  --> file.rs:10:1
   |
10 | struct X {
   | ^^^^^^^^ recursive type has infinite size
   |
   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `X` representable
```

vs

```rust
error[E0072]: recursive type `X` has infinite size
  --> file.rs:10:1
   |
10 |   struct X {
   |  _^ starting here...
11 | |     x: X,
12 | | }
   | |_^ ...ending here: recursive type has infinite size
   |
   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `X` representable
```
-rw-r--r--src/librustc/traits/error_reporting.rs28
-rw-r--r--src/libsyntax/codemap.rs19
-rw-r--r--src/test/ui/resolve/issue-3907-2.stderr2
-rw-r--r--src/test/ui/span/E0072.rs (renamed from src/test/compile-fail/E0072.rs)3
-rw-r--r--src/test/ui/span/E0072.stderr10
-rw-r--r--src/test/ui/span/multiline-span-E0072.rs20
-rw-r--r--src/test/ui/span/multiline-span-E0072.stderr16
7 files changed, 80 insertions, 18 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 152dd6ac300..dc85353c219 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -293,22 +293,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                 Some(val) => Some(val),
                                 None => {
                                     span_err!(self.tcx.sess, err_sp, E0272,
-                                                    "the #[rustc_on_unimplemented] \
-                                                            attribute on \
-                                                            trait definition for {} refers to \
-                                                            non-existent type parameter {}",
-                                                            trait_str, s);
+                                              "the #[rustc_on_unimplemented] attribute on trait \
+                                               definition for {} refers to non-existent type \
+                                               parameter {}",
+                                              trait_str, s);
                                     errored = true;
                                     None
                                 }
                             },
                             _ => {
                                 span_err!(self.tcx.sess, err_sp, E0273,
-                                            "the #[rustc_on_unimplemented] attribute \
-                                            on trait definition for {} must have \
-                                            named format arguments, eg \
-                                            `#[rustc_on_unimplemented = \
-                                            \"foo {{T}}\"]`", trait_str);
+                                          "the #[rustc_on_unimplemented] attribute on trait \
+                                           definition for {} must have named format arguments, eg \
+                                           `#[rustc_on_unimplemented = \"foo {{T}}\"]`",
+                                          trait_str);
                                 errored = true;
                                 None
                             }
@@ -449,8 +447,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                              "impl has stricter requirements than trait");
 
         if let Some(trait_item_span) = self.tcx.hir.span_if_local(trait_item_def_id) {
-            err.span_label(trait_item_span,
-                           &format!("definition of `{}` from trait", item_name));
+            let span = self.tcx.sess.codemap().def_span(trait_item_span);
+            err.span_label(span, &format!("definition of `{}` from trait", item_name));
         }
 
         err.span_label(
@@ -652,6 +650,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     {
         assert!(type_def_id.is_local());
         let span = self.hir.span_if_local(type_def_id).unwrap();
+        let span = self.sess.codemap().def_span(span);
         let mut err = struct_span_err!(self.sess, span, E0072,
                                        "recursive type `{}` has infinite size",
                                        self.item_path_str(type_def_id));
@@ -669,13 +668,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                                       -> DiagnosticBuilder<'tcx>
     {
         let trait_str = self.item_path_str(trait_def_id);
+        let span = self.sess.codemap().def_span(span);
         let mut err = struct_span_err!(
             self.sess, span, E0038,
             "the trait `{}` cannot be made into an object",
             trait_str);
-        err.span_label(span, &format!(
-            "the trait `{}` cannot be made into an object", trait_str
-        ));
+        err.span_label(span, &format!("the trait `{}` cannot be made into an object", trait_str));
 
         let mut reported_violations = FxHashSet();
         for violation in violations {
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 4d67390d442..da2d0a33d1a 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -441,6 +441,25 @@ impl CodeMap {
         }
     }
 
+    /// Given a `Span`, try to get a shorter span ending before the first occurrence of `c` `char`
+    pub fn span_until_char(&self, sp: Span, c: char) -> Span {
+        match self.span_to_snippet(sp) {
+            Ok(snippet) => {
+                let snippet = snippet.split(c).nth(0).unwrap_or("").trim_right();
+                if snippet.len() > 0 && !snippet.contains('\n') {
+                    Span { hi: BytePos(sp.lo.0 + snippet.len() as u32), ..sp }
+                } else {
+                    sp
+                }
+            }
+            _ => sp,
+        }
+    }
+
+    pub fn def_span(&self, sp: Span) -> Span {
+        self.span_until_char(sp, '{')
+    }
+
     pub fn get_filemap(&self, filename: &str) -> Option<Rc<FileMap>> {
         for fm in self.files.borrow().iter() {
             if filename == fm.name {
diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr
index ef02250e21c..2ef8c830eb2 100644
--- a/src/test/ui/resolve/issue-3907-2.stderr
+++ b/src/test/ui/resolve/issue-3907-2.stderr
@@ -2,7 +2,7 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
   --> $DIR/issue-3907-2.rs:20:1
    |
 20 | fn bar(_x: Foo) {}
-   | ^^^^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object
+   | ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object
    |
    = note: method `bar` has no receiver
 
diff --git a/src/test/compile-fail/E0072.rs b/src/test/ui/span/E0072.rs
index e6de7921b30..18ade4f1ab6 100644
--- a/src/test/compile-fail/E0072.rs
+++ b/src/test/ui/span/E0072.rs
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct ListNode { //~ ERROR E0072
-                  //~| NOTE recursive type has infinite size
+struct ListNode {
     head: u8,
     tail: Option<ListNode>,
 }
diff --git a/src/test/ui/span/E0072.stderr b/src/test/ui/span/E0072.stderr
new file mode 100644
index 00000000000..5204390ef9d
--- /dev/null
+++ b/src/test/ui/span/E0072.stderr
@@ -0,0 +1,10 @@
+error[E0072]: recursive type `ListNode` has infinite size
+  --> $DIR/E0072.rs:11:1
+   |
+11 | struct ListNode {
+   | ^^^^^^^^^^^^^^^ recursive type has infinite size
+   |
+   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/span/multiline-span-E0072.rs b/src/test/ui/span/multiline-span-E0072.rs
new file mode 100644
index 00000000000..323e7fb5a42
--- /dev/null
+++ b/src/test/ui/span/multiline-span-E0072.rs
@@ -0,0 +1,20 @@
+// Copyright 2017 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.
+
+// It should just use the entire body instead of pointing at the next two lines
+struct
+ListNode
+{
+    head: u8,
+    tail: Option<ListNode>,
+}
+
+fn main() {
+}
diff --git a/src/test/ui/span/multiline-span-E0072.stderr b/src/test/ui/span/multiline-span-E0072.stderr
new file mode 100644
index 00000000000..58cdc502300
--- /dev/null
+++ b/src/test/ui/span/multiline-span-E0072.stderr
@@ -0,0 +1,16 @@
+error[E0072]: recursive type `ListNode` has infinite size
+  --> $DIR/multiline-span-E0072.rs:12:1
+   |
+12 |   struct
+   |  _^ starting here...
+13 | | ListNode
+14 | | {
+15 | |     head: u8,
+16 | |     tail: Option<ListNode>,
+17 | | }
+   | |_^ ...ending here: recursive type has infinite size
+   |
+   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable
+
+error: aborting due to previous error
+