diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.cc | 11 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 62 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/macro25.rs | 9 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/macro9.rs | 1 |
5 files changed, 77 insertions, 9 deletions
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index 3bdb8c6..6b26f98 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -505,9 +505,6 @@ MacroExpander::match_fragment (Parser<MacroInvocLexer> &parser, return false; } - for (const auto &error : parser.get_errors ()) - error.emit_error (); - // it matches if the parser did not produce errors trying to parse that type // of item return !parser.has_errors (); @@ -714,7 +711,13 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser, bool did_meet_lo_bound = match_amount >= lo_bound; bool did_meet_hi_bound = hi_bound ? match_amount <= hi_bound : true; - return did_meet_lo_bound && did_meet_hi_bound; + // If the end-result is valid, then we can clear the parse errors: Since + // repetitions are parsed eagerly, it is okay to fail in some cases + auto res = did_meet_lo_bound && did_meet_hi_bound; + if (res) + parser.clear_errors (); + + return res; } bool diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 82e7e24..644e789 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -1832,6 +1832,56 @@ Parser<ManagedTokenSource>::parse_macro_match () const_TokenPtr t2 = lexer.peek_token (1); switch (t2->get_id ()) { + case ABSTRACT: + case AS: + case ASYNC: + case BECOME: + case BOX: + case BREAK: + case CONST: + case CONTINUE: + case CRATE: + case DO: + case DYN: + case ELSE: + case ENUM_TOK: + case EXTERN_TOK: + case FALSE_LITERAL: + case FINAL_TOK: + case FN_TOK: + case FOR: + case IF: + case IMPL: + case IN: + case LET: + case LOOP: + case MACRO: + case MATCH_TOK: + case MOD: + case MOVE: + case MUT: + case OVERRIDE_TOK: + case PRIV: + case PUB: + case REF: + case RETURN_TOK: + case SELF_ALIAS: + case SELF: + case STATIC_TOK: + case STRUCT_TOK: + case SUPER: + case TRAIT: + case TRUE_LITERAL: + case TRY: + case TYPE: + case TYPEOF: + case UNSAFE: + case UNSIZED: + case USE: + case VIRTUAL: + case WHERE: + case WHILE: + case YIELD: case IDENTIFIER: // macro fragment return parse_macro_match_fragment (); @@ -1877,8 +1927,14 @@ Parser<ManagedTokenSource>::parse_macro_match_fragment () Location fragment_locus = lexer.peek_token ()->get_locus (); skip_token (DOLLAR_SIGN); - const_TokenPtr ident_tok = expect_token (IDENTIFIER); - if (ident_tok == nullptr) + Identifier ident = ""; + auto identifier = lexer.peek_token (); + if (identifier->has_str ()) + ident = identifier->get_str (); + else + ident = std::string (token_id_to_str (identifier->get_id ())); + + if (ident.empty ()) { Error error (lexer.peek_token ()->get_locus (), "missing identifier in macro match fragment"); @@ -1886,7 +1942,7 @@ Parser<ManagedTokenSource>::parse_macro_match_fragment () return nullptr; } - Identifier ident = ident_tok->get_str (); + skip_token (identifier->get_id ()); if (!skip_token (COLON)) { diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 5880616..9a31fb6 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -649,7 +649,6 @@ private: bool done_end_of_file (); void add_error (Error error) { error_table.push_back (std::move (error)); } - void clear_errors () { error_table.clear (); } public: // Construct parser with specified "managed" token source. @@ -668,6 +667,8 @@ public: // Returns whether any parsing errors have occurred. bool has_errors () const { return !error_table.empty (); } + // Remove all parsing errors from the table + void clear_errors () { error_table.clear (); } // Get a reference to the list of errors encountered std::vector<Error> &get_errors () { return error_table; } diff --git a/gcc/testsuite/rust/compile/macro25.rs b/gcc/testsuite/rust/compile/macro25.rs new file mode 100644 index 0000000..d92534c --- /dev/null +++ b/gcc/testsuite/rust/compile/macro25.rs @@ -0,0 +1,9 @@ +macro_rules! valid { + ($($a:literal)* $i:ident) => {{}}; +} + +fn main() { + valid!(1 one_lit); + valid!(identifier_only); + valid!(1 2 two_lits); +} diff --git a/gcc/testsuite/rust/compile/macro9.rs b/gcc/testsuite/rust/compile/macro9.rs index a06a093..9a59089 100644 --- a/gcc/testsuite/rust/compile/macro9.rs +++ b/gcc/testsuite/rust/compile/macro9.rs @@ -12,7 +12,6 @@ fn main() -> i32 { let b = add!(15); let b = add!(15 14); // { dg-error "Failed to match any rule within macro" } let b = add!(15, 14,); // { dg-error "Failed to match any rule within macro" } - // { dg-error "found unexpected token" "" { target *-*-* } .-1 } 0 } |