@@ -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,13 @@ 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 (), locus);
1074+ }
10071075};
10081076
10091077// A function as represented in a type path
@@ -1112,6 +1180,21 @@ struct TypePathFunction
11121180 return return_type;
11131181 }
11141182
1183+ TypePathFunction reconstruct () const
1184+ {
1185+ std::vector<std::unique_ptr<Type>> new_inputs;
1186+ new_inputs.reserve (inputs.size ());
1187+ for (const auto &e : inputs)
1188+ new_inputs.push_back (e->reconstruct ());
1189+
1190+ std::unique_ptr<Type> new_ret = nullptr ;
1191+ if (return_type)
1192+ new_ret = return_type->reconstruct ();
1193+
1194+ return TypePathFunction (std::move (new_inputs), locus,
1195+ std::move (new_ret));
1196+ }
1197+
11151198 location_t get_locus () const { return locus; }
11161199};
11171200
@@ -1159,6 +1242,13 @@ class TypePathSegmentFunction : public TypePathSegment
11591242 {
11601243 return new TypePathSegmentFunction (*this );
11611244 }
1245+
1246+ TypePathSegmentFunction *reconstruct_impl () const override
1247+ {
1248+ return new TypePathSegmentFunction (get_ident_segment (),
1249+ has_separating_scope_resolution,
1250+ function_path.reconstruct (), locus);
1251+ }
11621252};
11631253
11641254class TypePath : public TypeNoBounds
@@ -1327,6 +1417,20 @@ struct QualifiedPathType
13271417 QualifiedPathType (QualifiedPathType &&other) = default ;
13281418 QualifiedPathType &operator = (QualifiedPathType &&other) = default ;
13291419
1420+ QualifiedPathType reconstruct () const
1421+ {
1422+ auto new_type = type_to_invoke_on->reconstruct ();
1423+
1424+ // trait_path is stored by value, but reconstruct returns a unique_ptr.
1425+ // We must dereference it to pass to the constructor.
1426+ // This is safe because the constructor makes its own copy/move.
1427+ auto new_trait_path_ptr = trait_path.reconstruct ();
1428+ TypePath *concrete_ptr
1429+ = static_cast <TypePath *> (new_trait_path_ptr.get ());
1430+
1431+ return QualifiedPathType (std::move (new_type), locus, *concrete_ptr);
1432+ }
1433+
13301434 // Returns whether the qualified path type has a rebind as clause.
13311435 bool has_as_clause () const { return !trait_path.is_error (); }
13321436
@@ -1433,6 +1537,20 @@ class QualifiedPathInExpression : public Path, public ExprWithoutBlock
14331537 return Expr::Kind::QualifiedPathInExpression;
14341538 }
14351539
1540+ std::unique_ptr<QualifiedPathInExpression> reconstruct () const
1541+ {
1542+ std::vector<PathExprSegment> new_segments;
1543+ new_segments.reserve (segments.size ());
1544+ for (const auto &seg : segments)
1545+ new_segments.push_back (seg.reconstruct ());
1546+
1547+ auto *new_path = new QualifiedPathInExpression (path_type.reconstruct (),
1548+ std::move (new_segments),
1549+ outer_attrs, locus);
1550+
1551+ return std::unique_ptr<QualifiedPathInExpression> (new_path);
1552+ }
1553+
14361554protected:
14371555 /* Use covariance to implement clone function as returning this object
14381556 * rather than base */
@@ -1474,7 +1592,7 @@ class QualifiedPathInType : public TypeNoBounds
14741592 }
14751593 QualifiedPathInType *reconstruct_impl () const override
14761594 {
1477- return new QualifiedPathInType (path_type,
1595+ return new QualifiedPathInType (path_type. reconstruct () ,
14781596 associated_segment->reconstruct (),
14791597 reconstruct_vec (segments), locus);
14801598 }
0 commit comments