diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2023-02-15 16:53:41 +0100 |
---|---|---|
committer | CohenArthur <arthur.cohen@embecosm.com> | 2023-02-23 13:54:18 +0000 |
commit | f60c15f5099349ccc04a697e4d37154c371253a3 (patch) | |
tree | 7453ed1d10bce6cb8238198b3af61ceedd28ac16 /gcc/rust/parse/rust-parse-impl.h | |
parent | 918851ad2c965cef63dd0cb0be01f80a80d6c9c7 (diff) | |
download | gcc-f60c15f5099349ccc04a697e4d37154c371253a3.zip gcc-f60c15f5099349ccc04a697e4d37154c371253a3.tar.gz gcc-f60c15f5099349ccc04a697e4d37154c371253a3.tar.bz2 |
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.
Diffstat (limited to 'gcc/rust/parse/rust-parse-impl.h')
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 36 |
1 files changed, 32 insertions, 4 deletions
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<ManagedTokenSource>::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<ManagedTokenSource>::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<ManagedTokenSource>::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<ManagedTokenSource>::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<ManagedTokenSource>::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<ManagedTokenSource>::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<AST::Trait> ( - 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<ManagedTokenSource>::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<ManagedTokenSource>::parse_stmt_or_expr_without_block () case ENUM_TOK: case CONST: case STATIC_TOK: + case AUTO: case TRAIT: case IMPL: { std::unique_ptr<AST::VisItem> item ( @@ -11790,6 +11817,7 @@ Parser<ManagedTokenSource>::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<AST::VisItem> item ( |