From e34fd546111c3cad82c91a9f466284d55a53e5fb Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Sun, 3 Oct 2021 17:58:10 +0200 Subject: [PATCH] Deny `where` clauses on `auto` traits --- .../rustc_ast_passes/src/ast_validation.rs | 49 ++++++++++++++----- .../auto-traits/auto-trait-validation.fixed | 13 +++++ .../ui/auto-traits/auto-trait-validation.rs | 8 ++- .../auto-traits/auto-trait-validation.stderr | 31 +++++++----- src/test/ui/auto-traits/issue-23080-2.stderr | 6 +-- src/test/ui/auto-traits/issue-23080.stderr | 13 +++-- src/test/ui/auto-traits/issue-84075.rs | 16 ++++++ src/test/ui/auto-traits/issue-84075.stderr | 11 +++++ .../typeck-auto-trait-no-supertraits-2.rs | 1 + .../typeck-auto-trait-no-supertraits-2.stderr | 18 +++++-- .../typeck-auto-trait-no-supertraits.stderr | 8 +-- .../supertrait-auto-trait.stderr | 8 +-- 12 files changed, 135 insertions(+), 47 deletions(-) create mode 100644 src/test/ui/auto-traits/auto-trait-validation.fixed create mode 100644 src/test/ui/auto-traits/issue-84075.rs create mode 100644 src/test/ui/auto-traits/issue-84075.stderr diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 24108f779c818..0f5580db30f63 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -683,31 +683,53 @@ impl<'a> AstValidator<'a> { } } + fn emit_e0568(&self, span: Span, ident_span: Span) { + struct_span_err!( + self.session, + span, + E0568, + "auto traits cannot have super traits or lifetime bounds" + ) + .span_label(ident_span, "auto trait cannot have super traits or lifetime bounds") + .span_suggestion( + span, + "remove the super traits or lifetime bounds", + String::new(), + Applicability::MachineApplicable, + ) + .emit(); + } + fn deny_super_traits(&self, bounds: &GenericBounds, ident_span: Span) { - if let [first @ last] | [first, .., last] = &bounds[..] { - let span = first.span().to(last.span()); - struct_span_err!(self.session, span, E0568, "auto traits cannot have super traits") - .span_label(ident_span, "auto trait cannot have super traits") - .span_suggestion( - span, - "remove the super traits", - String::new(), - Applicability::MachineApplicable, - ) - .emit(); + if let [.., last] = &bounds[..] { + let span = ident_span.shrink_to_hi().to(last.span()); + self.emit_e0568(span, ident_span); + } + } + + fn deny_where_clause(&self, where_clause: &WhereClause, ident_span: Span) { + if !where_clause.predicates.is_empty() { + self.emit_e0568(where_clause.span, ident_span); } } fn deny_items(&self, trait_items: &[P], ident_span: Span) { if !trait_items.is_empty() { let spans: Vec<_> = trait_items.iter().map(|i| i.ident.span).collect(); + let total_span = trait_items.first().unwrap().span.to(trait_items.last().unwrap().span); struct_span_err!( self.session, spans, E0380, - "auto traits cannot have methods or associated items" + "auto traits cannot have associated items" + ) + .span_suggestion( + total_span, + "remove these associated items", + String::new(), + Applicability::MachineApplicable, ) - .span_label(ident_span, "auto trait cannot have items") + .span_label(ident_span, "auto trait cannot have associated items") .emit(); } } @@ -1184,6 +1206,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // Auto traits cannot have generics, super traits nor contain items. self.deny_generic_params(generics, item.ident.span); self.deny_super_traits(bounds, item.ident.span); + self.deny_where_clause(&generics.where_clause, item.ident.span); self.deny_items(trait_items, item.ident.span); } self.no_questions_in_bounds(bounds, "supertraits", true); diff --git a/src/test/ui/auto-traits/auto-trait-validation.fixed b/src/test/ui/auto-traits/auto-trait-validation.fixed new file mode 100644 index 0000000000000..da878ac6222bb --- /dev/null +++ b/src/test/ui/auto-traits/auto-trait-validation.fixed @@ -0,0 +1,13 @@ +#![feature(auto_traits)] + +// run-rustfix + +auto trait Generic {} +//~^ auto traits cannot have generic parameters [E0567] +auto trait Bound {} +//~^ auto traits cannot have super traits or lifetime bounds [E0568] +auto trait LifetimeBound {} +//~^ auto traits cannot have super traits or lifetime bounds [E0568] +auto trait MyTrait { } +//~^ auto traits cannot have associated items [E0380] +fn main() {} diff --git a/src/test/ui/auto-traits/auto-trait-validation.rs b/src/test/ui/auto-traits/auto-trait-validation.rs index a997b044c8ff8..d43055e270bd5 100644 --- a/src/test/ui/auto-traits/auto-trait-validation.rs +++ b/src/test/ui/auto-traits/auto-trait-validation.rs @@ -1,9 +1,13 @@ #![feature(auto_traits)] +// run-rustfix + auto trait Generic {} //~^ auto traits cannot have generic parameters [E0567] auto trait Bound : Copy {} -//~^ auto traits cannot have super traits [E0568] +//~^ auto traits cannot have super traits or lifetime bounds [E0568] +auto trait LifetimeBound : 'static {} +//~^ auto traits cannot have super traits or lifetime bounds [E0568] auto trait MyTrait { fn foo() {} } -//~^ auto traits cannot have methods or associated items [E0380] +//~^ auto traits cannot have associated items [E0380] fn main() {} diff --git a/src/test/ui/auto-traits/auto-trait-validation.stderr b/src/test/ui/auto-traits/auto-trait-validation.stderr index 4040e66c6af77..2c380e5b09a6e 100644 --- a/src/test/ui/auto-traits/auto-trait-validation.stderr +++ b/src/test/ui/auto-traits/auto-trait-validation.stderr @@ -1,28 +1,37 @@ error[E0567]: auto traits cannot have generic parameters - --> $DIR/auto-trait-validation.rs:3:19 + --> $DIR/auto-trait-validation.rs:5:19 | LL | auto trait Generic {} | -------^^^ help: remove the parameters | | | auto trait cannot have generic parameters -error[E0568]: auto traits cannot have super traits - --> $DIR/auto-trait-validation.rs:5:20 +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/auto-trait-validation.rs:7:17 | LL | auto trait Bound : Copy {} - | ----- ^^^^ help: remove the super traits + | -----^^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have super traits + | auto trait cannot have super traits or lifetime bounds -error[E0380]: auto traits cannot have methods or associated items - --> $DIR/auto-trait-validation.rs:7:25 +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/auto-trait-validation.rs:9:25 | -LL | auto trait MyTrait { fn foo() {} } - | ------- ^^^ +LL | auto trait LifetimeBound : 'static {} + | -------------^^^^^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have items + | auto trait cannot have super traits or lifetime bounds + +error[E0380]: auto traits cannot have associated items + --> $DIR/auto-trait-validation.rs:11:25 + | +LL | auto trait MyTrait { fn foo() {} } + | ------- ---^^^----- + | | | + | | help: remove these associated items + | auto trait cannot have associated items -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0380, E0567, E0568. For more information about an error, try `rustc --explain E0380`. diff --git a/src/test/ui/auto-traits/issue-23080-2.stderr b/src/test/ui/auto-traits/issue-23080-2.stderr index efeceafdd2a7d..267a712f62fa0 100644 --- a/src/test/ui/auto-traits/issue-23080-2.stderr +++ b/src/test/ui/auto-traits/issue-23080-2.stderr @@ -1,10 +1,10 @@ -error[E0380]: auto traits cannot have methods or associated items +error[E0380]: auto traits cannot have associated items --> $DIR/issue-23080-2.rs:5:10 | LL | unsafe auto trait Trait { - | ----- auto trait cannot have items + | ----- auto trait cannot have associated items LL | type Output; - | ^^^^^^ + | -----^^^^^^- help: remove these associated items error: aborting due to previous error diff --git a/src/test/ui/auto-traits/issue-23080.stderr b/src/test/ui/auto-traits/issue-23080.stderr index 73ecb1c362e17..c1b16b2f403d7 100644 --- a/src/test/ui/auto-traits/issue-23080.stderr +++ b/src/test/ui/auto-traits/issue-23080.stderr @@ -1,10 +1,13 @@ -error[E0380]: auto traits cannot have methods or associated items +error[E0380]: auto traits cannot have associated items --> $DIR/issue-23080.rs:5:8 | -LL | unsafe auto trait Trait { - | ----- auto trait cannot have items -LL | fn method(&self) { - | ^^^^^^ +LL | unsafe auto trait Trait { + | ----- auto trait cannot have associated items +LL | fn method(&self) { + | _____- ^^^^^^ +LL | | println!("Hello"); +LL | | } + | |_____- help: remove these associated items error: aborting due to previous error diff --git a/src/test/ui/auto-traits/issue-84075.rs b/src/test/ui/auto-traits/issue-84075.rs new file mode 100644 index 0000000000000..a6afe24ea4c8b --- /dev/null +++ b/src/test/ui/auto-traits/issue-84075.rs @@ -0,0 +1,16 @@ +// Regression test for issue #84075. + +#![feature(auto_traits)] + +auto trait Magic where Self: Copy {} //~ ERROR E0568 +impl Magic for T {} + +fn copy(x: T) -> (T, T) { (x, x) } + +#[derive(Debug)] +struct NoClone; + +fn main() { + let (a, b) = copy(NoClone); + println!("{:?} {:?}", a, b); +} diff --git a/src/test/ui/auto-traits/issue-84075.stderr b/src/test/ui/auto-traits/issue-84075.stderr new file mode 100644 index 0000000000000..02dca598ec250 --- /dev/null +++ b/src/test/ui/auto-traits/issue-84075.stderr @@ -0,0 +1,11 @@ +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/issue-84075.rs:5:18 + | +LL | auto trait Magic where Self: Copy {} + | ----- ^^^^^^^^^^^^^^^^ help: remove the super traits or lifetime bounds + | | + | auto trait cannot have super traits or lifetime bounds + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0568`. diff --git a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs index 6cceaf821f6bf..98359ef51b764 100644 --- a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs +++ b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs @@ -2,6 +2,7 @@ #![feature(negative_impls)] auto trait Magic : Sized where Option : Magic {} //~ ERROR E0568 +//~^ ERROR E0568 impl Magic for T {} fn copy(x: T) -> (T, T) { (x, x) } diff --git a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr index 63b3300f6dbf4..4827916fa5c53 100644 --- a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr +++ b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr @@ -1,11 +1,19 @@ -error[E0568]: auto traits cannot have super traits - --> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:20 +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:17 | LL | auto trait Magic : Sized where Option : Magic {} - | ----- ^^^^^ help: remove the super traits + | -----^^^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have super traits + | auto trait cannot have super traits or lifetime bounds -error: aborting due to previous error +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:26 + | +LL | auto trait Magic : Sized where Option : Magic {} + | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the super traits or lifetime bounds + | | + | auto trait cannot have super traits or lifetime bounds + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0568`. diff --git a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr index 796638fc54dce..d7716f4b61f04 100644 --- a/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr +++ b/src/test/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr @@ -1,10 +1,10 @@ -error[E0568]: auto traits cannot have super traits - --> $DIR/typeck-auto-trait-no-supertraits.rs:28:19 +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/typeck-auto-trait-no-supertraits.rs:28:17 | LL | auto trait Magic: Copy {} - | ----- ^^^^ help: remove the super traits + | -----^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have super traits + | auto trait cannot have super traits or lifetime bounds error: aborting due to previous error diff --git a/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr b/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr index 7895e50eef5c4..8405d7ddc7aa5 100644 --- a/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr +++ b/src/test/ui/traits/inductive-overflow/supertrait-auto-trait.stderr @@ -1,10 +1,10 @@ -error[E0568]: auto traits cannot have super traits - --> $DIR/supertrait-auto-trait.rs:8:19 +error[E0568]: auto traits cannot have super traits or lifetime bounds + --> $DIR/supertrait-auto-trait.rs:8:17 | LL | auto trait Magic: Copy {} - | ----- ^^^^ help: remove the super traits + | -----^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have super traits + | auto trait cannot have super traits or lifetime bounds error[E0277]: the trait bound `NoClone: Copy` is not satisfied --> $DIR/supertrait-auto-trait.rs:16:23