[COMMITTED,051/101] gccrs: Split async and const function qualifiers

Message ID 20240130121026.807464-54-arthur.cohen@embecosm.com
State Committed
Commit 12844c82dec296c8530594211a65b55875797b43
Headers
Series [COMMITTED,001/101] gccrs: Add visibility to trait item |

Commit Message

Arthur Cohen Jan. 30, 2024, 12:07 p.m. UTC
  From: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>

A function cannot be both async and const, however this should not be
handled in the parser but rather at a later stage in the compiler. This
commit change the AsyncConstStatus in the AST and the HIR to allows a
function to be both async and const.

gcc/rust/ChangeLog:

	* ast/rust-ast-builder.cc (AstBuilder::fn_qualifiers): Change
	constructor to match the new arguments.
	* ast/rust-ast-collector.cc (TokenCollector::visit): Change behavior
	to handle both const and async specifiers at the same time.
	* ast/rust-ast.cc (FunctionQualifiers::as_string): Likewise.
	* ast/rust-item.h (class FunctionQualifiers): Remove AsyncConstStatus
	and replace it with both Async and Const status. Also change the safety
	arguments to use an enum instead of a boolean.
	* hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_qualifiers):
	Update constructor call.
	* hir/tree/rust-hir-item.h: Add Const and Async status, remove
	AsyncConstStatus, update the constructor.
	* hir/tree/rust-hir.cc (FunctionQualifiers::as_string): Update with
	the new status.
	* parse/rust-parse-impl.h (Parser::parse_function_qualifiers): Update
	constructor call.
	* util/rust-common.h (enum Mutability): Make an enum class.
	(enum class): Add Async and Const enum class to avoid booleans.
	(enum Unsafety): Change to an enum class.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
---
 gcc/rust/ast/rust-ast-builder.cc    |  2 +-
 gcc/rust/ast/rust-ast-collector.cc  | 16 +++-------
 gcc/rust/ast/rust-ast.cc            | 21 ++++---------
 gcc/rust/ast/rust-item.h            | 22 ++++++++------
 gcc/rust/hir/rust-ast-lower-base.cc |  3 +-
 gcc/rust/hir/tree/rust-hir-item.h   | 14 +++++----
 gcc/rust/hir/tree/rust-hir.cc       | 25 ++++------------
 gcc/rust/parse/rust-parse-impl.h    | 46 +++++++++++++++++------------
 gcc/rust/util/rust-common.h         | 16 ++++++++--
 9 files changed, 80 insertions(+), 85 deletions(-)
  

Patch

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index e2d3eea6c58..fd6f519fa25 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -46,7 +46,7 @@  AstBuilder::tuple_idx (std::string receiver, int idx)
 FunctionQualifiers
 AstBuilder::fn_qualifiers ()
 {
-  return FunctionQualifiers (loc, AsyncConstStatus::NONE, false);
+  return FunctionQualifiers (loc, Async::No, Const::No, Unsafety::Normal);
 }
 
 PathExprSegment
diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc
index 3e3a959578e..647724bec11 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -317,18 +317,10 @@  TokenCollector::visit (FunctionQualifiers &qualifiers)
   //    `const`? `async`? `unsafe`? (`extern` Abi?)?
   //    unsafe? (extern Abi?)?
 
