diff options
Diffstat (limited to 'gcc/rust/expand/rust-derive-clone.cc')
-rw-r--r-- | gcc/rust/expand/rust-derive-clone.cc | 164 |
1 files changed, 48 insertions, 116 deletions
diff --git a/gcc/rust/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc index 7620abe..074ea01 100644 --- a/gcc/rust/expand/rust-derive-clone.cc +++ b/gcc/rust/expand/rust-derive-clone.cc @@ -18,7 +18,6 @@ #include "rust-derive-clone.h" #include "rust-ast.h" -#include "rust-ast-dump.h" #include "rust-expr.h" #include "rust-item.h" #include "rust-path.h" @@ -92,86 +91,19 @@ DeriveClone::clone_impl ( std::unique_ptr<AssociatedItem> &&clone_fn, std::string name, const std::vector<std::unique_ptr<GenericParam>> &type_generics) { - auto clone = builder.type_path (LangItem::Kind::CLONE); - - auto trait_items = std::vector<std::unique_ptr<AssociatedItem>> (); - trait_items.emplace_back (std::move (clone_fn)); - - // we need to build up the generics for this impl block which will be just a - // clone of the types specified ones - // - // for example: - // - // #[derive(Clone)] - // struct Be<T: Clone> { ... } - // - // we need to generate the impl block: - // - // impl<T: Clone> Clone for Be<T> - - std::vector<Lifetime> lifetime_args; - std::vector<GenericArg> generic_args; - std::vector<std::unique_ptr<GenericParam>> impl_generics; - for (const auto &generic : type_generics) - { - switch (generic->get_kind ()) - { - case GenericParam::Kind::Lifetime: { - LifetimeParam &lifetime_param = (LifetimeParam &) *generic.get (); - - Lifetime l = builder.new_lifetime (lifetime_param.get_lifetime ()); - lifetime_args.push_back (std::move (l)); - - auto impl_lifetime_param - = builder.new_lifetime_param (lifetime_param); - impl_generics.push_back (std::move (impl_lifetime_param)); - } - break; - - case GenericParam::Kind::Type: { - TypeParam &type_param = (TypeParam &) *generic.get (); - - std::unique_ptr<Type> associated_type = builder.single_type_path ( - type_param.get_type_representation ().as_string ()); + // 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); - GenericArg type_arg - = GenericArg::create_type (std::move (associated_type)); - generic_args.push_back (std::move (type_arg)); + auto trait_items = vec (std::move (clone_fn)); - auto impl_type_param = builder.new_type_param (type_param); - impl_generics.push_back (std::move (impl_type_param)); - } - break; - - case GenericParam::Kind::Const: { - rust_unreachable (); - - // TODO - // const ConstGenericParam *const_param - // = (const ConstGenericParam *) generic.get (); - // std::unique_ptr<Expr> const_expr = nullptr; - - // GenericArg type_arg - // = GenericArg::create_const (std::move (const_expr)); - // generic_args.push_back (std::move (type_arg)); - } - break; - } - } + auto generics = setup_impl_generics (name, type_generics, + builder.trait_bound (clone_bound)); - GenericArgs generic_args_for_self (lifetime_args, generic_args, - {} /*binding args*/, loc); - std::unique_ptr<Type> self_type_path - = impl_generics.empty () - ? builder.single_type_path (name) - : builder.single_generic_type_path (name, generic_args_for_self); - - return std::unique_ptr<Item> ( - new TraitImpl (clone, /* unsafe */ false, - /* exclam */ false, std::move (trait_items), - std::move (impl_generics), std::move (self_type_path), - WhereClause::create_empty (), Visibility::create_private (), - {}, {}, loc)); + return builder.trait_impl (clone_trait_path, std::move (generics.self_type), + std::move (trait_items), + std::move (generics.impl)); } // TODO: Create new `make_qualified_call` helper function @@ -239,34 +171,27 @@ DeriveClone::visit_struct (StructStruct &item) item.get_generic_params ()); } -PathInExpression -DeriveClone::variant_match_path (Enum &item, const Identifier &variant) -{ - return PathInExpression ({builder.path_segment ( - item.get_identifier ().as_string ()), - builder.path_segment (variant.as_string ())}, - {}, loc, false); -} - MatchCase -DeriveClone::clone_enum_identifier (Enum &item, +DeriveClone::clone_enum_identifier (PathInExpression variant_path, const std::unique_ptr<EnumItem> &variant) { - auto variant_path = variant_match_path (item, variant->get_identifier ()); - auto pattern = std::unique_ptr<Pattern> (new ReferencePattern ( - std::unique_ptr<Pattern> (new PathInExpression (variant_path)), false, - false, loc)); - auto expr = std::unique_ptr<Expr> (new PathInExpression (variant_path)); + std::unique_ptr<Pattern> (new PathInExpression ( + variant_path.get_segments (), {}, variant_path.get_locus (), + variant_path.opening_scope_resolution ())), + false, false, loc)); + auto expr = std::unique_ptr<Expr> ( + new PathInExpression (variant_path.get_segments (), {}, + variant_path.get_locus (), + variant_path.opening_scope_resolution ())); return builder.match_case (std::move (pattern), std::move (expr)); } MatchCase -DeriveClone::clone_enum_tuple (Enum &item, const EnumItemTuple &variant) +DeriveClone::clone_enum_tuple (PathInExpression variant_path, + const EnumItemTuple &variant) { - auto variant_path = variant_match_path (item, variant.get_identifier ()); - auto patterns = std::vector<std::unique_ptr<Pattern>> (); auto cloned_patterns = std::vector<std::unique_ptr<Expr>> (); @@ -289,23 +214,27 @@ DeriveClone::clone_enum_tuple (Enum &item, const EnumItemTuple &variant) auto pattern_items = std::unique_ptr<TupleStructItems> ( new TupleStructItemsNoRange (std::move (patterns))); - auto pattern = std::unique_ptr<Pattern> ( - new ReferencePattern (std::unique_ptr<Pattern> (new TupleStructPattern ( - variant_path, std::move (pattern_items))), - false, false, loc)); - - auto expr - = builder.call (std::unique_ptr<Expr> (new PathInExpression (variant_path)), - std::move (cloned_patterns)); + auto pattern = std::unique_ptr<Pattern> (new ReferencePattern ( + std::unique_ptr<Pattern> (new TupleStructPattern ( + PathInExpression (variant_path.get_segments (), {}, + variant_path.get_locus (), + variant_path.opening_scope_resolution ()), + std::move (pattern_items))), + false, false, loc)); + + auto expr = builder.call (std::unique_ptr<Expr> (new PathInExpression ( + variant_path.get_segments (), {}, + variant_path.get_locus (), + variant_path.opening_scope_resolution ())), + std::move (cloned_patterns)); return builder.match_case (std::move (pattern), std::move (expr)); } MatchCase -DeriveClone::clone_enum_struct (Enum &item, const EnumItemStruct &variant) +DeriveClone::clone_enum_struct (PathInExpression variant_path, + const EnumItemStruct &variant) { - auto variant_path = variant_match_path (item, variant.get_identifier ()); - auto field_patterns = std::vector<std::unique_ptr<StructPatternField>> (); auto cloned_fields = std::vector<std::unique_ptr<StructExprField>> (); @@ -384,21 +313,25 @@ DeriveClone::visit_enum (Enum &item) for (const auto &variant : item.get_variants ()) { + auto path + = builder.variant_path (item.get_identifier ().as_string (), + variant->get_identifier ().as_string ()); + switch (variant->get_enum_item_kind ()) { // Identifiers and discriminated variants are the same for a clone - we // just return the same variant case EnumItem::Kind::Identifier: case EnumItem::Kind::Discriminant: - cases.emplace_back (clone_enum_identifier (item, variant)); + cases.emplace_back (clone_enum_identifier (path, variant)); break; case EnumItem::Kind::Tuple: cases.emplace_back ( - clone_enum_tuple (item, static_cast<EnumItemTuple &> (*variant))); + clone_enum_tuple (path, static_cast<EnumItemTuple &> (*variant))); break; case EnumItem::Kind::Struct: cases.emplace_back ( - clone_enum_struct (item, static_cast<EnumItemStruct &> (*variant))); + clone_enum_struct (path, static_cast<EnumItemStruct &> (*variant))); break; } } @@ -417,17 +350,16 @@ 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_path = builder.type_path (LangItem::Kind::COPY); + auto sized_path = builder.type_path (LangItem::Kind::SIZED); 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)); + new TraitBound (sized_path, item.get_locus (), false, + true /* opening_question_mark */)); - auto bounds = std::vector<std::unique_ptr<TypeParamBound>> (); - bounds.emplace_back (std::move (copy_bound)); - bounds.emplace_back (std::move (sized_bound)); + auto bounds = vec (std::move (copy_bound), std::move (sized_bound)); // struct AssertParamIsCopy<T: Copy + ?Sized> { _t: PhantomData<T> } auto assert_param_is_copy = "AssertParamIsCopy"; |