]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Reduce node id sharing
authorOwen Avery <powerboat9.gamer@gmail.com>
Sun, 25 Jan 2026 19:15:38 +0000 (14:15 -0500)
committerArthur Cohen <arthur.cohen@embecosm.com>
Fri, 27 Feb 2026 14:57:10 +0000 (15:57 +0100)
Also removes some redundant copies and improves TypePath copying.

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc (Builder::trait_bound): Replace copy
with move.
(Builder::trait_impl): Likewise.
(Builder::new_const_param): Replace cloning with reconstruction.
* ast/rust-path.h (TypePath::TypePath): Use TypeNoBounds copy
constructor.
(TypePath::operator=): Use TypeNoBounds copy assignment.
* expand/rust-derive-clone.cc (DeriveClone::clone_impl): Produce
trait bounds lazily.
* expand/rust-derive-copy.cc (DeriveCopy::copy_impl): Likewise.
* expand/rust-derive-debug.cc (DeriveDebug::stub_derive_impl):
Likewise.
* expand/rust-derive-default.cc (DeriveDefault::default_impl):
Likewise.
* expand/rust-derive-eq.cc (DeriveEq::eq_impls): Likewise.
* expand/rust-derive-hash.cc (DeriveHash::hash_impl): Likewise.
* expand/rust-derive-ord.cc (DeriveOrd::cmp_impl): Likewise.
* expand/rust-derive-partial-eq.cc
(DerivePartialEq::partialeq_impls): Likewise.
* expand/rust-derive.cc (DeriveVisitor::setup_impl_generics):
Likewise.
* expand/rust-derive.h (DeriveVisitor::setup_impl_generics):
Likewise.

Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
12 files changed:
gcc/rust/ast/rust-ast-builder.cc
gcc/rust/ast/rust-path.h
gcc/rust/expand/rust-derive-clone.cc
gcc/rust/expand/rust-derive-copy.cc
gcc/rust/expand/rust-derive-debug.cc
gcc/rust/expand/rust-derive-default.cc
gcc/rust/expand/rust-derive-eq.cc
gcc/rust/expand/rust-derive-hash.cc
gcc/rust/expand/rust-derive-ord.cc
gcc/rust/expand/rust-derive-partial-eq.cc
gcc/rust/expand/rust-derive.cc
gcc/rust/expand/rust-derive.h

index 3833706d7655d4ff65a1b7182f0d9d68439c495d..cb62f76f092f238d9b95e1ac3ebe880e972355b2 100644 (file)
@@ -510,7 +510,7 @@ Builder::loop (std::vector<std::unique_ptr<Stmt>> &&stmts)
 std::unique_ptr<TypeParamBound>
 Builder::trait_bound (TypePath bound)
 {
-  return std::make_unique<TraitBound> (bound, loc);
+  return std::make_unique<TraitBound> (std::move (bound), loc);
 }
 
 std::unique_ptr<Item>
