rust/rust-cfg-strip.o \
rust/rust-expand-visitor.o \
rust/rust-ast-builder.o \
+ rust/rust-ast-builder-type.o \
rust/rust-derive.o \
rust/rust-derive-clone.o \
rust/rust-derive-copy.o \
--- /dev/null
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-ast-builder-type.h"
+#include "rust-ast-builder.h"
+#include "rust-ast-full.h"
+#include "rust-common.h"
+#include "rust-make-unique.h"
+
+namespace Rust {
+namespace AST {
+
+ASTTypeBuilder::ASTTypeBuilder () : translated (nullptr) {}
+
+Type *
+ASTTypeBuilder::build (Type &type)
+{
+ ASTTypeBuilder builder;
+ type.accept_vis (builder);
+ rust_assert (builder.translated != nullptr);
+ return builder.translated;
+}
+
+void
+ASTTypeBuilder::visit (BareFunctionType &fntype)
+{
+ /* TODO */
+}
+
+void
+ASTTypeBuilder::visit (TupleType &tuple)
+{
+ std::vector<std::unique_ptr<Type> > elems;
+ for (auto &elem : tuple.get_elems ())
+ {
+ Type *t = ASTTypeBuilder::build (*elem.get ());
+ std::unique_ptr<Type> ty (t);
+ elems.push_back (std::move (ty));
+ }
+ translated = new TupleType (std::move (elems), tuple.get_locus ());
+}
+
+void
+ASTTypeBuilder::visit (TypePath &path)
+{
+ std::vector<std::unique_ptr<TypePathSegment> > segments;
+ for (auto &seg : path.get_segments ())
+ {
+ switch (seg->get_type ())
+ {
+ case TypePathSegment::REG: {
+ const TypePathSegment &segment
+ = (const TypePathSegment &) (*seg.get ());
+ TypePathSegment *s
+ = new TypePathSegment (segment.get_ident_segment (),
+ segment.get_separating_scope_resolution (),
+ segment.get_locus ());
+ std::unique_ptr<TypePathSegment> sg (s);
+ segments.push_back (std::move (sg));
+ }
+ break;
+
+ case TypePathSegment::GENERIC: {
+ TypePathSegmentGeneric &generic
+ = (TypePathSegmentGeneric &) (*seg.get ());
+
+ GenericArgs args
+ = Builder::new_generic_args (generic.get_generic_args ());
+ TypePathSegmentGeneric *s
+ = new TypePathSegmentGeneric (generic.get_ident_segment (), false,
+ std::move (args),
+ generic.get_locus ());
+ std::unique_ptr<TypePathSegment> sg (s);
+ segments.push_back (std::move (sg));
+ }
+ break;
+
+ case TypePathSegment::FUNCTION: {
+ rust_unreachable ();
+ // TODO
+ // const TypePathSegmentFunction &fn
+ // = (const TypePathSegmentFunction &) (*seg.get ());
+ }
+ break;
+ }
+ }
+
+ translated = new TypePath (std::move (segments), path.get_locus (),
+ path.has_opening_scope_resolution_op ());
+}
+
+void
+ASTTypeBuilder::visit (QualifiedPathInType &path)
+{
+ /* TODO */
+}
+
+void
+ASTTypeBuilder::visit (ArrayType &type)
+{
+ /* TODO */
+}
+
+void
+ASTTypeBuilder::visit (ReferenceType &type)
+{
+ /* TODO */
+}
+
+void
+ASTTypeBuilder::visit (RawPointerType &type)
+{
+ /* TODO */
+}
+
+void
+ASTTypeBuilder::visit (SliceType &type)
+{
+ Type *t = ASTTypeBuilder::build (type.get_elem_type ());
+ std::unique_ptr<Type> ty (t);
+ translated = new SliceType (std::move (ty), type.get_locus ());
+}
+
+void
+ASTTypeBuilder::visit (InferredType &type)
+{
+ translated = new InferredType (type.get_locus ());
+}
+
+void
+ASTTypeBuilder::visit (NeverType &type)
+{
+ translated = new NeverType (type.get_locus ());
+}
+
+void
+ASTTypeBuilder::visit (TraitObjectTypeOneBound &type)
+{
+ /* TODO */
+}
+
+void
+ASTTypeBuilder::visit (TraitObjectType &type)
+{
+ /* TODO */
+}
+
+} // namespace AST
+} // namespace Rust
--- /dev/null
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_AST_BUILDER_TYPE
+#define RUST_AST_BUILDER_TYPE
+
+#include "rust-ast-visitor.h"
+
+namespace Rust {
+namespace AST {
+
+class ASTTypeBuilder : public DefaultASTVisitor
+{
+protected:
+ using DefaultASTVisitor::visit;
+
+public:
+ static Type *build (Type &type);
+
+ void visit (BareFunctionType &fntype) override;
+ void visit (TupleType &tuple) override;
+ void visit (TypePath &path) override;
+ void visit (QualifiedPathInType &path) override;
+ void visit (ArrayType &type) override;
+ void visit (ReferenceType &type) override;
+ void visit (RawPointerType &type) override;
+ void visit (SliceType &type) override;
+ void visit (InferredType &type) override;
+ void visit (NeverType &type) override;
+ void visit (TraitObjectTypeOneBound &type) override;
+ void visit (TraitObjectType &type) override;
+
+private:
+ ASTTypeBuilder ();
+
+ Type *translated;
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // RUST_AST_BUILDER_TYPE
// <http://www.gnu.org/licenses/>.
#include "rust-ast-builder.h"
-#include "rust-ast-full-decls.h"
-#include "rust-ast-full.h"
+#include "rust-ast-builder-type.h"
#include "rust-common.h"
#include "rust-expr.h"
#include "rust-token.h"
new TypePathSegment (seg, false, loc));
}
+std::unique_ptr<TypePathSegment>
+Builder::generic_type_path_segment (std::string seg, GenericArgs args) const
+{
+ return std::unique_ptr<TypePathSegment> (
+ new TypePathSegmentGeneric (PathIdentSegment (seg, loc), false, args, loc));
+}
+
std::unique_ptr<Type>
Builder::single_type_path (std::string type) const
{
return std::unique_ptr<Type> (new TypePath (std::move (segments), loc));
}
+std::unique_ptr<Type>
+Builder::single_generic_type_path (std::string type, GenericArgs args) const
+{
+ auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
+ segments.emplace_back (generic_type_path_segment (type, args));
+
+ return std::unique_ptr<Type> (new TypePath (std::move (segments), loc));
+}
+
PathInExpression
Builder::path_in_expression (std::vector<std::string> &&segments) const
{
return std::unique_ptr<Pattern> (new WildcardPattern (loc));
}
+std::unique_ptr<Type>
+Builder::new_type (Type &type)
+{
+ Type *t = ASTTypeBuilder::build (type);
+ return std::unique_ptr<Type> (t);
+}
+
+std::unique_ptr<GenericParam>
+Builder::new_lifetime_param (LifetimeParam ¶m)
+{
+ Lifetime l = new_lifetime (param.get_lifetime ());
+ std::vector<Lifetime> lifetime_bounds;
+ for (auto b : param.get_lifetime_bounds ())
+ {
+ Lifetime bl = new_lifetime (b);
+ lifetime_bounds.push_back (bl);
+ }
+
+ auto p = new LifetimeParam (l, std::move (lifetime_bounds),
+ param.get_outer_attrs (), param.get_locus ());
+ return std::unique_ptr<GenericParam> (p);
+}
+
+std::unique_ptr<GenericParam>
+Builder::new_type_param (TypeParam ¶m)
+{
+ location_t locus = param.get_locus ();
+ AST::AttrVec outer_attrs = param.get_outer_attrs ();
+ Identifier type_representation = param.get_type_representation ();
+ std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
+ std::unique_ptr<Type> type = nullptr;
+
+ if (param.has_type ())
+ type = new_type (param.get_type ());
+
+ for (const auto &b : param.get_type_param_bounds ())
+ {
+ switch (b->get_bound_type ())
+ {
+ case TypeParamBound::TypeParamBoundType::TRAIT: {
+ const TraitBound &tb = (const TraitBound &) *b.get ();
+ const TypePath &path = tb.get_type_path ();
+
+ std::vector<LifetimeParam> for_lifetimes;
+ for (const auto &lifetime : tb.get_for_lifetimes ())
+ {
+ std::vector<Lifetime> lifetime_bounds;
+ for (const auto &b : lifetime.get_lifetime_bounds ())
+ {
+ Lifetime bl = new_lifetime (b);
+ lifetime_bounds.push_back (std::move (bl));
+ }
+
+ Lifetime nl = new_lifetime (lifetime.get_lifetime ());
+ LifetimeParam p (std::move (nl), std::move (lifetime_bounds),
+ {}, lifetime.get_locus ());
+ for_lifetimes.push_back (std::move (p));
+ }
+
+ std::vector<std::unique_ptr<TypePathSegment>> segments;
+ for (auto &seg : path.get_segments ())
+ {
+ switch (seg->get_type ())
+ {
+ case TypePathSegment::REG: {
+ const TypePathSegment &segment
+ = (const TypePathSegment &) (*seg.get ());
+ TypePathSegment *s = new TypePathSegment (
+ segment.get_ident_segment (),
+ segment.get_separating_scope_resolution (),
+ segment.get_locus ());
+ std::unique_ptr<TypePathSegment> sg (s);
+ segments.push_back (std::move (sg));
+ }
+ break;
+
+ case TypePathSegment::GENERIC: {
+ TypePathSegmentGeneric &generic
+ = (TypePathSegmentGeneric &) (*seg.get ());
+
+ GenericArgs args
+ = new_generic_args (generic.get_generic_args ());
+ TypePathSegmentGeneric *s = new TypePathSegmentGeneric (
+ generic.get_ident_segment (), false, std::move (args),
+ generic.get_locus ());
+ std::unique_ptr<TypePathSegment> sg (s);
+ segments.push_back (std::move (sg));
+ }
+ break;
+
+ case TypePathSegment::FUNCTION: {
+ rust_unreachable ();
+ // TODO
+ // const TypePathSegmentFunction &fn
+ // = (const TypePathSegmentFunction &) (*seg.get ());
+ }
+ break;
+ }
+ }
+
+ TypePath p (std::move (segments), path.get_locus (),
+ path.has_opening_scope_resolution_op ());
+
+ TraitBound *b = new TraitBound (std::move (p), tb.get_locus (),
+ tb.is_in_parens (),
+ tb.has_opening_question_mark (),
+ std::move (for_lifetimes));
+ std::unique_ptr<TypeParamBound> bound (b);
+ type_param_bounds.push_back (std::move (bound));
+ }
+ break;
+
+ case TypeParamBound::TypeParamBoundType::LIFETIME: {
+ const Lifetime &l = (const Lifetime &) *b.get ();
+
+ auto bl = new Lifetime (l.get_lifetime_type (),
+ l.get_lifetime_name (), l.get_locus ());
+ std::unique_ptr<TypeParamBound> bound (bl);
+ type_param_bounds.push_back (std::move (bound));
+ }
+ break;
+ }
+ }
+
+ auto type_param
+ = new TypeParam (type_representation, locus, std::move (type_param_bounds),
+ std::move (type), std::move (outer_attrs));
+
+ return std::unique_ptr<GenericParam> (type_param);
+}
+
+Lifetime
+Builder::new_lifetime (const Lifetime &lifetime)
+{
+ return Lifetime (lifetime.get_lifetime_type (), lifetime.get_lifetime_name (),
+ lifetime.get_locus ());
+}
+
+GenericArgs
+Builder::new_generic_args (GenericArgs &args)
+{
+ std::vector<Lifetime> lifetime_args;
+ std::vector<GenericArg> generic_args;
+ std::vector<GenericArgsBinding> binding_args;
+ location_t locus = args.get_locus ();
+
+ for (const auto &lifetime : args.get_lifetime_args ())
+ {
+ Lifetime l = new_lifetime (lifetime);
+ lifetime_args.push_back (std::move (l));
+ }
+
+ for (auto &binding : args.get_binding_args ())
+ {
+ Type &t = *binding.get_type_ptr ().get ();
+ std::unique_ptr<Type> ty = new_type (t);
+ GenericArgsBinding b (binding.get_identifier (), std::move (ty),
+ binding.get_locus ());
+ binding_args.push_back (std::move (b));
+ }
+
+ for (auto &arg : args.get_generic_args ())
+ {
+ switch (arg.get_kind ())
+ {
+ case GenericArg::Kind::Type: {
+ std::unique_ptr<Type> ty = new_type (arg.get_type ());
+ GenericArg arg = GenericArg::create_type (std::move (ty));
+ }
+ break;
+
+ default:
+ // FIXME
+ rust_unreachable ();
+ break;
+ }
+ }
+
+ return GenericArgs (std::move (lifetime_args), std::move (generic_args),
+ std::move (binding_args), locus);
+}
+
} // namespace AST
} // namespace Rust
/* And similarly for type path segments */
std::unique_ptr<TypePathSegment> type_path_segment (std::string seg) const;
+ std::unique_ptr<TypePathSegment>
+ generic_type_path_segment (std::string seg, GenericArgs args) const;
+
/* Create a Type from a single string - the most basic kind of type in our AST
*/
std::unique_ptr<Type> single_type_path (std::string type) const;
+ std::unique_ptr<Type> single_generic_type_path (std::string type,
+ GenericArgs args) const;
+
/**
* Create a path in expression from multiple segments (`Clone::clone`). You
* do not need to separate the segments using `::`, you can simply provide a
/* Create a wildcard pattern (`_`) */
std::unique_ptr<Pattern> wildcard () const;
+ static std::unique_ptr<Type> new_type (Type &type);
+
+ static std::unique_ptr<GenericParam>
+ new_lifetime_param (LifetimeParam ¶m);
+
+ static std::unique_ptr<GenericParam> new_type_param (TypeParam ¶m);
+
+ static Lifetime new_lifetime (const Lifetime &lifetime);
+
+ static GenericArgs new_generic_args (GenericArgs &args);
+
private:
/**
* Location of the generated AST nodes
class TypeParamBound : public Visitable
{
public:
+ enum TypeParamBoundType
+ {
+ TRAIT,
+ LIFETIME
+ };
+
virtual ~TypeParamBound () {}
// Unique pointer custom clone function
virtual location_t get_locus () const = 0;
+ virtual TypeParamBoundType get_bound_type () const = 0;
+
protected:
// Clone function implementation as pure virtual method
virtual TypeParamBound *clone_type_param_bound_impl () const = 0;
void accept_vis (ASTVisitor &vis) override;
- LifetimeType get_lifetime_type () { return lifetime_type; }
+ LifetimeType get_lifetime_type () const { return lifetime_type; }
location_t get_locus () const override final { return locus; }
std::string get_lifetime_name () const { return lifetime_name; }
+ TypeParamBoundType get_bound_type () const override
+ {
+ return TypeParamBound::TypeParamBoundType::LIFETIME;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
+ const std::vector<Lifetime> &get_lifetime_bounds () const
+ {
+ return lifetime_bounds;
+ }
+
// Returns whether the lifetime param has an outer attribute.
bool has_outer_attribute () const { return !outer_attrs.empty (); }
std::string as_string () const;
- // TODO: is this better? Or is a "vis_pattern" better?
std::vector<GenericArg> &get_generic_args () { return generic_args; }
- // TODO: is this better? Or is a "vis_pattern" better?
std::vector<GenericArgsBinding> &get_binding_args () { return binding_args; }
+ const std::vector<GenericArgsBinding> &get_binding_args () const
+ {
+ return binding_args;
+ }
+
std::vector<Lifetime> &get_lifetime_args () { return lifetime_args; };
- location_t get_locus () { return locus; }
+ const std::vector<Lifetime> &get_lifetime_args () const
+ {
+ return lifetime_args;
+ };
+
+ location_t get_locus () const { return locus; }
};
/* A segment of a path in expression, including an identifier aspect and maybe
std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
+ const std::vector<LifetimeParam> &get_for_lifetimes () const
+ {
+ return for_lifetimes;
+ }
+
TraitBound (TypePath type_path, location_t locus, bool in_parens = false,
bool opening_question_mark = false,
std::vector<LifetimeParam> for_lifetimes
bool is_in_parens () const { return in_parens; }
bool has_opening_question_mark () const { return opening_question_mark; }
+ TypeParamBoundType get_bound_type () const override
+ {
+ return TypeParamBound::TypeParamBoundType::TRAIT;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
*
*/
std::unique_ptr<Item>
-DeriveClone::clone_impl (std::unique_ptr<AssociatedItem> &&clone_fn,
- std::string name)
+DeriveClone::clone_impl (
+ std::unique_ptr<AssociatedItem> &&clone_fn, std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics)
{
// should that be `$crate::core::clone::Clone` instead?
auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
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 ());
+
+ GenericArg type_arg
+ = GenericArg::create_type (std::move (associated_type));
+ generic_args.push_back (std::move (type_arg));
+
+ 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;
+ }
+ }
+
+ 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),
- /* generics */ {}, builder.single_type_path (name),
+ std::move (impl_generics), std::move (self_type_path),
WhereClause::create_empty (), Visibility::create_private (),
{}, {}, loc));
}
auto constructor = builder.call (std::move (path), std::move (cloned_fields));
expanded = clone_impl (clone_fn (std::move (constructor)),
- item.get_identifier ().as_string ());
+ item.get_identifier ().as_string (),
+ item.get_generic_params ());
}
void
auto unit_ctor
= builder.struct_expr_struct (item.get_struct_name ().as_string ());
expanded = clone_impl (clone_fn (std::move (unit_ctor)),
- item.get_struct_name ().as_string ());
+ item.get_struct_name ().as_string (),
+ item.get_generic_params ());
return;
}
auto ctor = builder.struct_expr (item.get_struct_name ().as_string (),
std::move (cloned_fields));
expanded = clone_impl (clone_fn (std::move (ctor)),
- item.get_struct_name ().as_string ());
+ item.get_struct_name ().as_string (),
+ item.get_generic_params ());
}
void
auto block = builder.block (std::move (stmts), std::move (tail_expr));
expanded = clone_impl (clone_fn (std::move (block)),
- item.get_identifier ().as_string ());
+ item.get_identifier ().as_string (),
+ item.get_generic_params ());
}
} // namespace AST
* }
*
*/
- std::unique_ptr<Item> clone_impl (std::unique_ptr<AssociatedItem> &&clone_fn,
- std::string name);
+ std::unique_ptr<Item>
+ clone_impl (std::unique_ptr<AssociatedItem> &&clone_fn, std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics);
virtual void visit_struct (StructStruct &item);
virtual void visit_tuple (TupleStruct &item);
}
std::unique_ptr<Item>
-DeriveCopy::copy_impl (std::string name)
+DeriveCopy::copy_impl (
+ std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics)
{
// `$crate::core::marker::Copy` instead
auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
segments.emplace_back (builder.type_path_segment ("Copy"));
auto copy = TypePath (std::move (segments), loc);
+ // 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(Copy)]
+ // struct Be<T: Copy> { ... }
+ //
+ // we need to generate the impl block:
+ //
+ // impl<T: Copy> 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 ());
+
+ GenericArg type_arg
+ = GenericArg::create_type (std::move (associated_type));
+ generic_args.push_back (std::move (type_arg));
+
+ 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;
+ }
+ }
+
+ 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 (copy, /* unsafe */ false,
/* exclam */ false, /* trait items */ {},
- /* generics */ {}, builder.single_type_path (name),
+ std::move (impl_generics), std::move (self_type_path),
WhereClause::create_empty (), Visibility::create_private (),
{}, {}, loc));
}
void
DeriveCopy::visit_struct (StructStruct &item)
{
- expanded = copy_impl (item.get_struct_name ().as_string ());
+ expanded = copy_impl (item.get_struct_name ().as_string (),
+ item.get_generic_params ());
}
void
DeriveCopy::visit_tuple (TupleStruct &item)
{
- expanded = copy_impl (item.get_struct_name ().as_string ());
+ expanded = copy_impl (item.get_struct_name ().as_string (),
+ item.get_generic_params ());
}
void
DeriveCopy::visit_enum (Enum &item)
{
- expanded = copy_impl (item.get_identifier ().as_string ());
+ expanded = copy_impl (item.get_identifier ().as_string (),
+ item.get_generic_params ());
}
void
DeriveCopy::visit_union (Union &item)
{
- expanded = copy_impl (item.get_identifier ().as_string ());
+ expanded = copy_impl (item.get_identifier ().as_string (),
+ item.get_generic_params ());
}
} // namespace AST
*
* impl Copy for <type> {}
*/
- std::unique_ptr<Item> copy_impl (std::string name);
+ std::unique_ptr<Item>
+ copy_impl (std::string name,
+ const std::vector<std::unique_ptr<GenericParam>> &type_generics);
virtual void visit_struct (StructStruct &item);
virtual void visit_tuple (TupleStruct &item);
--- /dev/null
+#![feature(lang_items)]
+
+#[lang = "clone"]
+trait Clone {
+ fn clone(&self) -> Self;
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+struct Abound {
+ a: u32,
+ // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+ b: u32,
+ // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+#[derive(Clone)]
+struct Be<T:Clone> {
+ a: T,
+ b: Abound,
+}
+
+impl Clone for u32 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl Clone for usize {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl Clone for Abound {
+ fn clone(&self) -> Self {
+ return Abound { a: self.a.clone(), b: self.b.clone() };
+ }
+}
+
+fn main() {
+ let b: Be<usize> = Be {a:1,b:Abound { a:0,b:1 }};
+ let _: Be<usize> = b.clone();
+}
--- /dev/null
+#![feature(lang_items)]
+
+#[lang = "clone"]
+trait Clone {
+ fn clone(&self) -> Self;
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+struct Abound {
+ a: u32,
+ b: u32,
+}
+
+struct Be<T: Clone> {
+ a: T,
+ b: Abound,
+}
+
+impl<T: Clone> Clone for Be<T> {
+ fn clone(&self) -> Self {
+ return Be::<T> {
+ a: self.a.clone(),
+ b: self.b.clone(),
+ };
+ }
+}
+
+impl Clone for u32 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl Clone for usize {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl Clone for Abound {
+ fn clone(&self) -> Self {
+ return Abound {
+ a: self.a.clone(),
+ b: self.b.clone(),
+ };
+ }
+}
+
+fn main() {
+ let b: Be<usize> = Be {
+ a: 1,
+ b: Abound { a: 0, b: 1 },
+ };
+ let _: Be<usize> = b.clone();
+}
--- /dev/null
+#![feature(lang_items)]
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[derive(Copy)]
+struct Abound {
+ a: u32,
+ // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+ b: u32,
+ // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+#[derive(Copy)]
+struct Be<T: Copy> {
+ a: T,
+ // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+ b: Abound,
+ // { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+
+impl Copy for usize {}
+
+fn main() {
+ let _: Be<usize> = Be {
+ a: 1,
+ b: Abound { a: 0, b: 1 },
+ };
+}
issue-3030.rs
issue-3035.rs
issue-3082.rs
+issue-3139-1.rs
+issue-3139-2.rs
+issue-3139-3.rs