aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/parse/rust-parse-impl.h
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2023-02-15 16:53:41 +0100
committerCohenArthur <arthur.cohen@embecosm.com>2023-02-23 13:54:18 +0000
commitf60c15f5099349ccc04a697e4d37154c371253a3 (patch)
tree7453ed1d10bce6cb8238198b3af61ceedd28ac16 /gcc/rust/parse/rust-parse-impl.h
parent918851ad2c965cef63dd0cb0be01f80a80d6c9c7 (diff)
downloadgcc-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.h36
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 (