@@ -520,7 +520,7 @@ Builder::trait_impl (TypePath trait_path, std::unique_ptr<Type> target,
                     WhereClause where_clause, Visibility visibility) const
 {
   return std::unique_ptr<Item> (
-    new TraitImpl (trait_path, /* unsafe */ false,
+    new TraitImpl (std::move (trait_path), /* unsafe */ false,
                   /* exclam */ false, std::move (trait_items),
                   std::move (generics), std::move (target), where_clause,
                   visibility, {}, {}, loc));
@@ -567,7 +567,7 @@ std::unique_ptr<GenericParam>
 Builder::new_const_param (ConstGenericParam &param) const
 {
   return std::make_unique<ConstGenericParam> (param.get_name (),
-                                             param.get_type ().clone_type (),
+                                             param.get_type ().reconstruct (),
                                              param.get_default_value (),
                                              param.get_outer_attrs (),
                                              param.get_locus ());
index b6c6263e0b0575ade2ad164345d5ca389d4b4c93..2e13bea08514b680f0cfdd3d595529451eb8edf1 100644 (file)
@@ -1216,10 +1216,10 @@ public:
 
   // Copy constructor with vector clone
   TypePath (TypePath const &other)
-    : has_opening_scope_resolution (other.has_opening_scope_resolution),
+    : TypeNoBounds (other),
+      has_opening_scope_resolution (other.has_opening_scope_resolution),
       locus (other.locus)
   {
-    node_id = other.node_id;
     segments.reserve (other.segments.size ());
     for (const auto &e : other.segments)
       segments.push_back (e->clone_type_path_segment ());
@@ -1228,7 +1228,7 @@ public:
   // Overloaded assignment operator with clone
   TypePath &operator= (TypePath const &other)
   {
-    node_id = other.node_id;
+    TypeNoBounds::operator= (other);
     has_opening_scope_resolution = other.has_opening_scope_resolution;
     locus = other.locus;
 
index f2d32a589234809e90ac464d088e20a784c60126..fa0c7ab028253e153138a41b70d96242d2cd9f7f 100644 (file)
@@ -89,17 +89,17 @@ DeriveClone::clone_impl (
   std::unique_ptr<AssociatedItem> &&clone_fn, std::string name,
   const std::vector<std::unique_ptr<GenericParam>> &type_generics)
 {
-  // we should have two of these, so we don't run into issues with
-  // two paths sharing a node id
-  auto clone_bound = builder.type_path (LangItem::Kind::CLONE);
-  auto clone_trait_path = builder.type_path (LangItem::Kind::CLONE);
+  auto clone_trait_path
+    = [this] () { return builder.type_path (LangItem::Kind::CLONE); };
 
   auto trait_items = vec (std::move (clone_fn));
 
-  auto generics = setup_impl_generics (name, type_generics,
-                                      builder.trait_bound (clone_bound));
+  auto generics = setup_impl_generics (name, type_generics, [&, this] () {
+    return builder.trait_bound (clone_trait_path ());
+  });
 
-  return builder.trait_impl (clone_trait_path, std::move (generics.self_type),
+  return builder.trait_impl (clone_trait_path (),
+                            std::move (generics.self_type),
                             std::move (trait_items),
                             std::move (generics.impl));
 }
index 62666e029d5b5e6926c4414fb2ab6b79e8cd341a..305100768c90946de012c3d4ab84b8221c1471a9 100644 (file)
@@ -42,15 +42,14 @@ DeriveCopy::copy_impl (
   std::string name,
   const std::vector<std::unique_ptr<GenericParam>> &type_generics)
 {
-  // we should have two of these, so we don't run into issues with
-  // two paths sharing a node id
-  auto copy_bound = builder.type_path (LangItem::Kind::COPY);
-  auto copy_trait_path = builder.type_path (LangItem::Kind::COPY);
+  auto copy_trait_path
+    = [this] () { return builder.type_path (LangItem::Kind::COPY); };
 
-  auto generics = setup_impl_generics (name, type_generics,
-                                      builder.trait_bound (copy_bound));
+  auto generics = setup_impl_generics (name, type_generics, [&, this] () {
+    return builder.trait_bound (copy_trait_path ());
+  });
 
-  return builder.trait_impl (copy_trait_path, std::move (generics.self_type),
+  return builder.trait_impl (copy_trait_path (), std::move (generics.self_type),
                             {}, std::move (generics.impl));
 }
 
index 73e273c5311fdaf13a0c0906d8f6a3f57cff32c9..0edd4040a839c53bcbd2f1ff12e7e86c1cb2bd58 100644 (file)
@@ -81,11 +81,14 @@ DeriveDebug::stub_derive_impl (
 {
   auto trait_items = vec (stub_debug_fn ());
 
-  auto debug = builder.type_path ({"core", "fmt", "Debug"}, true);
-  auto generics
-    = setup_impl_generics (name, type_generics, builder.trait_bound (debug));
-
-  return builder.trait_impl (debug, std::move (generics.self_type),
+  auto debug = [this] () {
+    return builder.type_path ({"core", "fmt", "Debug"}, true);
+  };
+  auto generics = setup_impl_generics (name, type_generics, [&, this] () {
+    return builder.trait_bound (debug ());
+  });
+
+  return builder.trait_impl (debug (), std::move (generics.self_type),
                             std::move (trait_items),
                             std::move (generics.impl));
 }
index 081aabe83c39c8387fbdeab6c0fd5ed9c9d69672..f99d8979aefd3565916edc250de086888059a61c 100644 (file)
@@ -69,14 +69,17 @@ DeriveDefault::default_impl (
   std::unique_ptr<AssociatedItem> &&default_fn, std::string name,
   const std::vector<std::unique_ptr<GenericParam>> &type_generics)
 {
-  auto default_path = builder.type_path ({"core", "default", "Default"}, true);
+  auto default_path = [this] () {
+    return builder.type_path ({"core", "default", "Default"}, true);
+  };
 
   auto trait_items = vec (std::move (default_fn));
 
-  auto generics = setup_impl_generics (name, type_generics,
-                                      builder.trait_bound (default_path));
+  auto generics = setup_impl_generics (name, type_generics, [&, this] () {
+    return builder.trait_bound (default_path ());
+  });
 
-  return builder.trait_impl (default_path, std::move (generics.self_type),
+  return builder.trait_impl (default_path (), std::move (generics.self_type),
                             std::move (trait_items),
                             std::move (generics.impl));
 }
index c0358593b67d4b25634bfa32b29ca80f0d61ab6c..c388c379e4a9ccf02d6d9e5b6d854bbfb89d3fb0 100644 (file)
@@ -118,19 +118,17 @@ DeriveEq::eq_impls (
   std::unique_ptr<AssociatedItem> &&fn, std::string name,
   const std::vector<std::unique_ptr<GenericParam>> &type_generics)
 {
-  // We create two copies of the type-path to avoid duplicate NodeIds
-  auto eq = get_eq_trait_path (builder);
-  auto eq_bound = builder.trait_bound (get_eq_trait_path (builder));
+  auto eq = [this] () { return get_eq_trait_path (builder); };
+  auto eq_bound = [&, this] () { return builder.trait_bound (eq ()); };
 
   auto steq = builder.type_path (LangItem::Kind::STRUCTURAL_TEQ);
 
   auto trait_items = vec (std::move (fn));
 
-  auto eq_generics
-    = setup_impl_generics (name, type_generics, std::move (eq_bound));
+  auto eq_generics = setup_impl_generics (name, type_generics, eq_bound);
   auto steq_generics = setup_impl_generics (name, type_generics);
 
-  auto eq_impl = builder.trait_impl (eq, std::move (eq_generics.self_type),
+  auto eq_impl = builder.trait_impl (eq (), std::move (eq_generics.self_type),
                                     std::move (trait_items),
                                     std::move (eq_generics.impl));
 
index ce606181430d512a9e2fa375a8a413b132c3b133..91c357a1be230bfd7d4f02c18873568229aacb3d 100644 (file)
@@ -77,14 +77,17 @@ DeriveHash::hash_impl (
   std::unique_ptr<AssociatedItem> &&hash_fn, std::string name,
   const std::vector<std::unique_ptr<GenericParam>> &type_generics)
 {
-  auto hash_path = builder.type_path ({"core", "hash", "Hash"}, true);
+  auto hash_path = [this] () {
+    return builder.type_path ({"core", "hash", "Hash"}, true);
+  };
 
   auto trait_items = vec (std::move (hash_fn));
 
-  auto generics = setup_impl_generics (name, type_generics,
-                                      builder.trait_bound (hash_path));
+  auto generics = setup_impl_generics (name, type_generics, [&, this] () {
+    return builder.trait_bound (hash_path ());
+  });
 
-  return builder.trait_impl (hash_path, std::move (generics.self_type),
+  return builder.trait_impl (hash_path (), std::move (generics.self_type),
                             std::move (trait_items),
                             std::move (generics.impl));
 }
index edde40905ec83e1f6bf46f477975964b3477114c..0a1da8496c8b6dcbf951f79dd5fbd9f9d879f059 100644 (file)
@@ -58,18 +58,19 @@ DeriveOrd::cmp_impl (
   auto fn = cmp_fn (std::move (fn_block), type_name);
 
   auto trait = ordering == Ordering::Partial ? "PartialOrd" : "Ord";
-  auto trait_path = builder.type_path ({"core", "cmp", trait}, true);
+  auto trait_path = [&, this] () {
+    return builder.type_path ({"core", "cmp", trait}, true);
+  };
 
   auto trait_bound
-    = builder.trait_bound (builder.type_path ({"core", "cmp", trait}, true));
+    = [&, this] () { return builder.trait_bound (trait_path ()); };
 
   auto trait_items = vec (std::move (fn));
 
   auto cmp_generics
-    = setup_impl_generics (type_name.as_string (), type_generics,
-                          std::move (trait_bound));
+    = setup_impl_generics (type_name.as_string (), type_generics, trait_bound);
 
-  return builder.trait_impl (trait_path, std::move (cmp_generics.self_type),
+  return builder.trait_impl (trait_path (), std::move (cmp_generics.self_type),
                             std::move (trait_items),
                             std::move (cmp_generics.impl));
 }
index a6f981d7be21780a83bbe4ee9c7b9fcfed75d45a..03879fad95c799007b554b146b1f9d16f94f01d2 100644 (file)
@@ -42,17 +42,18 @@ DerivePartialEq::partialeq_impls (
   std::unique_ptr<AssociatedItem> &&eq_fn, std::string name,
   const std::vector<std::unique_ptr<GenericParam>> &type_generics)
 {
-  auto eq = builder.type_path (LangItem::Kind::EQ);
+  auto eq = [this] () { return builder.type_path (LangItem::Kind::EQ); };
   auto speq = builder.type_path (LangItem::Kind::STRUCTURAL_PEQ);
 
   auto trait_items = vec (std::move (eq_fn));
 
   // no extra bound on StructuralPeq
-  auto peq_generics
-    = setup_impl_generics (name, type_generics, builder.trait_bound (eq));
+  auto peq_generics = setup_impl_generics (name, type_generics, [&, this] () {
+    return builder.trait_bound (eq ());
+  });
   auto speq_generics = setup_impl_generics (name, type_generics);
 
-  auto peq = builder.trait_impl (eq, std::move (peq_generics.self_type),
+  auto peq = builder.trait_impl (eq (), std::move (peq_generics.self_type),
                                 std::move (trait_items),
                                 std::move (peq_generics.impl));
 
index f7b87cfbd7c654f16be88f8deb4e5d97c2587054..79f952e2d696bc2424b1db24374a576aabb76717 100644 (file)
@@ -83,7 +83,8 @@ DeriveVisitor::ImplGenerics
 DeriveVisitor::setup_impl_generics (
   const std::string &type_name,
   const std::vector<std::unique_ptr<GenericParam>> &type_generics,
-  tl::optional<std::unique_ptr<TypeParamBound>> &&extra_bound) const
+  tl::optional<std::function<std::unique_ptr<TypeParamBound> ()>> &&extra_bound)
+  const
 {
   std::vector<Lifetime> lifetime_args;
   std::vector<GenericArg> generic_args;
@@ -119,8 +120,7 @@ DeriveVisitor::setup_impl_generics (
            std::vector<std::unique_ptr<TypeParamBound>> extra_bounds;
 
            if (extra_bound)
-             extra_bounds.emplace_back (
-               extra_bound.value ()->clone_type_param_bound ());
+             extra_bounds.emplace_back (extra_bound.value () ());
 
            auto impl_type_param
              = builder.new_type_param (type_param, std::move (extra_bounds));
index 50405f12d4b7c422966e10262515503ffe876740..7a7019544f9e43698c5e5cff5db1bc32a38798b3 100644 (file)
@@ -67,7 +67,8 @@ protected:
   ImplGenerics setup_impl_generics (
     const std::string &type_name,
     const std::vector<std::unique_ptr<GenericParam>> &type_generics,
-    tl::optional<std::unique_ptr<TypeParamBound>> &&extra_bound
+    tl::optional<std::function<std::unique_ptr<TypeParamBound> ()>>
+      &&extra_bound
     = tl::nullopt) const;
 
 private: