From 439ff69d909a0add54b1ea1e093bc838693d1e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 11 Apr 2017 04:40:31 -0700 Subject: [PATCH] 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 ``` --- src/librustc/traits/error_reporting.rs | 28 +++++++++----------- src/libsyntax/codemap.rs | 19 +++++++++++++ src/test/ui/resolve/issue-3907-2.stderr | 2 +- src/test/{compile-fail => ui/span}/E0072.rs | 3 +-- src/test/ui/span/E0072.stderr | 10 +++++++ src/test/ui/span/multiline-span-E0072.rs | 20 ++++++++++++++ src/test/ui/span/multiline-span-E0072.stderr | 16 +++++++++++ 7 files changed, 80 insertions(+), 18 deletions(-) rename src/test/{compile-fail => ui/span}/E0072.rs (84%) create mode 100644 src/test/ui/span/E0072.stderr create mode 100644 src/test/ui/span/multiline-span-E0072.rs create mode 100644 src/test/ui/span/multiline-span-E0072.stderr diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 152dd6ac3000f..dc85353c21986 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 4d67390d44234..da2d0a33d1a10 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> { 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 ef02250e21cdf..2ef8c830eb2fe 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 similarity index 84% rename from src/test/compile-fail/E0072.rs rename to src/test/ui/span/E0072.rs index e6de7921b3036..18ade4f1ab68e 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, } diff --git a/src/test/ui/span/E0072.stderr b/src/test/ui/span/E0072.stderr new file mode 100644 index 0000000000000..5204390ef9d2a --- /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 0000000000000..323e7fb5a42c0 --- /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 or the MIT license +// , 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, +} + +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 0000000000000..58cdc50230063 --- /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, +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 +