From: Arthur Cohen <[email protected]>
gcc/rust/ChangeLog:
* ast/rust-ast.h: Add reconstruct() and reconstruct_impl() for Type
nodes.
* ast/rust-type.h: Implement them.
* ast/rust-macro.h: Likewise.
* ast/rust-path.h: Likewise.
---
gcc/rust/ast/rust-ast.h | 45 ++++++++++++-----
gcc/rust/ast/rust-macro.h | 20 +++++---
gcc/rust/ast/rust-path.h | 30 +++++++++++
gcc/rust/ast/rust-type.h | 103 +++++++++++++++++++++++++++++++++-----
4 files changed, 167 insertions(+), 31 deletions(-)
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 1cc10c90ee8..ecbc2918130 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -88,11 +88,11 @@ public:
* different from the old NodeId. It then wraps the given pointer into a unique
* pointer and returns it.
*/
-template <typename T, typename F>
+template <typename T>
std::unique_ptr<T>
-reconstruct (const T *instance, F method)
+reconstruct_base (const T *instance)
{
- auto *reconstructed = (instance->*method) ();
+ auto *reconstructed = instance->reconstruct_impl ();
rust_assert (reconstructed->get_node_id () != instance->get_node_id ());
@@ -102,19 +102,14 @@ reconstruct (const T *instance, F method)
/**
* Reconstruct multiple items in a vector
*/
-template <typename T, typename F>
+template <typename T>
std::vector<std::unique_ptr<T>>
-reconstruct_vec (const std::vector<std::unique_ptr<T>> &to_reconstruct,
- F method)
+reconstruct_vec (const std::vector<std::unique_ptr<T>> &to_reconstruct)
{
std::vector<std::unique_ptr<T>> reconstructed;
for (const auto &elt : to_reconstruct)
- {
- auto new_elt = (elt.get ()->*method) ();
-
- reconstructed.emplace_back (std::move (new_elt));
- }
+ reconstructed.emplace_back (std::unique_ptr<T> (elt->reconstruct_impl ()));
return reconstructed;
}
@@ -1516,6 +1511,10 @@ public:
return std::unique_ptr<Type> (clone_type_impl ());
}
+ // Similar to `clone_type`, but generates a new instance of the node with a
+ // different NodeId
+ std::unique_ptr<Type> reconstruct () const { return reconstruct_base (this);
}
+
// virtual destructor
virtual ~Type () {}
@@ -1534,11 +1533,13 @@ public:
virtual location_t get_locus () const = 0;
NodeId get_node_id () const { return node_id; }
+ virtual Type *reconstruct_impl () const = 0;
protected:
Type () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
+ Type (NodeId node_id) : node_id (node_id) {}
- // Clone function implementation as pure virtual method
+ // Clone and reconstruct function implementations as pure virtual methods
virtual Type *clone_type_impl () const = 0;
NodeId node_id;
@@ -1554,6 +1555,13 @@ public:
return std::unique_ptr<TypeNoBounds> (clone_type_no_bounds_impl ());
}
+ std::unique_ptr<TypeNoBounds> reconstruct () const
+ {
+ return reconstruct_base (this);
+ }
+
+ virtual TypeNoBounds *reconstruct_impl () const override = 0;
+
protected:
// Clone function implementation as pure virtual method
virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0;
@@ -1588,6 +1596,11 @@ public:
return std::unique_ptr<TypeParamBound> (clone_type_param_bound_impl ());
}
+ std::unique_ptr<TypeParamBound> reconstruct () const
+ {
+ return reconstruct_base (this);
+ }
+
virtual std::string as_string () const = 0;
NodeId get_node_id () const { return node_id; }
@@ -1596,10 +1609,14 @@ public:
virtual TypeParamBoundType get_bound_type () const = 0;
+ virtual TypeParamBound *reconstruct_impl () const = 0;
+
protected:
// Clone function implementation as pure virtual method
virtual TypeParamBound *clone_type_param_bound_impl () const = 0;
+ TypeParamBound () : node_id (Analysis::Mappings::get ().get_next_node_id ())
+ {}
TypeParamBound (NodeId node_id) : node_id (node_id) {}
NodeId node_id;
@@ -1661,6 +1678,10 @@ protected:
{
return new Lifetime (node_id, lifetime_type, lifetime_name, locus);
}
+ Lifetime *reconstruct_impl () const override
+ {
+ return new Lifetime (lifetime_type, lifetime_name, locus);
+ }
};
/* Base generic parameter in AST. Abstract - can be represented by a Lifetime
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index fc01e571b91..e8f377c001e 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -756,22 +756,16 @@ private:
std::vector<std::unique_ptr<MacroInvocation>> pending_eager_invocs;
protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
MacroInvocation *clone_pattern_impl () const final override
{
return clone_macro_invocation_impl ();
}
- /* Use covariance to implement clone function as returning this object rather
- * than base */
MacroInvocation *clone_expr_without_block_impl () const final override
{
return clone_macro_invocation_impl ();
}
- /* Use covariance to implement clone function as returning this object rather
- * than base */
MacroInvocation *clone_type_no_bounds_impl () const final override
{
return clone_macro_invocation_impl ();
@@ -788,6 +782,20 @@ public:
return new MacroInvocation (*this);
}
+ std::unique_ptr<MacroInvocation> reconstruct_macro_invocation () const
+ {
+ return nullptr;
+ // return reconstruct (this,
+ // &MacroInvocation::reconstruct_macro_invocation_impl);
+ }
+
+ MacroInvocation *reconstruct_impl () const override
+ {
+ return new MacroInvocation (kind, builtin_kind, invoc_data, outer_attrs,
+ locus, is_semi_coloned,
+ reconstruct_vec (pending_eager_invocs));
+ }
+
void add_semicolon () override { is_semi_coloned = true; }
Pattern::Kind get_pattern_kind () override
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index de895a2f838..a1b19d559c3 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -786,6 +786,11 @@ public:
{
return new TypePathSegment (*this);
}
+ virtual TypePathSegment *reconstruct_impl () const
+ {
+ return new TypePathSegment (lang_item, ident_segment,
+ has_separating_scope_resolution, locus);
+ }
public:
virtual ~TypePathSegment () {}
@@ -797,6 +802,11 @@ public:
{
return std::unique_ptr<TypePathSegment> (clone_type_path_segment_impl ());
}
+ // Unique pointer custom reconstruct function
+ std::unique_ptr<TypePathSegment> reconstruct () const
+ {
+ return reconstruct_base (this);
+ }
TypePathSegment (PathIdentSegment ident_segment,
bool has_separating_scope_resolution, location_t locus)
@@ -821,6 +831,15 @@ public:
node_id (Analysis::Mappings::get ().get_next_node_id ())
{}
+ // General constructor
+ TypePathSegment (tl::optional<LangItem::Kind> lang_item,
+ tl::optional<PathIdentSegment> ident_segment,
+ bool has_separating_scope_resolution, location_t locus)
+ : lang_item (lang_item), ident_segment (ident_segment), locus (locus),
+ has_separating_scope_resolution (has_separating_scope_resolution),
+ node_id (Analysis::Mappings::get ().get_next_node_id ())
+ {}
+
TypePathSegment (TypePathSegment const &other)
: lang_item (other.lang_item), ident_segment (other.ident_segment),
locus (other.locus),
@@ -1152,6 +1171,11 @@ protected:
{
return new TypePath (*this);
}
+ TypePath *reconstruct_impl () const override
+ {
+ return new TypePath (reconstruct_vec (segments), locus,
+ has_opening_scope_resolution);
+ }
public:
/* Returns whether the TypePath has an opening scope resolution operator
@@ -1443,6 +1467,12 @@ protected:
{
return new QualifiedPathInType (*this);
}
+ QualifiedPathInType *reconstruct_impl () const override
+ {
+ return new QualifiedPathInType (path_type,
+ associated_segment->reconstruct (),
+ reconstruct_vec (segments), locus);
+ }
public:
QualifiedPathInType (
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index 6c0652a013f..abbfd36a6f5 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -19,6 +19,7 @@
#ifndef RUST_AST_TYPE_H
#define RUST_AST_TYPE_H
+#include "optional.h"
#include "rust-ast.h"
#include "rust-path.h"
@@ -106,6 +107,11 @@ protected:
return new TraitBound (node_id, type_path, locus, in_parens,
opening_question_mark, for_lifetimes);
}
+ TraitBound *reconstruct_impl () const override
+ {
+ return new TraitBound (type_path, locus, in_parens, opening_question_mark,
+ for_lifetimes);
+ }
};
// definition moved to rust-ast.h
@@ -127,6 +133,10 @@ protected:
{
return new ImplTraitType (*this);
}
+ ImplTraitType *reconstruct_impl () const override
+ {
+ return new ImplTraitType (reconstruct_vec (type_param_bounds), locus);
+ }
public:
ImplTraitType (
@@ -136,7 +146,8 @@ public:
{}
// copy constructor with vector clone
- ImplTraitType (ImplTraitType const &other) : locus (other.locus)
+ ImplTraitType (ImplTraitType const &other)
+ : Type (other.node_id), locus (other.locus)
{
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
@@ -191,6 +202,11 @@ protected:
{
return new TraitObjectType (*this);
}
+ TraitObjectType *reconstruct_impl () const override
+ {
+ return new TraitObjectType (reconstruct_vec (type_param_bounds), locus,
+ has_dyn);
+ }
public:
TraitObjectType (
@@ -202,7 +218,7 @@ public:
// copy constructor with vector clone
TraitObjectType (TraitObjectType const &other)
- : has_dyn (other.has_dyn), locus (other.locus)
+ : Type (other.node_id), has_dyn (other.has_dyn), locus (other.locus)
{
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
@@ -258,6 +274,10 @@ protected:
{
return new ParenthesisedType (*this);
}
+ ParenthesisedType *reconstruct_impl () const override
+ {
+ return new ParenthesisedType (type_in_parens->reconstruct (), locus);
+ }
public:
// Constructor uses Type pointer for polymorphism
@@ -338,6 +358,10 @@ public:
{
return new ImplTraitTypeOneBound (*this);
}
+ TypeNoBounds *reconstruct_impl () const override
+ {
+ return new ImplTraitTypeOneBound (trait_bound->reconstruct (), locus);
+ }
};
/* A trait object with a single trait bound. The "trait bound" is really just
@@ -355,6 +379,10 @@ protected:
{
return new TraitObjectTypeOneBound (*this);
}
+ TraitObjectTypeOneBound *reconstruct_impl () const override
+ {
+ return new TraitObjectTypeOneBound (trait_bound, locus, has_dyn);
+ }
public:
TraitObjectTypeOneBound (TraitBound trait_bound, location_t locus,
@@ -448,6 +476,10 @@ protected:
{
return new TupleType (*this);
}
+ TupleType *reconstruct_impl () const override
+ {
+ return new TupleType (reconstruct_vec (elems), locus);
+ }
};
/* A type with no values, representing the result of computations that never
@@ -464,6 +496,10 @@ protected:
{
return new NeverType (*this);
}
+ NeverType *reconstruct_impl () const override
+ {
+ return new NeverType (locus);
+ }
public:
NeverType (location_t locus) : locus (locus) {}
@@ -544,6 +580,10 @@ protected:
{
return new RawPointerType (*this);
}
+ RawPointerType *reconstruct_impl () const override
+ {
+ return new RawPointerType (pointer_type, type->reconstruct (), locus);
+ }
};
// A type pointing to memory owned by another value
@@ -622,6 +662,16 @@ protected:
{
return new ReferenceType (*this);
}
+ ReferenceType *reconstruct_impl () const override
+ {
+ return new ReferenceType (has_mut, type->reconstruct (), locus,
+ // TODO: Improve this - it's ugly!
+ has_lifetime () ? tl::make_optional<Lifetime> (
+ lifetime->get_lifetime_type (),
+ lifetime->get_lifetime_name (),
+ lifetime->get_locus ())
+ : tl::nullopt);
+ }
};
// A fixed-size sequence of elements of a specified type
@@ -689,6 +739,13 @@ protected:
{
return new ArrayType (*this);
}
+ ArrayType *reconstruct_impl () const override
+ {
+ return new ArrayType (
+ elem_type->reconstruct (),
+ size->clone_expr () /* FIXME: This should be `reconstruct_expr()` */,
+ locus);
+ }
};
/* A dynamically-sized type representing a "view" into a sequence of elements
of
@@ -739,12 +796,16 @@ public:
std::unique_ptr<Type> &get_elem_type_ptr () { return elem_type; }
protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
+ /* Use covariance to implement clone function as returning this object
+ * rather than base */
SliceType *clone_type_no_bounds_impl () const override
{
return new SliceType (*this);
}
+ SliceType *reconstruct_impl () const override
+ {
+ return new SliceType (elem_type->reconstruct (), locus);
+ }
};
/* Type used in generic arguments to explicitly request type inference
(wildcard
@@ -755,13 +816,21 @@ class InferredType : public TypeNoBounds
// e.g. Vec<_> = whatever
protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
+ /* Use covariance to implement clone function as returning this object
+ * rather than base */
InferredType *clone_type_no_bounds_impl () const override
{
+ // This goes through the copy constructor
return new InferredType (*this);
}
+ InferredType *reconstruct_impl () const override
+ {
+ // This goes through the base constructor which calls the base
+ // TypeNoBounds constructor, which allocates a new NodeId
+ return new InferredType (locus);
+ }
+
public:
InferredType (location_t locus) : locus (locus) {}
@@ -980,9 +1049,17 @@ public:
FunctionQualifiers &get_function_qualifiers () { return function_qualifiers;
}
+ BareFunctionType *reconstruct_impl () const override
+ {
+ return new BareFunctionType (
+ for_lifetimes, function_qualifiers, params,
+ /* FIXME: Should params be reconstruct() as well? */
+ _is_variadic, variadic_attrs, return_type->reconstruct (), locus);
+ }
+
protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
+ /* Use covariance to implement clone function as returning this object
+ * rather than base */
BareFunctionType *clone_type_no_bounds_impl () const override
{
return new BareFunctionType (*this);
@@ -999,13 +1076,13 @@ class MacroInvocation;
* function item type?
* closure expression types?
* primitive types (bool, int, float, char, str (the slice))
- * Although supposedly TypePaths are used to reference these types (including
- * primitives) */
+ * Although supposedly TypePaths are used to reference these types
+ * (including primitives) */
/* FIXME: Incomplete spec references:
- * anonymous type parameters, aka "impl Trait in argument position" - impl
then
- * trait bounds abstract return types, aka "impl Trait in return position" -
- * impl then trait bounds */
+ * anonymous type parameters, aka "impl Trait in argument position" - impl
+ * then trait bounds abstract return types, aka "impl Trait in return
+ * position" - impl then trait bounds */
} // namespace AST
} // namespace Rust
--
2.49.0