Also removes some redundant copies and improves TypePath copying.
gcc/rust/ChangeLog:
* ast/rust-ast-builder.cc (Builder::trait_bound): Replace copy
with move.
(Builder::trait_impl): Likewise.
(Builder::new_const_param): Replace cloning with reconstruction.
* ast/rust-path.h (TypePath::TypePath): Use TypeNoBounds copy
constructor.
(TypePath::operator=): Use TypeNoBounds copy assignment.
* expand/rust-derive-clone.cc (DeriveClone::clone_impl): Produce
trait bounds lazily.
* expand/rust-derive-copy.cc (DeriveCopy::copy_impl): Likewise.
* expand/rust-derive-debug.cc (DeriveDebug::stub_derive_impl):
Likewise.
* expand/rust-derive-default.cc (DeriveDefault::default_impl):
Likewise.
* expand/rust-derive-eq.cc (DeriveEq::eq_impls): Likewise.
* expand/rust-derive-hash.cc (DeriveHash::hash_impl): Likewise.
* expand/rust-derive-ord.cc (DeriveOrd::cmp_impl): Likewise.
* expand/rust-derive-partial-eq.cc
(DerivePartialEq::partialeq_impls): Likewise.
* expand/rust-derive.cc (DeriveVisitor::setup_impl_generics):
Likewise.
* expand/rust-derive.h (DeriveVisitor::setup_impl_generics):
Likewise.
Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
std::unique_ptr<TypeParamBound>
Builder::trait_bound (TypePath bound)
{
- return std::make_unique<TraitBound> (bound, loc);
+ return std::make_unique<TraitBound> (std::move (bound), loc);
}
std::unique_ptr<Item>
WhereClause where_clause, Visibility visibility) const
{
return std::unique_ptr<Item> (
- new TraitImpl (trait_path, /* unsafe */ false,
+ new TraitImpl (std::move (trait_path), /* unsafe */ false,
/* exclam */ false, std::move (trait_items),
std::move (generics), std::move (target), where_clause,
visibility, {}, {}, loc));
Builder::new_const_param (ConstGenericParam ¶m) const
{
return std::make_unique<ConstGenericParam> (param.get_name (),
- param.get_type ().clone_type (),
+ param.get_type ().reconstruct (),
param.get_default_value (),
param.get_outer_attrs (),
param.get_locus ());
// Copy constructor with vector clone
TypePath (TypePath const &other)
- : has_opening_scope_resolution (other.has_opening_scope_resolution),
+ : TypeNoBounds (other),
+ has_opening_scope_resolution (other.has_opening_scope_resolution),
locus (other.locus)
{
- node_id = other.node_id;
segments.reserve (other.segments.size ());
for (const auto &e : other.segments)
segments.push_back (e->clone_type_path_segment ());
// Overloaded assignment operator with clone
TypePath &operator= (TypePath const &other)
{
- node_id = other.node_id;
+ TypeNoBounds::operator= (other);
has_opening_scope_resolution = other.has_opening_scope_resolution;
locus = other.locus;
std::unique_ptr<AssociatedItem> &&clone_fn, std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics)
{
- // 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);
+ auto clone_trait_path
+ = [this] () { return builder.type_path (LangItem::Kind::CLONE); };
auto trait_items = vec (std::move (clone_fn));
- auto generics = setup_impl_generics (name, type_generics,
- builder.trait_bound (clone_bound));
+ auto generics = setup_impl_generics (name, type_generics, [&, this] () {
+ return builder.trait_bound (clone_trait_path ());
+ });
- return builder.trait_impl (clone_trait_path, std::move (generics.self_type),
+ return builder.trait_impl (clone_trait_path (),
+ std::move (generics.self_type),
std::move (trait_items),
std::move (generics.impl));
}
std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics)
{
- // we should have two of these, so we don't run into issues with
- // two paths sharing a node id
- auto copy_bound = builder.type_path (LangItem::Kind::COPY);
- auto copy_trait_path = builder.type_path (LangItem::Kind::COPY);
+ auto copy_trait_path
+ = [this] () { return builder.type_path (LangItem::Kind::COPY); };
- auto generics = setup_impl_generics (name, type_generics,
- builder.trait_bound (copy_bound));
+ auto generics = setup_impl_generics (name, type_generics, [&, this] () {
+ return builder.trait_bound (copy_trait_path ());
+ });
- return builder.trait_impl (copy_trait_path, std::move (generics.self_type),
+ return builder.trait_impl (copy_trait_path (), std::move (generics.self_type),
{}, std::move (generics.impl));
}
{
auto trait_items = vec (stub_debug_fn ());
- auto debug = builder.type_path ({"core", "fmt", "Debug"}, true);
- auto generics
- = setup_impl_generics (name, type_generics, builder.trait_bound (debug));
-
- return builder.trait_impl (debug, std::move (generics.self_type),
+ auto debug = [this] () {
+ return builder.type_path ({"core", "fmt", "Debug"}, true);
+ };
+ auto generics = setup_impl_generics (name, type_generics, [&, this] () {
+ return builder.trait_bound (debug ());
+ });
+
+ return builder.trait_impl (debug (), std::move (generics.self_type),
std::move (trait_items),
std::move (generics.impl));
}
std::unique_ptr<AssociatedItem> &&default_fn, std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics)
{
- auto default_path = builder.type_path ({"core", "default", "Default"}, true);
+ auto default_path = [this] () {
+ return builder.type_path ({"core", "default", "Default"}, true);
+ };
auto trait_items = vec (std::move (default_fn));
- auto generics = setup_impl_generics (name, type_generics,
- builder.trait_bound (default_path));
+ auto generics = setup_impl_generics (name, type_generics, [&, this] () {
+ return builder.trait_bound (default_path ());
+ });
- return builder.trait_impl (default_path, std::move (generics.self_type),
+ return builder.trait_impl (default_path (), std::move (generics.self_type),
std::move (trait_items),
std::move (generics.impl));
}
std::unique_ptr<AssociatedItem> &&fn, std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics)
{
- // We create two copies of the type-path to avoid duplicate NodeIds
- auto eq = get_eq_trait_path (builder);
- auto eq_bound = builder.trait_bound (get_eq_trait_path (builder));
+ auto eq = [this] () { return get_eq_trait_path (builder); };
+ auto eq_bound = [&, this] () { return builder.trait_bound (eq ()); };
auto steq = builder.type_path (LangItem::Kind::STRUCTURAL_TEQ);
auto trait_items = vec (std::move (fn));
- auto eq_generics
- = setup_impl_generics (name, type_generics, std::move (eq_bound));
+ auto eq_generics = setup_impl_generics (name, type_generics, eq_bound);
auto steq_generics = setup_impl_generics (name, type_generics);
- auto eq_impl = builder.trait_impl (eq, std::move (eq_generics.self_type),
+ auto eq_impl = builder.trait_impl (eq (), std::move (eq_generics.self_type),
std::move (trait_items),
std::move (eq_generics.impl));
std::unique_ptr<AssociatedItem> &&hash_fn, std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics)
{
- auto hash_path = builder.type_path ({"core", "hash", "Hash"}, true);
+ auto hash_path = [this] () {
+ return builder.type_path ({"core", "hash", "Hash"}, true);
+ };
auto trait_items = vec (std::move (hash_fn));
- auto generics = setup_impl_generics (name, type_generics,
- builder.trait_bound (hash_path));
+ auto generics = setup_impl_generics (name, type_generics, [&, this] () {
+ return builder.trait_bound (hash_path ());
+ });
- return builder.trait_impl (hash_path, std::move (generics.self_type),
+ return builder.trait_impl (hash_path (), std::move (generics.self_type),
std::move (trait_items),
std::move (generics.impl));
}
auto fn = cmp_fn (std::move (fn_block), type_name);
auto trait = ordering == Ordering::Partial ? "PartialOrd" : "Ord";
- auto trait_path = builder.type_path ({"core", "cmp", trait}, true);
+ auto trait_path = [&, this] () {
+ return builder.type_path ({"core", "cmp", trait}, true);
+ };
auto trait_bound
- = builder.trait_bound (builder.type_path ({"core", "cmp", trait}, true));
+ = [&, this] () { return builder.trait_bound (trait_path ()); };
auto trait_items = vec (std::move (fn));
auto cmp_generics
- = setup_impl_generics (type_name.as_string (), type_generics,
- std::move (trait_bound));
+ = setup_impl_generics (type_name.as_string (), type_generics, trait_bound);
- return builder.trait_impl (trait_path, std::move (cmp_generics.self_type),
+ return builder.trait_impl (trait_path (), std::move (cmp_generics.self_type),
std::move (trait_items),
std::move (cmp_generics.impl));
}
std::unique_ptr<AssociatedItem> &&eq_fn, std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics)
{
- auto eq = builder.type_path (LangItem::Kind::EQ);
+ auto eq = [this] () { return builder.type_path (LangItem::Kind::EQ); };
auto speq = builder.type_path (LangItem::Kind::STRUCTURAL_PEQ);
auto trait_items = vec (std::move (eq_fn));
// no extra bound on StructuralPeq
- auto peq_generics
- = setup_impl_generics (name, type_generics, builder.trait_bound (eq));
+ auto peq_generics = setup_impl_generics (name, type_generics, [&, this] () {
+ return builder.trait_bound (eq ());
+ });
auto speq_generics = setup_impl_generics (name, type_generics);
- auto peq = builder.trait_impl (eq, std::move (peq_generics.self_type),
+ auto peq = builder.trait_impl (eq (), std::move (peq_generics.self_type),
std::move (trait_items),
std::move (peq_generics.impl));
DeriveVisitor::setup_impl_generics (
const std::string &type_name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics,
- tl::optional<std::unique_ptr<TypeParamBound>> &&extra_bound) const
+ tl::optional<std::function<std::unique_ptr<TypeParamBound> ()>> &&extra_bound)
+ const
{
std::vector<Lifetime> lifetime_args;
std::vector<GenericArg> generic_args;
std::vector<std::unique_ptr<TypeParamBound>> extra_bounds;
if (extra_bound)
- extra_bounds.emplace_back (
- extra_bound.value ()->clone_type_param_bound ());
+ extra_bounds.emplace_back (extra_bound.value () ());
auto impl_type_param
= builder.new_type_param (type_param, std::move (extra_bounds));
ImplGenerics setup_impl_generics (
const std::string &type_name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics,
- tl::optional<std::unique_ptr<TypeParamBound>> &&extra_bound
+ tl::optional<std::function<std::unique_ptr<TypeParamBound> ()>>
+ &&extra_bound
= tl::nullopt) const;
private: