aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2022-06-20 11:22:11 +0200
committerArthur Cohen <arthur.cohen@embecosm.com>2022-06-24 15:11:02 +0200
commitaf7f140f2f17b5290ec09266329bd719a7d49d99 (patch)
tree94356d2fde7a77b6dec1a7e1b9baaf2e0233ac0c /gcc
parent5b90f0b3cdbe8b83cd8139d0e1bdb0e8e086e358 (diff)
downloadgcc-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.cc38
-rw-r--r--gcc/rust/ast/rust-path.h6
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)