diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-06-20 11:22:11 +0200 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-06-24 15:11:02 +0200 |
commit | af7f140f2f17b5290ec09266329bd719a7d49d99 (patch) | |
tree | 94356d2fde7a77b6dec1a7e1b9baaf2e0233ac0c /gcc | |
parent | 5b90f0b3cdbe8b83cd8139d0e1bdb0e8e086e358 (diff) | |
download | gcc-af7f140f2f17b5290ec09266329bd719a7d49d99.zip gcc-af7f140f2f17b5290ec09266329bd719a7d49d99.tar.gz gcc-af7f140f2f17b5290ec09266329bd719a7d49d99.tar.bz2 |
ast: Allow disambiguation of ConstGenericArgs to const generic arguments
At the AST level, we might encounter situations where const generic
arguments are ambiguous: They could be resolved to either a type or a
const expression, as shown in this example:
```rust
let a: Foo<N>; // what is N? A type? A const? The parser doesn't know
```
However, when parsing default expressions for const generic parameters,
we need to be able to disambiguate to const expressions early:
```rust
struct Foo<const N: usize = { M }> {
/* ... */
}
```
In that code, `M` could be considered ambiguous: Is it a type? a const?
A random non-const variable? What matters is that we disambiguate it to
a const generic argument, so that it errors out appropriately in later
phases of the compiler.
In that case, we need to go from a `ConstArg::Ambiguous("M")` to a
`ConstArg::Clear(IdentifierExpr("M"))`.
In later passes of the compiler, we will also need to disambiguate to
types. But that will be done at the HIR/Resolving level.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/ast/rust-ast-full-test.cc | 38 | ||||
-rw-r--r-- | gcc/rust/ast/rust-path.h | 6 |
2 files changed, 31 insertions, 13 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc index 7f66ee4..0d4d36b 100644 --- a/gcc/rust/ast/rust-ast-full-test.cc +++ b/gcc/rust/ast/rust-ast-full-test.cc @@ -4096,10 +4096,10 @@ DelimTokenTree::parse_to_meta_item () const /* assume top-level delim token tree in attribute - convert all nested ones * to token stream */ - std::vector<std::unique_ptr<Token> > token_stream = to_token_stream (); + std::vector<std::unique_ptr<Token>> token_stream = to_token_stream (); AttributeParser parser (std::move (token_stream)); - std::vector<std::unique_ptr<MetaItemInner> > meta_items ( + std::vector<std::unique_ptr<MetaItemInner>> meta_items ( parser.parse_meta_item_seq ()); return new AttrInputMetaItemContainer (std::move (meta_items)); @@ -4282,7 +4282,7 @@ AttributeParser::parse_path_meta_item () switch (peek_token ()->get_id ()) { case LEFT_PAREN: { - std::vector<std::unique_ptr<MetaItemInner> > meta_items + std::vector<std::unique_ptr<MetaItemInner>> meta_items = parse_meta_item_seq (); return std::unique_ptr<MetaItemSeq> ( @@ -4320,11 +4320,11 @@ AttributeParser::parse_path_meta_item () /* Parses a parenthesised sequence of meta item inners. Parentheses are * required here. */ -std::vector<std::unique_ptr<MetaItemInner> > +std::vector<std::unique_ptr<MetaItemInner>> AttributeParser::parse_meta_item_seq () { int vec_length = token_stream.size (); - std::vector<std::unique_ptr<MetaItemInner> > meta_items; + std::vector<std::unique_ptr<MetaItemInner>> meta_items; if (peek_token ()->get_id () != LEFT_PAREN) { @@ -4364,13 +4364,13 @@ AttributeParser::parse_meta_item_seq () /* Collects any nested token trees into a flat token stream, suitable for * parsing. */ -std::vector<std::unique_ptr<Token> > +std::vector<std::unique_ptr<Token>> DelimTokenTree::to_token_stream () const { - std::vector<std::unique_ptr<Token> > tokens; + std::vector<std::unique_ptr<Token>> tokens; for (const auto &tree : token_trees) { - std::vector<std::unique_ptr<Token> > stream = tree->to_token_stream (); + std::vector<std::unique_ptr<Token>> stream = tree->to_token_stream (); tokens.insert (tokens.end (), std::make_move_iterator (stream.begin ()), std::make_move_iterator (stream.end ())); @@ -4711,12 +4711,12 @@ MetaItemPathLit::check_cfg_predicate (const Session &session) const lit.as_string ()); } -std::vector<std::unique_ptr<Token> > +std::vector<std::unique_ptr<Token>> Token::to_token_stream () const { /* initialisation list doesn't work as it needs copy constructor, so have to * do this */ - std::vector<std::unique_ptr<Token> > dummy_vector; + std::vector<std::unique_ptr<Token>> dummy_vector; dummy_vector.reserve (1); dummy_vector.push_back (std::unique_ptr<Token> (clone_token_impl ())); return dummy_vector; @@ -4744,7 +4744,7 @@ MetaItemPath::to_attribute () const Attribute MetaItemSeq::to_attribute () const { - std::vector<std::unique_ptr<MetaItemInner> > new_seq; + std::vector<std::unique_ptr<MetaItemInner>> new_seq; new_seq.reserve (seq.size ()); for (const auto &e : seq) new_seq.push_back (e->clone_meta_item_inner ()); @@ -4768,7 +4768,7 @@ MetaListPaths::to_attribute () const * no longer known). If conversions back are required, might have to do a * "check all are paths" pass or something. */ - std::vector<std::unique_ptr<MetaItemInner> > new_seq; + std::vector<std::unique_ptr<MetaItemInner>> new_seq; new_seq.reserve (paths.size ()); for (const auto &e : paths) new_seq.push_back (std::unique_ptr<MetaItemPath> (new MetaItemPath (e))); @@ -4782,7 +4782,7 @@ MetaListPaths::to_attribute () const Attribute MetaListNameValueStr::to_attribute () const { - std::vector<std::unique_ptr<MetaItemInner> > new_seq; + std::vector<std::unique_ptr<MetaItemInner>> new_seq; new_seq.reserve (strs.size ()); for (const auto &e : strs) new_seq.push_back ( @@ -5792,5 +5792,17 @@ MetaWord::accept_vis (ASTVisitor &vis) { vis.visit (*this); } + +ConstGenericArg +ConstGenericArg::disambiguate_to_const () const +{ + rust_assert (get_kind () == Kind::Ambiguous); + + // FIXME: is it fine to have no outer attributes? + return ConstGenericArg (std::unique_ptr<Expr> ( + new IdentifierExpr (path, {}, locus)), + locus); +} + } // namespace AST } // namespace Rust diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index 6e2b020..d2d925a 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -208,6 +208,12 @@ public: return ""; } + /** + * Disambiguate an amibguous const generic argument or generic type argument + * to a const generic argument, unequivocally + */ + ConstGenericArg disambiguate_to_const () const; + private: ConstGenericArg (std::unique_ptr<AST::Expr> expression, Identifier path, Kind kind, Location locus) |