-  switch (qualifiers.get_const_status ())
-    {
-    case NONE:
-      break;
-    case CONST_FN:
-      push (Rust::Token::make (CONST, qualifiers.get_locus ()));
-      break;
-    case ASYNC_FN:
-      push (Rust::Token::make (ASYNC, qualifiers.get_locus ()));
-      break;
-    }
-
+  if (qualifiers.is_async ())
+    push (Rust::Token::make (ASYNC, qualifiers.get_locus ()));
+  if (qualifiers.is_const ())
+    push (Rust::Token::make (CONST, qualifiers.get_locus ()));
   if (qualifiers.is_unsafe ())
     push (Rust::Token::make (UNSAFE, qualifiers.get_locus ()));
   if (qualifiers.is_extern ())
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 17f82d67430..607f07955d4 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -2333,22 +2333,11 @@  FunctionQualifiers::as_string () const
 {
   std::string str;
 
-  switch (const_status)
-    {
-    case NONE:
-      // do nothing
-      break;
-    case CONST_FN:
-      str += "const ";
-      break;
-    case ASYNC_FN:
-      str += "async ";
-      break;
-    default:
-      return "ERROR_MARK_STRING: async-const status failure";
-    }
-
-  if (has_unsafe)
+  if (is_async ())
+    str += "async ";
+  if (is_const ())
+    str += "const ";
+  if (is_unsafe ())
     str += "unsafe ";
 
   if (has_extern)
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index b34aca0d56c..9a83f3d5981 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -533,19 +533,20 @@  public:
 // Qualifiers for function, i.e. const, unsafe, extern etc.
 class FunctionQualifiers
 {
-  AsyncConstStatus const_status;
-  bool has_unsafe;
+  Async async_status;
+  Const const_status;
+  Unsafety unsafe_status;
   bool has_extern;
   std::string extern_abi;
   location_t locus;
 
 public:
-  FunctionQualifiers (location_t locus, AsyncConstStatus const_status,
-		      bool has_unsafe, bool has_extern = false,
+  FunctionQualifiers (location_t locus, Async async_status, Const const_status,
+		      Unsafety unsafe_status, bool has_extern = false,
 		      std::string extern_abi = std::string ())
-    : const_status (const_status), has_unsafe (has_unsafe),
-      has_extern (has_extern), extern_abi (std::move (extern_abi)),
-      locus (locus)
+    : async_status (async_status), const_status (const_status),
+      unsafe_status (unsafe_status), has_extern (has_extern),
+      extern_abi (std::move (extern_abi)), locus (locus)
   {
     if (!this->extern_abi.empty ())
       {
@@ -556,11 +557,14 @@  public:
 
   std::string as_string () const;
 
-  AsyncConstStatus get_const_status () const { return const_status; }
-  bool is_unsafe () const { return has_unsafe; }
+  bool is_unsafe () const { return unsafe_status == Unsafety::Unsafe; }
   bool is_extern () const { return has_extern; }
+  bool is_const () const { return const_status == Const::Yes; }
+  bool is_async () const { return async_status == Async::Yes; }
   std::string get_extern_abi () const { return extern_abi; }
   bool has_abi () const { return !extern_abi.empty (); }
+  Const get_const_status () const { return const_status; }
+  Async get_async_status () const { return async_status; }
 
   location_t get_locus () const { return locus; }
 };
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index f5eed256a5e..f8438557707 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -721,7 +721,8 @@  ASTLoweringBase::lower_qualifiers (const AST::FunctionQualifiers &qualifiers)
 		       "invalid ABI: found %qs", extern_abi.c_str ());
     }
 
-  return HIR::FunctionQualifiers (qualifiers.get_const_status (), unsafety,
+  return HIR::FunctionQualifiers (qualifiers.get_async_status (),
+				  qualifiers.get_const_status (), unsafety,
 				  has_extern, abi);
 }
 
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 6cd41892e49..f72d8c8b050 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -481,24 +481,26 @@  public:
 struct FunctionQualifiers
 {
 private:
-  AsyncConstStatus const_status;
+  Async async_status;
+  Const const_status;
   Unsafety unsafety;
   bool has_extern;
   ABI abi;
 
 public:
-  FunctionQualifiers (AsyncConstStatus const_status, Unsafety unsafety,
+  FunctionQualifiers (Async async_status, Const const_status, Unsafety unsafety,
 		      bool has_extern, ABI abi)
-    : const_status (const_status), unsafety (unsafety), has_extern (has_extern),
-      abi (abi)
+    : async_status (async_status), const_status (const_status),
+      unsafety (unsafety), has_extern (has_extern), abi (abi)
   {}
 
   std::string as_string () const;
 
-  AsyncConstStatus get_status () const { return const_status; }
+  Const get_const_status () const { return const_status; }
 
-  bool is_const () const { return const_status == AsyncConstStatus::CONST_FN; }
+  bool is_const () const { return const_status == Const::Yes; }
   bool is_unsafe () const { return unsafety == Unsafety::Unsafe; }
+  bool is_async () const { return async_status == Async::Yes; }
 
   ABI get_abi () const { return abi; }
 };
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index 66f626ba845..fb0a9c388ae 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -1947,25 +1947,12 @@  FunctionQualifiers::as_string () const
 {
   std::string str;
 
-  switch (const_status)
-    {
-    case NONE:
-      // do nothing
-      break;
-    case CONST_FN:
-      str += "const ";
-      break;
-    case ASYNC_FN:
-      str += "async ";
-      break;
-    default:
-      return "ERROR_MARK_STRING: async-const status failure";
-    }
-
-  if (unsafety == Unsafety::Unsafe)
-    {
-      str += "unsafe ";
-    }
+  if (is_const ())
+    str += "const ";
+  if (is_async ())
+    str += "async ";
+  if (is_unsafe ())
+    str += "unsafe ";
 
   if (has_extern)
     {
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index a9af7dc3f38..a1ad4f11993 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -24,6 +24,7 @@ 
 
 #include "rust-common.h"
 #include "rust-item.h"
+#include "rust-common.h"
 #include "rust-token.h"
 #define INCLUDE_ALGORITHM
 #include "rust-diagnostics.h"
@@ -2987,33 +2988,40 @@  template <typename ManagedTokenSource>
 AST::FunctionQualifiers
 Parser<ManagedTokenSource>::parse_function_qualifiers ()
 {
-  AsyncConstStatus const_status = NONE;
-  bool has_unsafe = false;
+  Async async_status = Async::No;
+  Const const_status = Const::No;
+  Unsafety unsafe_status = Unsafety::Normal;
   bool has_extern = false;
   std::string abi;
 
+  const_TokenPtr t;
+  location_t locus;
   // Check in order of const, unsafe, then extern
-  const_TokenPtr t = lexer.peek_token ();
-  location_t locus = t->get_locus ();
-  switch (t->get_id ())
+  for (int i = 0; i < 2; i++)
     {
-    case CONST:
-      lexer.skip_token ();
-      const_status = CONST_FN;
-      break;
-    case ASYNC:
-      lexer.skip_token ();
-      const_status = ASYNC_FN;
-      break;
-    default:
-      // const status is still none
-      break;
+      t = lexer.peek_token ();
+      locus = t->get_locus ();
+
+      switch (t->get_id ())
+	{
+	case CONST:
+	  lexer.skip_token ();
+	  const_status = Const::Yes;
+	  break;
+	case ASYNC:
+	  lexer.skip_token ();
+	  async_status = Async::Yes;
+	  break;
+	default:
+	  // const status is still none
+	  break;
+	}
     }
 
   if (lexer.peek_token ()->get_id () == UNSAFE)
     {
       lexer.skip_token ();
-      has_unsafe = true;
+      unsafe_status = Unsafety::Unsafe;
     }
 
   if (lexer.peek_token ()->get_id () == EXTERN_KW)
@@ -3030,8 +3038,8 @@  Parser<ManagedTokenSource>::parse_function_qualifiers ()
 	}
     }
 
-  return AST::FunctionQualifiers (locus, const_status, has_unsafe, has_extern,
-				  std::move (abi));
+  return AST::FunctionQualifiers (locus, async_status, const_status,
+				  unsafe_status, has_extern, std::move (abi));
 }
 
 // Parses generic (lifetime or type) params inside angle brackets (optional).
diff --git a/gcc/rust/util/rust-common.h b/gcc/rust/util/rust-common.h
index fc8ba6e1e58..299ae71e909 100644
--- a/gcc/rust/util/rust-common.h
+++ b/gcc/rust/util/rust-common.h
@@ -25,18 +25,30 @@ 
 
 namespace Rust {
 
-enum Mutability
+enum class Mutability
 {
   Imm,
   Mut
 };
 
-enum Unsafety
+enum class Unsafety
 {
   Unsafe,
   Normal
 };
 
+enum class Const
+{
+  Yes,
+  No,
+};
+
+enum class Async
+{
+  Yes,
+  No
+};
+
 enum BoundPolarity
 {
   RegularBound,