aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/ast
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2022-07-05 16:40:38 +0200
committerArthur Cohen <arthur.cohen@embecosm.com>2022-07-07 11:35:06 +0200
commit1f32e5b4558126d872f455c65a94d9640a93c285 (patch)
tree46593ffd2c9b242b801f7cf021a4b9d380baf55a /gcc/rust/ast
parentad0e01dfbba94c0a10019db7c11b13fa0758c1fb (diff)
downloadgcc-1f32e5b4558126d872f455c65a94d9640a93c285.zip
gcc-1f32e5b4558126d872f455c65a94d9640a93c285.tar.gz
gcc-1f32e5b4558126d872f455c65a94d9640a93c285.tar.bz2
ast: Rename ConstGenericArg -> GenericArg
This makes the class clearer and exposes the fact that it may contain a type OR a const value clearer. Because we now run in ambiguous cases later in the compiler pipeline, this commit also adds horrible hacks to simply ignore ambiguous generic arguments and treat them as type arguments.
Diffstat (limited to 'gcc/rust/ast')
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc47
-rw-r--r--gcc/rust/ast/rust-path.h172
2 files changed, 123 insertions, 96 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index d98a7cf..6c41d13 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -2598,28 +2598,14 @@ GenericArgs::as_string () const
}
// type args
- if (!type_args.empty ())
+ if (!generic_args.empty ())
{
- auto i = type_args.begin ();
- auto e = type_args.end ();
+ auto i = generic_args.begin ();
+ auto e = generic_args.end ();
for (; i != e; i++)
{
- args += (*i)->as_string ();
- if (e != i + 1)
- args += ", ";
- }
- }
-
- // const args
- if (!const_args.empty ())
- {
- auto i = const_args.begin ();
- auto e = const_args.end ();
-
- for (; i != e; i++)
- {
- args += i->as_string ();
+ args += (*i).as_string ();
if (e != i + 1)
args += ", ";
}
@@ -5800,15 +5786,28 @@ MetaWord::accept_vis (ASTVisitor &vis)
vis.visit (*this);
}
-ConstGenericArg
-ConstGenericArg::disambiguate_to_const () const
+GenericArg
+GenericArg::disambiguate_to_const () const
{
- rust_assert (get_kind () == Kind::Ambiguous);
+ rust_assert (get_kind () == Kind::Either);
// FIXME: is it fine to have no outer attributes?
- return ConstGenericArg (std::unique_ptr<Expr> (
- new IdentifierExpr (path, {}, locus)),
- locus);
+ return GenericArg::create_const (
+ std::unique_ptr<Expr> (new IdentifierExpr (path, {}, locus)));
+}
+
+GenericArg
+GenericArg::disambiguate_to_type () const
+{
+ rust_assert (get_kind () == Kind::Either);
+
+ auto segment = std::unique_ptr<TypePathSegment> (
+ new TypePathSegment (path, false, locus));
+ auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
+ segments.emplace_back (std::move (segment));
+
+ return GenericArg::create_type (
+ std::unique_ptr<Type> (new TypePath (std::move (segments), locus)));
}
} // namespace AST
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index c6485c0..722ed93 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -132,7 +132,7 @@ public:
};
/* Class representing a const generic application */
-class ConstGenericArg
+class GenericArg
{
public:
/**
@@ -152,32 +152,43 @@ public:
enum class Kind
{
Error,
- Clear,
- Ambiguous,
+ Const, // A const value
+ Type, // A type argument (not discernable during parsing)
+ Either, // Either a type or a const value, cleared up during resolving
};
- static ConstGenericArg create_error ()
+ static GenericArg create_error ()
{
- return ConstGenericArg (nullptr, "", Kind::Error, Location ());
+ return GenericArg (nullptr, nullptr, "", Kind::Error, Location ());
}
- ConstGenericArg (std::unique_ptr<Expr> expression, Location locus)
- : expression (std::move (expression)), path (""), kind (Kind::Clear),
- locus (locus)
- {}
+ static GenericArg create_const (std::unique_ptr<Expr> expression)
+ {
+ return GenericArg (std::move (expression), nullptr, "", Kind::Const,
+ expression->get_locus ());
+ }
- ConstGenericArg (Identifier path, Location locus)
- : expression (nullptr), path (path), kind (Kind::Ambiguous), locus (locus)
- {}
+ static GenericArg create_type (std::unique_ptr<Type> type)
+ {
+ return GenericArg (nullptr, std::move (type), "", Kind::Type,
+ type->get_locus ());
+ }
- ConstGenericArg (const ConstGenericArg &other)
+ static GenericArg create_ambiguous (Identifier path, Location locus)
+ {
+ return GenericArg (nullptr, nullptr, std::move (path), Kind::Either, locus);
+ }
+
+ GenericArg (const GenericArg &other)
: path (other.path), kind (other.kind), locus (other.locus)
{
if (other.expression)
expression = other.expression->clone_expr ();
+ if (other.type)
+ type = other.type->clone_type ();
}
- ConstGenericArg operator= (const ConstGenericArg &other)
+ GenericArg operator= (const GenericArg &other)
{
kind = other.kind;
path = other.path;
@@ -185,6 +196,8 @@ public:
if (other.expression)
expression = other.expression->clone_expr ();
+ if (other.type)
+ type = other.type->clone_type ();
return *this;
}
@@ -192,40 +205,63 @@ public:
bool is_error () const { return kind == Kind::Error; }
Kind get_kind () const { return kind; }
+ const Location &get_locus () const { return locus; }
- const std::unique_ptr<AST::Expr> &get_expression () const
+ std::unique_ptr<Expr> &get_expression ()
{
- rust_assert (kind == Kind::Clear);
+ rust_assert (kind == Kind::Const);
return expression;
}
+ std::unique_ptr<Type> &get_type ()
+ {
+ rust_assert (kind == Kind::Type);
+
+ return type;
+ }
+
+ const std::string &get_path () const
+ {
+ rust_assert (kind == Kind::Either);
+
+ return path;
+ }
+
std::string as_string () const
{
switch (get_kind ())
{
case Kind::Error:
gcc_unreachable ();
- case Kind::Ambiguous:
+ case Kind::Either:
return "Ambiguous: " + path;
- case Kind::Clear:
- return "Clear: { " + expression->as_string () + " }";
+ case Kind::Const:
+ return "Const: { " + expression->as_string () + " }";
+ case Kind::Type:
+ return "Type: " + type->as_string ();
}
return "";
}
/**
- * Disambiguate an amibguous const generic argument or generic type argument
- * to a const generic argument, unequivocally
+ * Disambiguate an ambiguous generic argument to a const generic argument,
+ * unequivocally
*/
- ConstGenericArg disambiguate_to_const () const;
+ GenericArg disambiguate_to_const () const;
+
+ /**
+ * Disambiguate an ambiguous generic argument to a type argument,
+ * unequivocally
+ */
+ GenericArg disambiguate_to_type () const;
private:
- ConstGenericArg (std::unique_ptr<AST::Expr> expression, Identifier path,
- Kind kind, Location locus)
- : expression (std::move (expression)), path (std::move (path)), kind (kind),
- locus (locus)
+ GenericArg (std::unique_ptr<Expr> expression, std::unique_ptr<Type> type,
+ Identifier path, Kind kind, Location locus)
+ : expression (std::move (expression)), type (std::move (type)),
+ path (std::move (path)), kind (kind), locus (locus)
{}
/**
@@ -236,8 +272,14 @@ private:
std::unique_ptr<Expr> expression;
/**
+ * If the argument ends up being a type argument instead. A null pointer will
+ * be present here until the resolving phase.
+ */
+ std::unique_ptr<Type> type;
+
+ /**
* Optional path which cannot be differentiated between a constant item and
- * a type. Only used for `Ambiguous` const generic arguments, otherwise
+ * a type. Only used for ambiguous const generic arguments, otherwise
* empty.
*/
Identifier path;
@@ -262,14 +304,14 @@ class ConstGenericParam : public GenericParam
/**
* Default value for the const generic parameter
*/
- ConstGenericArg default_value;
+ GenericArg default_value;
Attribute outer_attr;
Location locus;
public:
ConstGenericParam (Identifier name, std::unique_ptr<AST::Type> type,
- ConstGenericArg default_value, Attribute outer_attr,
+ GenericArg default_value, Attribute outer_attr,
Location locus)
: name (name), type (std::move (type)),
default_value (std::move (default_value)), outer_attr (outer_attr),
@@ -294,7 +336,14 @@ public:
return type;
}
- const ConstGenericArg &get_default_value () const
+ GenericArg &get_default_value ()
+ {
+ rust_assert (has_default_value ());
+
+ return default_value;
+ }
+
+ const GenericArg &get_default_value () const
{
rust_assert (has_default_value ());
@@ -322,39 +371,32 @@ protected:
struct GenericArgs
{
std::vector<Lifetime> lifetime_args;
- std::vector<std::unique_ptr<Type> > type_args;
+ std::vector<GenericArg> generic_args;
std::vector<GenericArgsBinding> binding_args;
- std::vector<ConstGenericArg> const_args;
Location locus;
public:
// Returns true if there are any generic arguments
bool has_generic_args () const
{
- return !(lifetime_args.empty () && type_args.empty ()
- && binding_args.empty () && const_args.empty ());
+ return !(lifetime_args.empty () && generic_args.empty ()
+ && binding_args.empty ());
}
GenericArgs (std::vector<Lifetime> lifetime_args,
- std::vector<std::unique_ptr<Type> > type_args,
+ std::vector<GenericArg> generic_args,
std::vector<GenericArgsBinding> binding_args,
- std::vector<ConstGenericArg> const_args,
Location locus = Location ())
: lifetime_args (std::move (lifetime_args)),
- type_args (std::move (type_args)),
- binding_args (std::move (binding_args)),
- const_args (std::move (const_args)), locus (locus)
+ generic_args (std::move (generic_args)),
+ binding_args (std::move (binding_args)), locus (locus)
{}
// copy constructor with vector clone
GenericArgs (GenericArgs const &other)
- : lifetime_args (other.lifetime_args), binding_args (other.binding_args),
- const_args (other.const_args), locus (other.locus)
- {
- type_args.reserve (other.type_args.size ());
- for (const auto &e : other.type_args)
- type_args.push_back (e->clone_type ());
- }
+ : lifetime_args (other.lifetime_args), generic_args (other.generic_args),
+ binding_args (other.binding_args), locus (other.locus)
+ {}
~GenericArgs () = default;
@@ -362,14 +404,10 @@ public:
GenericArgs &operator= (GenericArgs const &other)
{
lifetime_args = other.lifetime_args;
+ generic_args = other.generic_args;
binding_args = other.binding_args;
- const_args = other.const_args;
locus = other.locus;
- type_args.reserve (other.type_args.size ());
- for (const auto &e : other.type_args)
- type_args.push_back (e->clone_type ());
-
return *this;
}
@@ -378,26 +416,18 @@ public:
GenericArgs &operator= (GenericArgs &&other) = default;
// Creates an empty GenericArgs (no arguments)
- static GenericArgs create_empty ()
- {
- return GenericArgs (std::vector<Lifetime> (),
- std::vector<std::unique_ptr<Type> > (),
- std::vector<GenericArgsBinding> (),
- std::vector<ConstGenericArg> ());
- }
+ static GenericArgs create_empty () { return GenericArgs ({}, {}, {}); }
std::string as_string () const;
// TODO: is this better? Or is a "vis_pattern" better?
- std::vector<std::unique_ptr<Type> > &get_type_args () { return type_args; }
+ std::vector<GenericArg> &get_generic_args () { return generic_args; }
// TODO: is this better? Or is a "vis_pattern" better?
std::vector<GenericArgsBinding> &get_binding_args () { return binding_args; }
std::vector<Lifetime> &get_lifetime_args () { return lifetime_args; };
- std::vector<ConstGenericArg> &get_const_args () { return const_args; };
-
Location get_locus () { return locus; }
};
@@ -427,13 +457,12 @@ public:
* args) */
PathExprSegment (std::string segment_name, Location locus,
std::vector<Lifetime> lifetime_args = {},
- std::vector<std::unique_ptr<Type> > type_args = {},
- std::vector<GenericArgsBinding> binding_args = {},
- std::vector<ConstGenericArg> const_args = {})
+ std::vector<GenericArg> generic_args = {},
+ std::vector<GenericArgsBinding> binding_args = {})
: segment_name (PathIdentSegment (std::move (segment_name), locus)),
- generic_args (
- GenericArgs (std::move (lifetime_args), std::move (type_args),
- std::move (binding_args), std::move (const_args))),
+ generic_args (GenericArgs (std::move (lifetime_args),
+ std::move (generic_args),
+ std::move (binding_args))),
locus (locus), node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
@@ -724,15 +753,14 @@ public:
TypePathSegmentGeneric (std::string segment_name,
bool has_separating_scope_resolution,
std::vector<Lifetime> lifetime_args,
- std::vector<std::unique_ptr<Type> > type_args,
+ std::vector<GenericArg> generic_args,
std::vector<GenericArgsBinding> binding_args,
- std::vector<ConstGenericArg> const_args,
Location locus)
: TypePathSegment (std::move (segment_name),
has_separating_scope_resolution, locus),
- generic_args (
- GenericArgs (std::move (lifetime_args), std::move (type_args),
- std::move (binding_args), std::move (const_args)))
+ generic_args (GenericArgs (std::move (lifetime_args),
+ std::move (generic_args),
+ std::move (binding_args)))
{}
std::string as_string () const override;