@@ -84,6 +84,15 @@ struct GenericArgsBinding
8484 // and also identifier is empty, but cheaper computation
8585 }
8686
87+ GenericArgsBinding reconstruct () const
88+ {
89+ std::unique_ptr<Type> new_type = nullptr ;
90+ if (type)
91+ new_type = type->reconstruct ();
92+
93+ return GenericArgsBinding (identifier, std::move (new_type), locus);
94+ }
95+
8796 // Creates an error state generic args binding.
8897 static GenericArgsBinding create_error ()
8998 {
@@ -190,6 +199,22 @@ class GenericArg
190199 return GenericArg (nullptr , nullptr , std::move (path), Kind::Either, locus);
191200 }
192201
202+ GenericArg reconstruct () const
203+ {
204+ switch (kind)
205+ {
206+ case Kind::Type:
207+ return create_type (type->reconstruct ());
208+ case Kind::Const:
209+ // FIXME: Use reconstruct_expr when available
210+ return create_const (expression->clone_expr ());
211+ case Kind::Either:
212+ default :
213+ // For ambiguous or error states, copy constructs are sufficient
214+ return GenericArg (*this );
215+ }
216+ }
217+
193218 GenericArg (const GenericArg &other)
194219 : path (other.path), kind (other.kind), locus (other.locus)
195220 {
@@ -460,6 +485,23 @@ struct GenericArgs
460485
461486 ~GenericArgs () = default ;
462487
488+ GenericArgs reconstruct () const
489+ {
490+ std::vector<GenericArg> new_args;
491+ new_args.reserve (generic_args.size ());
492+ for (const auto &arg : generic_args)
493+ new_args.push_back (arg.reconstruct ());
494+
495+ std::vector<GenericArgsBinding> new_bindings;
496+ new_bindings.reserve (binding_args.size ());
497+ for (const auto &binding : binding_args)
498+ new_bindings.push_back (binding.reconstruct ());
499+
500+ // Lifetimes are values, so they can be copied directly
501+ return GenericArgs (lifetime_args, std::move (new_args),
502+ std::move (new_bindings), locus);
503+ }
504+
463505 // overloaded assignment operator to vector clone
464506 GenericArgs &operator = (GenericArgs const &other)
465507 {
@@ -563,6 +605,11 @@ class PathExprSegment
563605
564606 NodeId get_node_id () const { return node_id; }
565607
608+ PathExprSegment reconstruct () const
609+ {
610+ return PathExprSegment (segment_name, locus, generic_args.reconstruct ());
611+ }
612+
566613 bool is_super_path_seg () const
567614 {
568615 return !has_generic_args () && get_ident_segment ().is_super_path_seg ();
@@ -705,6 +752,20 @@ class PathInExpression : public Path, public ExprWithoutBlock
705752 return convert_to_simple_path (has_opening_scope_resolution);
706753 }
707754
755+ std::unique_ptr<PathInExpression> reconstruct () const
756+ {
757+ std::vector<PathExprSegment> new_segments;
758+ new_segments.reserve (segments.size ());
759+ for (const auto &seg : segments)
760+ new_segments.push_back (seg.reconstruct ());
761+
762+ auto *new_path
763+ = new PathInExpression (std::move (new_segments), outer_attrs, locus,
764+ has_opening_scope_resolution);
765+
766+ return std::unique_ptr<PathInExpression> (new_path);
767+ }
768+
708769 location_t get_locus () const override final { return locus; }
709770
710771 void accept_vis (ASTVisitor &vis) override ;
@@ -1004,6 +1065,14 @@ class TypePathSegmentGeneric : public TypePathSegment
10041065 {
10051066 return new TypePathSegmentGeneric (*this );
10061067 }
1068+
1069+ TypePathSegmentGeneric *reconstruct_impl () const override
1070+ {
1071+ return new TypePathSegmentGeneric (get_ident_segment (),
1072+ has_separating_scope_resolution,
1073+ generic_args.reconstruct (),
1074+ get_locus ());
1075+ }
10071076};
10081077
10091078// A function as represented in a type path
@@ -1112,6 +1181,21 @@ struct TypePathFunction
11121181 return return_type;
11131182 }
11141183
1184+ TypePathFunction reconstruct () const
1185+ {
1186+ std::vector<std::unique_ptr<Type>> new_inputs;
1187+ new_inputs.reserve (inputs.size ());
1188+ for (const auto &e : inputs)
1189+ new_inputs.push_back (e->reconstruct ());
1190+
1191+ std::unique_ptr<Type> new_ret = nullptr ;
1192+ if (return_type)
1193+ new_ret = return_type->reconstruct ();
1194+
1195+ return TypePathFunction (std::move (new_inputs), locus,
1196+ std::move (new_ret));
1197+ }
1198+
11151199 location_t get_locus () const { return locus; }
11161200};
11171201
@@ -1159,6 +1243,14 @@ class TypePathSegmentFunction : public TypePathSegment
11591243 {
11601244 return new TypePathSegmentFunction (*this );
11611245 }
1246+
1247+ TypePathSegmentFunction *reconstruct_impl () const override
1248+ {
1249+ return new TypePathSegmentFunction (get_ident_segment (),
1250+ has_separating_scope_resolution,
1251+ function_path.reconstruct (),
1252+ get_locus ());
1253+ }
11621254};
11631255
11641256class TypePath : public TypeNoBounds
@@ -1327,6 +1419,20 @@ struct QualifiedPathType
13271419 QualifiedPathType (QualifiedPathType &&other) = default ;
13281420 QualifiedPathType &operator = (QualifiedPathType &&other) = default ;
13291421
1422+ QualifiedPathType reconstruct () const
1423+ {
1424+ auto new_type = type_to_invoke_on->reconstruct ();
1425+
1426+ // trait_path is stored by value, but reconstruct returns a unique_ptr.
1427+ // We must dereference it to pass to the constructor.
1428+ // This is safe because the constructor makes its own copy/move.
1429+ auto new_trait_path_ptr = trait_path.reconstruct ();
1430+ TypePath *concrete_ptr
1431+ = static_cast <TypePath *> (new_trait_path_ptr.get ());
1432+
1433+ return QualifiedPathType (std::move (new_type), locus, *concrete_ptr);
1434+ }
1435+
13301436 // Returns whether the qualified path type has a rebind as clause.
13311437 bool has_as_clause () const { return !trait_path.is_error (); }
13321438
@@ -1433,6 +1539,20 @@ class QualifiedPathInExpression : public Path, public ExprWithoutBlock
14331539 return Expr::Kind::QualifiedPathInExpression;
14341540 }
14351541
1542+ std::unique_ptr<QualifiedPathInExpression> reconstruct () const
1543+ {
1544+ std::vector<PathExprSegment> new_segments;
1545+ new_segments.reserve (segments.size ());
1546+ for (const auto &seg : segments)
1547+ new_segments.push_back (seg.reconstruct ());
1548+
1549+ auto *new_path = new QualifiedPathInExpression (path_type.reconstruct (),
1550+ std::move (new_segments),
1551+ outer_attrs, locus);
1552+
1553+ return std::unique_ptr<QualifiedPathInExpression> (new_path);
1554+ }
1555+
14361556protected:
14371557 /* Use covariance to implement clone function as returning this object
14381558 * rather than base */
@@ -1474,7 +1594,7 @@ class QualifiedPathInType : public TypeNoBounds
14741594 }
14751595 QualifiedPathInType *reconstruct_impl () const override
14761596 {
1477- return new QualifiedPathInType (path_type,
1597+ return new QualifiedPathInType (path_type. reconstruct () ,
14781598 associated_segment->reconstruct (),
14791599 reconstruct_vec (segments), locus);
14801600 }
0 commit comments