From 6fba412499e854d6c4cd8e6b22073d5684d549ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 6 Mar 2020 10:55:21 -0800 Subject: [PATCH] Further tweak spans in ast validation errors --- src/librustc_ast_passes/ast_validation.rs | 59 +++++++++++++++---- src/test/ui/async-await/no-const-async.stderr | 4 +- src/test/ui/auto-trait-validation.stderr | 18 ++++-- src/test/ui/issues/issue-23080-2.rs | 3 +- src/test/ui/issues/issue-23080-2.stderr | 11 ++-- src/test/ui/issues/issue-23080.rs | 3 +- src/test/ui/issues/issue-23080.stderr | 13 ++-- .../ui/parser/fn-header-semantic-fail.stderr | 10 ++-- ...inductive-overflow-supertrait-oibit.stderr | 6 +- .../typeck-auto-trait-no-supertraits-2.stderr | 6 +- .../typeck-auto-trait-no-supertraits.stderr | 6 +- 11 files changed, 91 insertions(+), 48 deletions(-) diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index d90e9c4df269..eff58ad4d9aa 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -13,7 +13,7 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use rustc_ast::walk_list; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{error_code, struct_span_err, Applicability}; +use rustc_errors::{error_code, pluralize, struct_span_err, Applicability}; use rustc_parse::validate_attr; use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY; use rustc_session::lint::LintBuffer; @@ -887,30 +887,63 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if is_auto == IsAuto::Yes { // Auto traits cannot have generics, super traits nor contain items. if !generics.params.is_empty() { - struct_span_err!( + let spans: Vec<_> = generics.params.iter().map(|i| i.ident.span).collect(); + let last = spans.iter().last().map(|s| *s); + let len = spans.len(); + let mut err = struct_span_err!( self.session, - item.span, + spans, E0567, "auto traits cannot have generic parameters" - ) - .emit(); + ); + if let Some(span) = last { + err.span_label( + span, + &format!( + "cannot have {these} generic parameter{s}", + these = if len == 1 { "this" } else { "these" }, + s = pluralize!(len) + ), + ); + } + err.span_label( + item.ident.span, + "auto trait cannot have generic parameters", + ); + err.emit(); } if !bounds.is_empty() { - struct_span_err!( + let spans: Vec<_> = bounds.iter().map(|b| b.span()).collect(); + let last = spans.iter().last().map(|s| *s); + let len = spans.len(); + let mut err = struct_span_err!( self.session, - item.span, + spans, E0568, "auto traits cannot have super traits" - ) - .emit(); + ); + if let Some(span) = last { + err.span_label( + span, + &format!( + "cannot have {these} super trait{s}", + these = if len == 1 { "this" } else { "these" }, + s = pluralize!(len) + ), + ); + } + err.span_label(item.ident.span, "auto trait cannot have super traits"); + err.emit(); } if !trait_items.is_empty() { + let spans: Vec<_> = trait_items.iter().map(|i| i.ident.span).collect(); struct_span_err!( self.session, - item.span, + spans, E0380, "auto traits cannot have methods or associated items" ) + .span_label(item.ident.span, "auto trait cannot have items") .emit(); } } @@ -1157,9 +1190,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }) = fk.header() { self.err_handler() - .struct_span_err(span, "functions cannot be both `const` and `async`") + .struct_span_err( + vec![*cspan, *aspan], + "functions cannot be both `const` and `async`", + ) .span_label(*cspan, "`const` because of this") .span_label(*aspan, "`async` because of this") + .span_label(span, "") // Point at the fn header. .emit(); } diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr index 07559cd240bb..4e59bb507676 100644 --- a/src/test/ui/async-await/no-const-async.stderr +++ b/src/test/ui/async-await/no-const-async.stderr @@ -1,8 +1,8 @@ error: functions cannot be both `const` and `async` - --> $DIR/no-const-async.rs:4:1 + --> $DIR/no-const-async.rs:4:5 | LL | pub const async fn x() {} - | ^^^^-----^-----^^^^^^^^^^ + | ----^^^^^-^^^^^---------- | | | | | `async` because of this | `const` because of this diff --git a/src/test/ui/auto-trait-validation.stderr b/src/test/ui/auto-trait-validation.stderr index 51422fab81fd..75919a1f9913 100644 --- a/src/test/ui/auto-trait-validation.stderr +++ b/src/test/ui/auto-trait-validation.stderr @@ -1,20 +1,26 @@ error[E0567]: auto traits cannot have generic parameters - --> $DIR/auto-trait-validation.rs:3:1 + --> $DIR/auto-trait-validation.rs:3:20 | LL | auto trait Generic {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ------- ^ cannot have this generic parameter + | | + | auto trait cannot have generic parameters error[E0568]: auto traits cannot have super traits - --> $DIR/auto-trait-validation.rs:5:1 + --> $DIR/auto-trait-validation.rs:5:20 | LL | auto trait Bound : Copy {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ----- ^^^^ cannot have this super trait + | | + | auto trait cannot have super traits error[E0380]: auto traits cannot have methods or associated items - --> $DIR/auto-trait-validation.rs:7:1 + --> $DIR/auto-trait-validation.rs:7:25 | LL | auto trait MyTrait { fn foo() {} } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------- ^^^ + | | + | auto trait cannot have items error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-23080-2.rs b/src/test/ui/issues/issue-23080-2.rs index 319aa2a5cce9..d20bb4bd9072 100644 --- a/src/test/ui/issues/issue-23080-2.rs +++ b/src/test/ui/issues/issue-23080-2.rs @@ -3,8 +3,7 @@ #![feature(optin_builtin_traits)] unsafe auto trait Trait { -//~^ ERROR E0380 - type Output; + type Output; //~ ERROR E0380 } fn call_method(x: T) {} diff --git a/src/test/ui/issues/issue-23080-2.stderr b/src/test/ui/issues/issue-23080-2.stderr index 1103de0d9104..fcd1ecfa9828 100644 --- a/src/test/ui/issues/issue-23080-2.stderr +++ b/src/test/ui/issues/issue-23080-2.stderr @@ -1,11 +1,10 @@ error[E0380]: auto traits cannot have methods or associated items - --> $DIR/issue-23080-2.rs:5:1 + --> $DIR/issue-23080-2.rs:6:10 | -LL | / unsafe auto trait Trait { -LL | | -LL | | type Output; -LL | | } - | |_^ +LL | unsafe auto trait Trait { + | ----- auto trait cannot have items +LL | type Output; + | ^^^^^^ error[E0275]: overflow evaluating the requirement `<() as Trait>::Output` | diff --git a/src/test/ui/issues/issue-23080.rs b/src/test/ui/issues/issue-23080.rs index fdfee6981447..fa5c35316bc2 100644 --- a/src/test/ui/issues/issue-23080.rs +++ b/src/test/ui/issues/issue-23080.rs @@ -1,8 +1,7 @@ #![feature(optin_builtin_traits)] unsafe auto trait Trait { -//~^ ERROR E0380 - fn method(&self) { + fn method(&self) { //~ ERROR E0380 println!("Hello"); } } diff --git a/src/test/ui/issues/issue-23080.stderr b/src/test/ui/issues/issue-23080.stderr index 91c272173242..dbb9861b5784 100644 --- a/src/test/ui/issues/issue-23080.stderr +++ b/src/test/ui/issues/issue-23080.stderr @@ -1,13 +1,10 @@ error[E0380]: auto traits cannot have methods or associated items - --> $DIR/issue-23080.rs:3:1 + --> $DIR/issue-23080.rs:4:8 | -LL | / unsafe auto trait Trait { -LL | | -LL | | fn method(&self) { -LL | | println!("Hello"); -LL | | } -LL | | } - | |_^ +LL | unsafe auto trait Trait { + | ----- auto trait cannot have items +LL | fn method(&self) { + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr index 1142cee9851b..d6b36fbb7145 100644 --- a/src/test/ui/parser/fn-header-semantic-fail.stderr +++ b/src/test/ui/parser/fn-header-semantic-fail.stderr @@ -2,7 +2,7 @@ error: functions cannot be both `const` and `async` --> $DIR/fn-header-semantic-fail.rs:13:5 | LL | const async unsafe extern "C" fn ff5() {} // OK. - | -----^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^-^^^^^------------------------------ | | | | | `async` because of this | `const` because of this @@ -45,7 +45,7 @@ error: functions cannot be both `const` and `async` --> $DIR/fn-header-semantic-fail.rs:21:9 | LL | const async unsafe extern "C" fn ft5(); - | -----^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^-^^^^^---------------------------- | | | | | `async` because of this | `const` because of this @@ -88,7 +88,7 @@ error: functions cannot be both `const` and `async` --> $DIR/fn-header-semantic-fail.rs:34:9 | LL | const async unsafe extern "C" fn ft5() {} - | -----^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^-^^^^^------------------------------ | | | | | `async` because of this | `const` because of this @@ -97,7 +97,7 @@ error: functions cannot be both `const` and `async` --> $DIR/fn-header-semantic-fail.rs:46:9 | LL | const async unsafe extern "C" fn fi5() {} - | -----^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^-^^^^^------------------------------ | | | | | `async` because of this | `const` because of this @@ -160,7 +160,7 @@ error: functions cannot be both `const` and `async` --> $DIR/fn-header-semantic-fail.rs:55:9 | LL | const async unsafe extern "C" fn fe5(); - | -----^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^-^^^^^---------------------------- | | | | | `async` because of this | `const` because of this diff --git a/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr b/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr index 63182a6bd958..03d05f4c928a 100644 --- a/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr +++ b/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr @@ -1,8 +1,10 @@ error[E0568]: auto traits cannot have super traits - --> $DIR/traits-inductive-overflow-supertrait-oibit.rs:7:1 + --> $DIR/traits-inductive-overflow-supertrait-oibit.rs:7:19 | LL | auto trait Magic: Copy {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ----- ^^^^ cannot have this super trait + | | + | auto trait cannot have super traits error[E0277]: the trait bound `NoClone: std::marker::Copy` is not satisfied --> $DIR/traits-inductive-overflow-supertrait-oibit.rs:15:23 diff --git a/src/test/ui/typeck/typeck-auto-trait-no-supertraits-2.stderr b/src/test/ui/typeck/typeck-auto-trait-no-supertraits-2.stderr index 8755bcded9d2..45c95b191bd5 100644 --- a/src/test/ui/typeck/typeck-auto-trait-no-supertraits-2.stderr +++ b/src/test/ui/typeck/typeck-auto-trait-no-supertraits-2.stderr @@ -1,8 +1,10 @@ error[E0568]: auto traits cannot have super traits - --> $DIR/typeck-auto-trait-no-supertraits-2.rs:3:1 + --> $DIR/typeck-auto-trait-no-supertraits-2.rs:3:20 | LL | auto trait Magic : Sized where Option : Magic {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ----- ^^^^^ cannot have this super trait + | | + | auto trait cannot have super traits error: aborting due to previous error diff --git a/src/test/ui/typeck/typeck-auto-trait-no-supertraits.stderr b/src/test/ui/typeck/typeck-auto-trait-no-supertraits.stderr index 5a3888349095..094f5d7dd24f 100644 --- a/src/test/ui/typeck/typeck-auto-trait-no-supertraits.stderr +++ b/src/test/ui/typeck/typeck-auto-trait-no-supertraits.stderr @@ -1,8 +1,10 @@ error[E0568]: auto traits cannot have super traits - --> $DIR/typeck-auto-trait-no-supertraits.rs:27:1 + --> $DIR/typeck-auto-trait-no-supertraits.rs:27:19 | LL | auto trait Magic: Copy {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ----- ^^^^ cannot have this super trait + | | + | auto trait cannot have super traits error: aborting due to previous error