https://gcc.gnu.org/g:41cd035570ec2767d23647a7764c24d6c1a7a82e
commit r15-8629-g41cd035570ec2767d23647a7764c24d6c1a7a82e Author: Arthur Cohen <arthur.co...@embecosm.com> Date: Thu Dec 26 10:50:13 2024 +0000 gccrs: derive(Clone): Manually generate AssertParamIsCopy struct for unions gcc/rust/ChangeLog: * expand/rust-derive-clone.cc (DeriveClone::visit_union): Manually generate the struct used for asserting a union implements Copy. Diff: --- gcc/rust/expand/rust-derive-clone.cc | 38 ++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/gcc/rust/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc index 18436be4bf75..8093bf67ff0a 100644 --- a/gcc/rust/expand/rust-derive-clone.cc +++ b/gcc/rust/expand/rust-derive-clone.cc @@ -17,6 +17,8 @@ // <http://www.gnu.org/licenses/>. #include "rust-derive-clone.h" +#include "rust-ast.h" +#include "rust-ast-dump.h" #include "rust-item.h" namespace Rust { @@ -238,13 +240,40 @@ void DeriveClone::visit_union (Union &item) { // FIXME: Should be $crate::core::clone::AssertParamIsCopy (or similar) + // (Rust-GCC#3329) + + auto copy_path = TypePath (vec (builder.type_path_segment ("Copy")), loc); + auto sized_path = TypePath (vec (builder.type_path_segment ("Sized")), loc); + + auto copy_bound = std::unique_ptr<TypeParamBound> ( + new TraitBound (copy_path, item.get_locus ())); + auto sized_bound = std::unique_ptr<TypeParamBound> ( + new TraitBound (sized_path, item.get_locus (), false, true)); + + auto bounds = std::vector<std::unique_ptr<TypeParamBound>> (); + bounds.emplace_back (std::move (copy_bound)); + bounds.emplace_back (std::move (sized_bound)); + + // struct AssertParamIsCopy<T: Copy + ?Sized> { _t: PhantomData<T> } + auto assert_param_is_copy = "AssertParamIsCopy"; + auto t = std::unique_ptr<GenericParam> ( + new TypeParam (Identifier ("T"), item.get_locus (), std::move (bounds))); + auto assert_param_is_copy_struct = builder.struct_struct ( + assert_param_is_copy, vec (std::move (t)), + {StructField ( + Identifier ("_t"), + builder.single_generic_type_path ( + "PhantomData", + GenericArgs ( + {}, {GenericArg::create_type (builder.single_type_path ("T"))}, {})), + Visibility::create_private (), item.get_locus ())}); // <Self> auto arg = GenericArg::create_type (builder.single_type_path ("Self")); // AssertParamIsCopy::<Self> auto type = std::unique_ptr<TypePathSegment> ( - new TypePathSegmentGeneric (PathIdentSegment ("AssertParamIsCopy", loc), + new TypePathSegmentGeneric (PathIdentSegment (assert_param_is_copy, loc), false, GenericArgs ({}, {arg}, {}, loc), loc)); auto type_paths = std::vector<std::unique_ptr<TypePathSegment>> (); type_paths.emplace_back (std::move (type)); @@ -252,11 +281,12 @@ DeriveClone::visit_union (Union &item) auto full_path = std::unique_ptr<Type> (new TypePath ({std::move (type_paths)}, loc)); - auto stmts = std::vector<std::unique_ptr<Stmt>> (); - stmts.emplace_back ( - builder.let (builder.wildcard (), std::move (full_path), nullptr)); auto tail_expr = builder.deref (builder.identifier ("self")); + auto stmts + = vec (std::move (assert_param_is_copy_struct), + builder.let (builder.wildcard (), std::move (full_path), nullptr)); + auto block = builder.block (std::move (stmts), std::move (tail_expr)); expanded = clone_impl (clone_fn (std::move (block)),