Skip to content

Commit c825189

Browse files
committed
derive: Implement reconstruct_path helper for cmp
This patch introduces a local helper to clone PathInExpression objects. This allows removing duplicate calls to , fulfilling the TODOs in EnumMatchBuilder. This ensures the self and other paths are identical without reconstructing them from strings twice. gcc/rust/ChangeLog: * expand/rust-derive-cmp-common.cc (reconstruct_path): New helper. (EnumMatchBuilder::tuple): Use reconstruct_path. (EnumMatchBuilder::strukt): Use reconstruct_path. Signed-off-by: Jayant Chauhan <[email protected]>
1 parent 23de527 commit c825189

File tree

2 files changed

+67
-4
lines changed

2 files changed

+67
-4
lines changed

gcc/rust/ast/rust-path.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,16 @@ struct GenericArgsBinding
8383
return type == nullptr;
8484
// and also identifier is empty, but cheaper computation
8585
}
86+
Identifier get_identifier() const { return identifier; }
87+
88+
GenericArgsBinding reconstruct() const
89+
{
90+
std::unique_ptr<Type> new_type = nullptr;
91+
if (type)
92+
new_type = type->reconstruct();
93+
94+
return GenericArgsBinding(identifier, std::move(new_type), locus);
95+
}
8696

8797
// Creates an error state generic args binding.
8898
static GenericArgsBinding create_error ()
@@ -189,6 +199,24 @@ class GenericArg
189199
{
190200
return GenericArg (nullptr, nullptr, std::move (path), Kind::Either, locus);
191201
}
202+
Kind get_kind() const { return kind; }
203+
location_t get_locus() const { return locus; }
204+
205+
GenericArg reconstruct() const
206+
{
207+
switch (kind)
208+
{
209+
case Kind::Type:
210+
return create_type(type->reconstruct());
211+
case Kind::Const:
212+
// FIXME: Use reconstruct_expr when available
213+
return create_const(expression->clone_expr());
214+
case Kind::Either:
215+
default:
216+
// For ambiguous or error states, copy constructs are sufficient
217+
return GenericArg(*this);
218+
}
219+
}
192220

193221
GenericArg (const GenericArg &other)
194222
: path (other.path), kind (other.kind), locus (other.locus)
@@ -460,6 +488,23 @@ struct GenericArgs
460488

461489
~GenericArgs () = default;
462490

491+
GenericArgs reconstruct() const
492+
{
493+
std::vector<GenericArg> new_args;
494+
new_args.reserve(generic_args.size());
495+
for (const auto &arg : generic_args)
496+
new_args.push_back(arg.reconstruct());
497+
498+
std::vector<GenericArgsBinding> new_bindings;
499+
new_bindings.reserve(binding_args.size());
500+
for (const auto &binding : binding_args)
501+
new_bindings.push_back(binding.reconstruct());
502+
503+
// Lifetimes are values, so they can be copied directly
504+
return GenericArgs(lifetime_args, std::move(new_args),
505+
std::move(new_bindings), locus);
506+
}
507+
463508
// overloaded assignment operator to vector clone
464509
GenericArgs &operator= (GenericArgs const &other)
465510
{
@@ -563,6 +608,11 @@ class PathExprSegment
563608

564609
NodeId get_node_id () const { return node_id; }
565610

611+
PathExprSegment reconstruct() const
612+
{
613+
return PathExprSegment(segment_name, locus, generic_args.reconstruct());
614+
}
615+
566616
bool is_super_path_seg () const
567617
{
568618
return !has_generic_args () && get_ident_segment ().is_super_path_seg ();
@@ -705,6 +755,19 @@ class PathInExpression : public Path, public ExprWithoutBlock
705755
return convert_to_simple_path (has_opening_scope_resolution);
706756
}
707757

758+
std::unique_ptr<PathInExpression> reconstruct() const
759+
{
760+
std::vector<PathExprSegment> new_segments;
761+
new_segments.reserve(segments.size());
762+
for (const auto &seg : segments)
763+
new_segments.push_back(seg.reconstruct());
764+
765+
auto *new_path = new PathInExpression(std::move(new_segments), outer_attrs, locus,
766+
has_opening_scope_resolution);
767+
768+
return std::unique_ptr<PathInExpression>(new_path);
769+
}
770+
708771
location_t get_locus () const override final { return locus; }
709772

710773
void accept_vis (ASTVisitor &vis) override;

gcc/rust/expand/rust-derive-cmp-common.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,10 @@ EnumMatchBuilder::tuple (EnumItem &variant_raw)
9696
});
9797
}
9898

99-
// TODO: Replace with `reconstruct()` instead of building these twice
10099
auto self_variant_path = builder.variant_path (enum_path, variant_path);
101-
auto other_variant_path = builder.variant_path (enum_path, variant_path);
100+
// Dereference the unique_ptr if you need the object directly,
101+
// or move it if you need ownership.
102+
auto other_variant_path = *self_variant_path.reconstruct();
102103

103104
auto self_pattern_items = std::unique_ptr<TupleStructItems> (
104105
new TupleStructItemsNoRest (std::move (self_patterns)));
@@ -159,9 +160,8 @@ EnumMatchBuilder::strukt (EnumItem &variant_raw)
159160
});
160161
}
161162

162-
// TODO: Replace with `reconstruct()` instead of building these twice
163163
auto self_variant_path = builder.variant_path (enum_path, variant_path);
164-
auto other_variant_path = builder.variant_path (enum_path, variant_path);
164+
auto other_variant_path = reconstruct_path (self_variant_path);
165165

166166
auto self_elts = StructPatternElements (std::move (self_fields));
167167
auto other_elts = StructPatternElements (std::move (other_fields));

0 commit comments

Comments
 (0)