aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/expand/rust-derive-clone.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/expand/rust-derive-clone.cc')
-rw-r--r--gcc/rust/expand/rust-derive-clone.cc164
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";