gccrs: Split async and const function qualifiers
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>
This commit is contained in:
parent
f84e564243
commit
12844c82de
9 changed files with 80 additions and 85 deletions
|
@ -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
|
||||
|
|
|
@ -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 ())
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue