From f60c15f5099349ccc04a697e4d37154c371253a3 Mon Sep 17 00:00:00 2001 From: Arthur Cohen Date: Wed, 15 Feb 2023 16:53:41 +0100 Subject: parser: Add parsing of auto traits This adds enough handling to start parsing `auto` traits but not handle them in the AST, lowering phase or HIR yet. The feature is named `optin_builtin_traits` in Rust 1.49 but changes to `auto_traits` later down the line. So we'll need to take care of this later on. Finally, this also changes the way the lexer detects if a string is a keyword or not. We relied on a call to `std::lower_bound` to figure out if a string was contained in an array or not, and this ended up causing issues when adding new keywords. We can instead switch to a simple hashmap and search for the key. The code *might* be less optimized (unsure) but it is definitely simpler and easier to read. Fixes #1814 gcc/rust/ChangeLog: * ast/rust-item.h (class Trait): Add `has_auto` field. * checks/errors/rust-feature.cc: Add handling for `feature(optin_builtin_traits)` * checks/errors/rust-feature.h: Likewise. * lex/rust-lex.cc: Fix keyword classification using hashmap. * lex/rust-token.h: Add `auto` keyword token. * parse/rust-parse-impl.h (Parser::parse_vis_item): Parse auto traits on `auto` keyword. gcc/testsuite/ChangeLog: * rust/compile/auto_trait_invalid.rs: New test. * rust/compile/auto_trait_valid.rs: New test. --- gcc/rust/parse/rust-parse-impl.h | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'gcc/rust/parse/rust-parse-impl.h') diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 2cb5e3e..0841db4 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -1057,6 +1057,7 @@ Parser::parse_item (bool called_from_statement) case ENUM_TOK: case CONST: case STATIC_TOK: + case AUTO: case TRAIT: case IMPL: case MACRO: @@ -1304,6 +1305,7 @@ Parser::parse_vis_item (AST::AttrVec outer_attrs) } case STATIC_TOK: return parse_static_item (std::move (vis), std::move (outer_attrs)); + case AUTO: case TRAIT: return parse_trait (std::move (vis), std::move (outer_attrs)); case IMPL: @@ -1314,6 +1316,7 @@ Parser::parse_vis_item (AST::AttrVec outer_attrs) switch (t->get_id ()) { + case AUTO: case TRAIT: return parse_trait (std::move (vis), std::move (outer_attrs)); case EXTERN_TOK: @@ -2034,6 +2037,7 @@ Parser::parse_macro_match () case STATIC_TOK: case STRUCT_TOK: case SUPER: + case AUTO: case TRAIT: case TRUE_LITERAL: case TRY: @@ -4753,12 +4757,20 @@ Parser::parse_trait (AST::Visibility vis, { Location locus = lexer.peek_token ()->get_locus (); bool is_unsafe = false; + bool is_auto_trait = false; + if (lexer.peek_token ()->get_id () == UNSAFE) { is_unsafe = true; lexer.skip_token (); } + if (lexer.peek_token ()->get_id () == AUTO) + { + is_auto_trait = true; + lexer.skip_token (); + } + skip_token (TRAIT); // parse trait name @@ -4824,12 +4836,25 @@ Parser::parse_trait (AST::Visibility vis, return nullptr; } + if (is_auto_trait && !trait_items.empty ()) + { + add_error ( + Error (locus, "associated items are forbidden within auto traits")); + + // 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, std::move (generic_params), - std::move (type_param_bounds), std::move (where_clause), - std::move (trait_items), std::move (vis), - std::move (outer_attrs), std::move (inner_attrs), locus)); + new AST::Trait (std::move (ident), is_unsafe, is_auto_trait, + std::move (generic_params), std::move (type_param_bounds), + std::move (where_clause), std::move (trait_items), + std::move (vis), std::move (outer_attrs), + std::move (inner_attrs), locus)); } // Parses a trait item used inside traits (not trait, the Item). @@ -6120,6 +6145,7 @@ Parser::parse_stmt (ParseRestrictions restrictions) case ENUM_TOK: case CONST: case STATIC_TOK: + case AUTO: case TRAIT: case IMPL: case MACRO: @@ -11769,6 +11795,7 @@ Parser::parse_stmt_or_expr_without_block () case ENUM_TOK: case CONST: case STATIC_TOK: + case AUTO: case TRAIT: case IMPL: { std::unique_ptr item ( @@ -11790,6 +11817,7 @@ Parser::parse_stmt_or_expr_without_block () // unsafe block return parse_stmt_or_expr_with_block (std::move (outer_attrs)); } + case AUTO: case TRAIT: { // unsafe trait std::unique_ptr item ( -- cgit v1.1