[COMMITTED 03/43] gccrs: derive: Do not add default type parameters on derived impls

arthur.cohen@opensrcsec.com arthur.cohen@opensrcsec.com
Thu Sep 10 08:19:16 GMT 2026


From: Arthur Cohen <arthur.cohen@embecosm.com>

When creating the list of generic types for the derived impl, default parameters should be
skipped as they can only be present on type definitions, not impls.

gcc/rust/ChangeLog:

	* ast/rust-ast-builder.h: Add new parameter to Builder::new_type_param to avoid
	recreating default type parameters when building the new type parameter.
	* ast/rust-ast-builder.cc: Implement the change.
	* expand/rust-derive.cc: Use it in setup_impl_generics.

gcc/testsuite/ChangeLog:

	* rust/compile/derive-with-default-types.rs: New test.
---
 gcc/rust/ast/rust-ast-builder.cc                    |  5 +++--
 gcc/rust/ast/rust-ast-builder.h                     |  9 ++++++++-
 gcc/rust/expand/rust-derive.cc                      |  3 ++-
 .../rust/compile/derive-with-default-types.rs       | 13 +++++++++++++
 4 files changed, 26 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/derive-with-default-types.rs

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index af96899b77e..6332ce2f5c9 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -582,7 +582,8 @@ Builder::new_const_param (ConstGenericParam &param) const
 
 std::unique_ptr<GenericParam>
 Builder::new_type_param (
-  TypeParam &param, std::vector<std::unique_ptr<TypeParamBound>> extra_bounds)
+  TypeParam &param, std::vector<std::unique_ptr<TypeParamBound>> extra_bounds,
+  DefaultParamGen default_param_generation)
 {
   location_t locus = param.get_locus ();
   AST::AttrVec outer_attrs = param.get_outer_attrs ();
@@ -590,7 +591,7 @@ Builder::new_type_param (
   std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
   std::unique_ptr<Type> type = nullptr;
 
-  if (param.has_type ())
+  if (default_param_generation == DefaultParamGen::Keep && param.has_type ())
     type = param.get_type ().reconstruct ();
 
   for (auto &&extra_bound : extra_bounds)
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 16a41c940fb..bc790e98ae6 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -339,9 +339,16 @@ public:
   std::unique_ptr<GenericParam>
   new_const_param (ConstGenericParam &param) const;
 
+  enum class DefaultParamGen
+  {
+    Remove,
+    Keep,
+  };
+
   static std::unique_ptr<GenericParam> new_type_param (
     TypeParam &param,
-    std::vector<std::unique_ptr<TypeParamBound>> extra_trait_bounds = {});
+    std::vector<std::unique_ptr<TypeParamBound>> extra_trait_bounds = {},
+    DefaultParamGen default_param_generation = DefaultParamGen::Keep);
 
   static Lifetime new_lifetime (const Lifetime &lifetime);
 
diff --git a/gcc/rust/expand/rust-derive.cc b/gcc/rust/expand/rust-derive.cc
index 0b73d241173..f45acaa8c24 100644
--- a/gcc/rust/expand/rust-derive.cc
+++ b/gcc/rust/expand/rust-derive.cc
@@ -132,7 +132,8 @@ DeriveVisitor::setup_impl_generics (
 	      extra_bounds.emplace_back (extra_bound.value () ());
 
 	    auto impl_type_param
-	      = builder.new_type_param (type_param, std::move (extra_bounds));
+	      = builder.new_type_param (type_param, std::move (extra_bounds),
+					Builder::DefaultParamGen::Remove);
 
 	    impl_generics.push_back (std::move (impl_type_param));
 	  }
diff --git a/gcc/testsuite/rust/compile/derive-with-default-types.rs b/gcc/testsuite/rust/compile/derive-with-default-types.rs
new file mode 100644
index 00000000000..824e2338853
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive-with-default-types.rs
@@ -0,0 +1,13 @@
+#![feature(no_core)]
+#![feature(lang_items)]
+#![feature(rustc_attrs)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[derive(Copy)]
+pub struct SadWrap<T = ()>(T);
-- 
2.50.1



More information about the Gcc-rust mailing list