aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/parse
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2023-02-23 15:11:04 +0100
committerCohenArthur <arthur.cohen@embecosm.com>2023-02-27 09:52:33 +0000
commitce43f55e9976929f9ff2388c8971a65afd24e26d (patch)
tree6df3152421ed8f15efbffe46b957060dcba575cd /gcc/rust/parse
parent0d4a4475e9fbd972bdbcf8e0bcf6f3be3db2f00f (diff)
downloadgcc-ce43f55e9976929f9ff2388c8971a65afd24e26d.zip
gcc-ce43f55e9976929f9ff2388c8971a65afd24e26d.tar.gz
gcc-ce43f55e9976929f9ff2388c8971a65afd24e26d.tar.bz2
parser: Parse `default` impl Functions and Methods
gcc/rust/ChangeLog: * ast/rust-item.h (class Method): Add `is_default` field. (class Function): Likewise. * parse/rust-parse-impl.h (Parser::parse_item): Add nice error when parsing `default` outside of an `impl` block (Parser::parse_trait_impl_item): Allow parsing functions or methods when seeing `default`. gcc/testsuite/ChangeLog: * rust/compile/parse_invalid_specialization.rs: New test. * rust/compile/parse_specialization.rs: New test. * rust/compile/default_not_a_kw.rs: New test.
Diffstat (limited to 'gcc/rust/parse')
-rw-r--r--gcc/rust/parse/rust-parse-impl.h127
1 files changed, 47 insertions, 80 deletions
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 0841db4..7807d75 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -1086,6 +1086,13 @@ Parser<ManagedTokenSource>::parse_item (bool called_from_statement)
return parse_vis_item (std::move (outer_attrs));
// or should this go straight to parsing union?
}
+ else if (t->get_str () == "default")
+ {
+ add_error (Error (t->get_locus (),
+ "%qs is only allowed on items within %qs blocks",
+ "default", "impl"));
+ return nullptr;
+ }
else if (t->get_str () == "macro_rules")
{
// macro_rules! macro item
@@ -5538,13 +5545,14 @@ Parser<ManagedTokenSource>::parse_trait_impl_item ()
// parse outer attributes (if they exist)
AST::AttrVec outer_attrs = parse_outer_attributes ();
- // TODO: clean this function up, it is basically unreadable hacks
+ auto visibility = AST::Visibility::create_private ();
+ if (lexer.peek_token ()->get_id () == PUB)
+ visibility = parse_visibility ();
// branch on next token:
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case IDENTIFIER:
case SUPER:
case SELF:
case CRATE:
@@ -5552,67 +5560,20 @@ Parser<ManagedTokenSource>::parse_trait_impl_item ()
// these seem to be SimplePath tokens, so this is a macro invocation
// semi
return parse_macro_invocation_semi (std::move (outer_attrs));
+ case IDENTIFIER:
+ if (lexer.peek_token ()->get_str () == "default")
+ return parse_trait_impl_function_or_method (visibility,
+ std::move (outer_attrs));
+ else
+ return parse_macro_invocation_semi (std::move (outer_attrs));
case TYPE:
- return parse_type_alias (AST::Visibility::create_private (),
- std::move (outer_attrs));
- case PUB: {
- // visibility, so not a macro invocation semi - must be constant,
- // function, or method
- AST::Visibility vis = parse_visibility ();
-
- // TODO: is a recursive call to parse_trait_impl_item better?
- switch (lexer.peek_token ()->get_id ())
- {
- case TYPE:
- return parse_type_alias (std::move (vis), std::move (outer_attrs));
- case EXTERN_TOK:
- case UNSAFE:
- case FN_TOK:
- // function or method
- return parse_trait_impl_function_or_method (std::move (vis),
- std::move (
- outer_attrs));
- case CONST:
- // lookahead to resolve production - could be function/method or
- // const item
- t = lexer.peek_token (1);
-
- switch (t->get_id ())
- {
- case IDENTIFIER:
- case UNDERSCORE:
- return parse_const_item (std::move (vis),
- std::move (outer_attrs));
- case UNSAFE:
- case EXTERN_TOK:
- case FN_TOK:
- return parse_trait_impl_function_or_method (std::move (vis),
- std::move (
- outer_attrs));
- default:
- add_error (Error (t->get_locus (),
- "unexpected token %qs in some sort of const "
- "item in trait impl",
- t->get_token_description ()));
-
- lexer.skip_token (1); // TODO: is this right thing to do?
- return nullptr;
- }
- default:
- add_error (Error (t->get_locus (),
- "unrecognised token %qs for item in trait impl",
- t->get_token_description ()));
-
- // skip?
- return nullptr;
- }
- }
+ return parse_type_alias (visibility, std::move (outer_attrs));
case EXTERN_TOK:
case UNSAFE:
case FN_TOK:
// function or method
- return parse_trait_impl_function_or_method (
- AST::Visibility::create_private (), std::move (outer_attrs));
+ return parse_trait_impl_function_or_method (visibility,
+ std::move (outer_attrs));
case CONST:
// lookahead to resolve production - could be function/method or const
// item
@@ -5622,13 +5583,12 @@ Parser<ManagedTokenSource>::parse_trait_impl_item ()
{
case IDENTIFIER:
case UNDERSCORE:
- return parse_const_item (AST::Visibility::create_private (),
- std::move (outer_attrs));
+ return parse_const_item (visibility, std::move (outer_attrs));
case UNSAFE:
case EXTERN_TOK:
case FN_TOK:
- return parse_trait_impl_function_or_method (
- AST::Visibility::create_private (), std::move (outer_attrs));
+ return parse_trait_impl_function_or_method (visibility,
+ std::move (outer_attrs));
default:
add_error (Error (
t->get_locus (),
@@ -5640,13 +5600,14 @@ Parser<ManagedTokenSource>::parse_trait_impl_item ()
}
gcc_unreachable ();
default:
- add_error (Error (t->get_locus (),
- "unrecognised token %qs for item in trait impl",
- t->get_token_description ()));
-
- // skip?
- return nullptr;
+ break;
}
+ add_error (Error (t->get_locus (),
+ "unrecognised token %qs for item in trait impl",
+ t->get_token_description ()));
+
+ // skip?
+ return nullptr;
}
/* For internal use only by parse_trait_impl_item() - splits giant method into
@@ -5665,6 +5626,14 @@ Parser<ManagedTokenSource>::parse_trait_impl_function_or_method (
// parse function or method qualifiers
AST::FunctionQualifiers qualifiers = parse_function_qualifiers ();
+ auto is_default = false;
+ auto t = lexer.peek_token ();
+ if (t->get_id () == IDENTIFIER && t->get_str () == "default")
+ {
+ is_default = true;
+ lexer.skip_token ();
+ }
+
skip_token (FN_TOK);
// parse function or method name
@@ -5789,21 +5758,19 @@ Parser<ManagedTokenSource>::parse_trait_impl_function_or_method (
// do actual if instead of ternary for return value optimisation
if (is_method)
{
- return std::unique_ptr<AST::Method> (
- new AST::Method (std::move (ident), std::move (qualifiers),
- std::move (generic_params), std::move (self_param),
- std::move (function_params), std::move (return_type),
- std::move (where_clause), std::move (body),
- std::move (vis), std::move (outer_attrs), locus));
+ return std::unique_ptr<AST::Method> (new AST::Method (
+ std::move (ident), std::move (qualifiers), std::move (generic_params),
+ std::move (self_param), std::move (function_params),
+ std::move (return_type), std::move (where_clause), std::move (body),
+ std::move (vis), std::move (outer_attrs), locus, is_default));
}
else
{
- return std::unique_ptr<AST::Function> (
- new AST::Function (std::move (ident), std::move (qualifiers),
- std::move (generic_params),
- std::move (function_params), std::move (return_type),
- std::move (where_clause), std::move (body),
- std::move (vis), std::move (outer_attrs), locus));
+ return std::unique_ptr<AST::Function> (new AST::Function (
+ std::move (ident), std::move (qualifiers), std::move (generic_params),
+ std::move (function_params), std::move (return_type),
+ std::move (where_clause), std::move (body), std::move (vis),
+ std::move (outer_attrs), locus, is_default));
}
}