From 50fe556cc37e41af0d103f8723896c3e9ca39353 Mon Sep 17 00:00:00 2001 From: M V V S Manoj Kumar Date: Tue, 21 Nov 2023 22:04:24 +0530 Subject: [PATCH] Added support to Parse ASYNC function Fixes issue #2650 The parser now parses ASYNC functions. Added ASYNC case to parse_item Added a new function parse_async_item which is called in parse_vis_item to handle the ASYNC case. Parse_async_item also checks the current Rust edition and generates an error if the edition is 2015 gcc/rust/ChangeLog: * parse/rust-parse-impl.h (Parser::parse_item): Likewise. (Parser::parse_vis_item): Likewise. (Parser::parse_async_item): Likewise. * parse/rust-parse.h: Made declaration for parse_async_item. gcc/testsuite/ChangeLog: * rust/compile/issue-2650-1.rs: New test.(edition=2018) * rust/compile/issue-2650-2.rs: New test.(edition=2015) Signed-off-by: M V V S Manoj Kumar --- gcc/rust/parse/rust-parse-impl.h | 40 ++++++++++++++++++++++ gcc/rust/parse/rust-parse.h | 2 ++ gcc/testsuite/rust/compile/issue-2650-1.rs | 5 +++ gcc/testsuite/rust/compile/issue-2650-2.rs | 5 +++ 4 files changed, 52 insertions(+) create mode 100644 gcc/testsuite/rust/compile/issue-2650-1.rs create mode 100644 gcc/testsuite/rust/compile/issue-2650-2.rs diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 5a186d910681..90dfc46cc664 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -30,6 +30,7 @@ #include "rust-dir-owner.h" #include "rust-attribute-values.h" #include "rust-keyword-values.h" +#include "rust-session-manager.h" #include "optional.h" @@ -1113,6 +1114,8 @@ Parser::parse_item (bool called_from_statement) add_error (std::move (error)); } return nullptr; + + case ASYNC: case PUB: case MOD: case EXTERN_KW: @@ -1389,6 +1392,10 @@ Parser::parse_vis_item (AST::AttrVec outer_attrs) lexer.skip_token (1); // TODO: is this right thing to do? return nullptr; } + // for async functions + case ASYNC: + return parse_async_item (std::move (vis), std::move (outer_attrs)); + case STATIC_KW: return parse_static_item (std::move (vis), std::move (outer_attrs)); case AUTO: @@ -1429,6 +1436,39 @@ Parser::parse_vis_item (AST::AttrVec outer_attrs) return nullptr; } +template +std::unique_ptr +Parser::parse_async_item (AST::Visibility vis, + AST::AttrVec outer_attrs) +{ + const_TokenPtr t = lexer.peek_token (); + if (Session::get_instance ().options.get_edition () + == CompileOptions::Edition::E2015) + { + add_error (Error (t->get_locus (), ErrorCode::E0670, + "% is not permitted in Rust 2015")); + add_error ( + Error::Hint (t->get_locus (), + "to use %, switch to Rust 2018 or later")); + } + + t = lexer.peek_token (1); + + switch (t->get_id ()) + { + case UNSAFE: + case FN_KW: + return parse_function (std::move (vis), std::move (outer_attrs)); + + default: + add_error ( + Error (t->get_locus (), "expected item, found keyword %")); + + lexer.skip_token (1); + return nullptr; + } +} + // Parses a macro rules definition syntax extension whatever thing. template std::unique_ptr diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index e873d5292cde..d3718467b489 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -357,6 +357,8 @@ template class Parser std::unique_ptr parse_extern_block (AST::Visibility vis, AST::AttrVec outer_attrs); std::unique_ptr parse_method (); + std::unique_ptr parse_async_item (AST::Visibility vis, + AST::AttrVec outer_attrs); // Expression-related (Pratt parsed) std::unique_ptr diff --git a/gcc/testsuite/rust/compile/issue-2650-1.rs b/gcc/testsuite/rust/compile/issue-2650-1.rs new file mode 100644 index 000000000000..381398e19f58 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2650-1.rs @@ -0,0 +1,5 @@ +// { dg-additional-options "-frust-edition=2018" } + +pub async fn a() -> u32 { + 1 +} diff --git a/gcc/testsuite/rust/compile/issue-2650-2.rs b/gcc/testsuite/rust/compile/issue-2650-2.rs new file mode 100644 index 000000000000..5132e6e11586 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2650-2.rs @@ -0,0 +1,5 @@ +// { dg-additional-options "-frust-edition=2015" } + +pub async fn a() -> u32 { // { dg-error "'async fn' is not permitted in Rust 2015" } + 1 +}