diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc b/gcc/rust/checks/errors/rust-ast-validation.cc index f6ce45eaccab..673290959f4b 100644 --- a/gcc/rust/checks/errors/rust-ast-validation.cc +++ b/gcc/rust/checks/errors/rust-ast-validation.cc @@ -96,4 +96,29 @@ ASTValidation::visit (AST::Function &function) AST::ContextualASTVisitor::visit (function); } +void +ASTValidation::visit (AST::Trait &trait) +{ + if (trait.is_auto ()) + { + if (trait.has_generics ()) + rust_error_at (trait.get_generic_params ()[0]->get_locus (), + ErrorCode::E0567, + "auto traits cannot have generic parameters"); + if (trait.has_type_param_bounds ()) + rust_error_at (trait.get_type_param_bounds ()[0]->get_locus (), + ErrorCode::E0568, + "auto traits cannot have super traits"); + if (trait.has_trait_items ()) + { + rust_error_at (trait.get_identifier ().get_locus (), ErrorCode::E0380, + "auto traits cannot have methods or associated items"); + for (const auto &item : trait.get_trait_items ()) + Error::Hint (item->get_locus (), "remove this item").emit (); + } + } + + AST::ContextualASTVisitor::visit (trait); +} + } // namespace Rust diff --git a/gcc/rust/checks/errors/rust-ast-validation.h b/gcc/rust/checks/errors/rust-ast-validation.h index 44995eb1fbce..49133ee0c3d8 100644 --- a/gcc/rust/checks/errors/rust-ast-validation.h +++ b/gcc/rust/checks/errors/rust-ast-validation.h @@ -38,6 +38,7 @@ class ASTValidation : public AST::ContextualASTVisitor virtual void visit (AST::LoopLabel &label); virtual void visit (AST::ExternalFunctionItem &item); virtual void visit (AST::Function &function); + virtual void visit (AST::Trait &trait); }; } // namespace Rust diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 3cfbc67c5e33..b9da3c183ab8 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -4983,18 +4983,6 @@ Parser::parse_trait (AST::Visibility vis, return nullptr; } - if (is_auto_trait && !trait_items.empty ()) - { - add_error (Error (locus, ErrorCode::E0380, - "auto traits cannot have associated items")); - - // FIXME: unsure if this should be done at parsing time or not - for (const auto &item : trait_items) - add_error (Error::Hint (item->get_locus (), "remove this item")); - - return nullptr; - } - trait_items.shrink_to_fit (); return std::unique_ptr ( new AST::Trait (std::move (ident), is_unsafe, is_auto_trait, diff --git a/gcc/testsuite/rust/compile/auto_trait_invalid.rs b/gcc/testsuite/rust/compile/auto_trait_invalid.rs index 66e45531f5d8..3be2acbb53b6 100644 --- a/gcc/testsuite/rust/compile/auto_trait_invalid.rs +++ b/gcc/testsuite/rust/compile/auto_trait_invalid.rs @@ -2,7 +2,9 @@ #![feature(optin_builtin_traits)] -unsafe auto trait Invalid { // { dg-error "auto traits cannot have associated items" } +auto trait Invalid { + // { dg-error "auto traits cannot have methods or associated items" "" { target *-*-* } .-1 } + fn foo(); // { dg-message "remove this item" } fn bar() {} // { dg-message "remove this item" } @@ -13,4 +15,3 @@ unsafe auto trait Invalid { // { dg-error "auto traits cannot have associated it const BAR: i32 = 15; // { dg-message "remove this item" } } -// { dg-error "failed to parse item in crate" "" {target *-*-* } .+1 } diff --git a/gcc/testsuite/rust/compile/auto_trait_super_trait.rs b/gcc/testsuite/rust/compile/auto_trait_super_trait.rs new file mode 100644 index 000000000000..1080afb5124d --- /dev/null +++ b/gcc/testsuite/rust/compile/auto_trait_super_trait.rs @@ -0,0 +1,4 @@ +trait Cold {} + +auto trait IsCool: Cold {} +// { dg-error "auto traits cannot have super traits .E0568." "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/rust/compile/generic_auto_trait.rs b/gcc/testsuite/rust/compile/generic_auto_trait.rs new file mode 100644 index 000000000000..ae6a51d0244c --- /dev/null +++ b/gcc/testsuite/rust/compile/generic_auto_trait.rs @@ -0,0 +1,2 @@ +auto trait IsCooler {} +// { dg-error "auto traits cannot have generic parameters .E0567." "" { target *-*-* } .-1 }