From 5fd04425c09ae8b3c800d74602689b4d28dce32b Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Patry Date: Wed, 8 Feb 2023 16:19:41 +0100 Subject: [PATCH] gccrs: typecheck: Refactor rust-hir-trait-reference.h Move function body to their own cc file instead of keeping them in the header file. gcc/rust/ChangeLog: * Make-lang.in: Add `rust-hir-trait-reference.o`. * typecheck/rust-hir-trait-reference.h: Remove multiple function body. * typecheck/rust-hir-trait-reference.cc: Add multiple function body. Signed-off-by: Pierre-Emmanuel Patry --- gcc/rust/Make-lang.in | 1 + gcc/rust/typecheck/rust-hir-trait-reference.cc | 463 +++++++++++++++++++++++++ gcc/rust/typecheck/rust-hir-trait-reference.h | 343 +++--------------- 3 files changed, 510 insertions(+), 297 deletions(-) create mode 100644 gcc/rust/typecheck/rust-hir-trait-reference.cc diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index d9bc409..09bbe45 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -123,6 +123,7 @@ GRS_OBJS = \ rust/rust-tyty-bounds.o \ rust/rust-hir-type-check-util.o \ rust/rust-hir-trait-resolve.o \ + rust/rust-hir-trait-reference.o \ rust/rust-hir-type-check-item.o \ rust/rust-hir-type-check-type.o \ rust/rust-hir-type-check-struct.o \ diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.cc b/gcc/rust/typecheck/rust-hir-trait-reference.cc new file mode 100644 index 0000000..651c55a --- /dev/null +++ b/gcc/rust/typecheck/rust-hir-trait-reference.cc @@ -0,0 +1,463 @@ +// Copyright (C) 2020-2022 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 +// . + +#include "rust-hir-trait-reference.h" + +namespace Rust { +namespace Resolver { + +std::string +TraitItemReference::as_string () const +{ + return "(" + trait_item_type_as_string (type) + " " + identifier + " " + ")"; +} + +bool +TraitItemReference::is_error () const +{ + return type == ERROR; +} + +bool +TraitItemReference::is_optional () const +{ + return optional_flag; +}; + +std::string +TraitItemReference::get_identifier () const +{ + return identifier; +} + +TraitItemReference::TraitItemType +TraitItemReference::get_trait_item_type () const +{ + return type; +} + +HIR::TraitItem * +TraitItemReference::get_hir_trait_item () const +{ + return hir_trait_item; +} + +Location +TraitItemReference::get_locus () const +{ + return locus; +} + +const Analysis::NodeMapping +TraitItemReference::get_mappings () const +{ + return hir_trait_item->get_mappings (); +} + +TyTy::BaseType * +TraitItemReference::get_tyty () const +{ + rust_assert (hir_trait_item != nullptr); + + switch (type) + { + case CONST: + return get_type_from_constant ( + static_cast (*hir_trait_item)); + break; + + case TYPE: + return get_type_from_typealias ( + static_cast (*hir_trait_item)); + + case FN: + return get_type_from_fn ( + static_cast (*hir_trait_item)); + break; + + default: + return get_error (); + } + + gcc_unreachable (); + return get_error (); +} + +TyTy::ErrorType * +TraitItemReference::get_error () const +{ + return new TyTy::ErrorType (get_mappings ().get_hirid ()); +} + +TraitReference::TraitReference ( + const HIR::Trait *hir_trait_ref, std::vector item_refs, + std::vector super_traits, + std::vector substs) + : hir_trait_ref (hir_trait_ref), item_refs (item_refs), + super_traits (super_traits) +{ + trait_substs.clear (); + trait_substs.reserve (substs.size ()); + for (const auto &p : substs) + trait_substs.push_back (p.clone ()); +} + +TraitReference::TraitReference (TraitReference const &other) + : hir_trait_ref (other.hir_trait_ref), item_refs (other.item_refs), + super_traits (other.super_traits) +{ + trait_substs.clear (); + trait_substs.reserve (other.trait_substs.size ()); + for (const auto &p : other.trait_substs) + trait_substs.push_back (p.clone ()); +} + +TraitReference & +TraitReference::operator= (TraitReference const &other) +{ + hir_trait_ref = other.hir_trait_ref; + item_refs = other.item_refs; + super_traits = other.super_traits; + + trait_substs.clear (); + trait_substs.reserve (other.trait_substs.size ()); + for (const auto &p : other.trait_substs) + trait_substs.push_back (p.clone ()); + + return *this; +} + +bool +TraitReference::is_error () const +{ + return hir_trait_ref == nullptr; +} + +Location +TraitReference::get_locus () const +{ + return hir_trait_ref->get_locus (); +} + +std::string +TraitReference::get_name () const +{ + rust_assert (!is_error ()); + return hir_trait_ref->get_name (); +} + +std::string +TraitReference::as_string () const +{ + if (is_error ()) + return ""; + + std::string item_buf; + for (auto &item : item_refs) + { + item_buf += item.as_string () + ", "; + } + return "HIR Trait: " + get_name () + "->" + + hir_trait_ref->get_mappings ().as_string () + " [" + item_buf + "]"; +} + +const HIR::Trait * +TraitReference::get_hir_trait_ref () const +{ + return hir_trait_ref; +} + +const Analysis::NodeMapping & +TraitReference::get_mappings () const +{ + return hir_trait_ref->get_mappings (); +} + +DefId +TraitReference::get_defid () const +{ + return get_mappings ().get_defid (); +} + +bool +TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item, + TraitItemReference **ref) +{ + return lookup_trait_item (item.trait_identifier (), ref); +} + +bool +TraitReference::lookup_trait_item (const std::string &ident, + TraitItemReference **ref) +{ + for (auto &item : item_refs) + { + if (ident.compare (item.get_identifier ()) == 0) + { + *ref = &item; + return true; + } + } + return false; +} + +bool +TraitReference::lookup_trait_item_by_type ( + const std::string &ident, TraitItemReference::TraitItemType type, + TraitItemReference **ref) +{ + for (auto &item : item_refs) + { + if (item.get_trait_item_type () != type) + continue; + + if (ident.compare (item.get_identifier ()) == 0) + { + *ref = &item; + return true; + } + } + return false; +} + +bool +TraitReference::lookup_trait_item_by_type ( + const std::string &ident, TraitItemReference::TraitItemType type, + const TraitItemReference **ref) const +{ + for (auto &item : item_refs) + { + if (item.get_trait_item_type () != type) + continue; + + if (ident.compare (item.get_identifier ()) == 0) + { + *ref = &item; + return true; + } + } + return false; +} + +bool +TraitReference::lookup_hir_trait_item (const HIR::TraitItem &item, + const TraitItemReference **ref) const +{ + return lookup_trait_item (item.trait_identifier (), ref); +} + +bool +TraitReference::lookup_trait_item (const std::string &ident, + const TraitItemReference **ref) const +{ + for (auto &item : item_refs) + { + if (ident.compare (item.get_identifier ()) == 0) + { + *ref = &item; + return true; + } + } + + // lookup super traits + for (const auto &super_trait : super_traits) + { + bool found = super_trait->lookup_trait_item (ident, ref); + if (found) + return true; + } + + return false; +} + +const TraitItemReference * +TraitReference::lookup_trait_item (const std::string &ident, + TraitItemReference::TraitItemType type) const +{ + for (auto &item : item_refs) + { + if (item.get_trait_item_type () != type) + continue; + + if (ident.compare (item.get_identifier ()) == 0) + return &item; + } + + // lookup super traits + for (const auto &super_trait : super_traits) + { + const TraitItemReference *res + = super_trait->lookup_trait_item (ident, type); + if (!res->is_error ()) + return res; + } + + return &TraitItemReference::error_node (); +} + +size_t +TraitReference::size () const +{ + return item_refs.size (); +} + +const std::vector & +TraitReference::get_trait_items () const +{ + return item_refs; +} + +void +TraitReference::get_trait_items_and_supers ( + std::vector &result) const +{ + for (const auto &item : item_refs) + result.push_back (&item); + + for (const auto &super_trait : super_traits) + super_trait->get_trait_items_and_supers (result); +} + +void +TraitReference::on_resolved () +{ + for (auto &item : item_refs) + { + item.on_resolved (); + } +} + +void +TraitReference::clear_associated_types () +{ + for (auto &item : item_refs) + { + bool is_assoc_type = item.get_trait_item_type () + == TraitItemReference::TraitItemType::TYPE; + if (is_assoc_type) + item.associated_type_reset (); + } +} + +bool +TraitReference::is_equal (const TraitReference &other) const +{ + DefId this_id = get_mappings ().get_defid (); + DefId other_id = other.get_mappings ().get_defid (); + return this_id == other_id; +} + +const std::vector +TraitReference::get_super_traits () const +{ + return super_traits; +} + +bool +TraitReference::is_object_safe (bool emit_error, Location locus) const +{ + // https: // doc.rust-lang.org/reference/items/traits.html#object-safety + std::vector non_object_super_traits; + for (auto &item : super_traits) + { + if (!item->is_object_safe (false, Location ())) + non_object_super_traits.push_back (item); + } + + std::vector non_object_safe_items; + for (auto &item : get_trait_items ()) + { + if (!item.is_object_safe ()) + non_object_safe_items.push_back (&item); + } + + bool is_safe + = non_object_super_traits.empty () && non_object_safe_items.empty (); + if (emit_error && !is_safe) + { + RichLocation r (locus); + for (auto &item : non_object_super_traits) + r.add_range (item->get_locus ()); + for (auto &item : non_object_safe_items) + r.add_range (item->get_locus ()); + + rust_error_at (r, "trait bound is not object safe"); + } + + return is_safe; +} + +bool +TraitReference::trait_has_generics () const +{ + return !trait_substs.empty (); +} + +std::vector +TraitReference::get_trait_substs () const +{ + return trait_substs; +} + +bool +TraitReference::satisfies_bound (const TraitReference &reference) const +{ + if (is_equal (reference)) + return true; + + for (const auto &super_trait : super_traits) + { + if (super_trait->satisfies_bound (reference)) + return true; + } + + return false; +} + +AssociatedImplTrait::AssociatedImplTrait (TraitReference *trait, + HIR::ImplBlock *impl, + TyTy::BaseType *self, + Resolver::TypeCheckContext *context) + : trait (trait), impl (impl), self (self), context (context) +{} + +TraitReference * +AssociatedImplTrait::get_trait () +{ + return trait; +} + +HIR::ImplBlock * +AssociatedImplTrait::get_impl_block () +{ + return impl; +} + +TyTy::BaseType * +AssociatedImplTrait::get_self () +{ + return self; +} +const TyTy::BaseType * +AssociatedImplTrait::get_self () const +{ + return self; +} + +} // namespace Resolver +} // namespace Rust diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.h b/gcc/rust/typecheck/rust-hir-trait-reference.h index adb63b4..f3703ef 100644 --- a/gcc/rust/typecheck/rust-hir-trait-reference.h +++ b/gcc/rust/typecheck/rust-hir-trait-reference.h @@ -20,8 +20,8 @@ #define RUST_HIR_TRAIT_REF_H #include "rust-hir-full.h" -#include "rust-tyty-visitor.h" #include "rust-hir-type-check-util.h" +#include "rust-tyty-visitor.h" namespace Rust { namespace Resolver { @@ -61,13 +61,9 @@ public: return error; } - bool is_error () const { return type == ERROR; } + bool is_error () const; - std::string as_string () const - { - return "(" + trait_item_type_as_string (type) + " " + identifier + " " - + ")"; - } + std::string as_string () const; static std::string trait_item_type_as_string (TraitItemType ty) { @@ -85,53 +81,24 @@ public: return "ERROR"; } - bool is_optional () const { return optional_flag; } - - std::string get_identifier () const { return identifier; } - - TraitItemType get_trait_item_type () const { return type; } - - HIR::TraitItem *get_hir_trait_item () const { return hir_trait_item; } + bool is_optional () const; - Location get_locus () const { return locus; } + std::string get_identifier () const; - const Analysis::NodeMapping get_mappings () const - { - return hir_trait_item->get_mappings (); - } + TraitItemType get_trait_item_type () const; - TyTy::BaseType *get_tyty () const - { - rust_assert (hir_trait_item != nullptr); + HIR::TraitItem *get_hir_trait_item () const; - switch (type) - { - case CONST: - return get_type_from_constant ( - static_cast (*hir_trait_item)); - break; + Location get_locus () const; - case TYPE: - return get_type_from_typealias ( - static_cast (*hir_trait_item)); + const Analysis::NodeMapping get_mappings () const; - case FN: - return get_type_from_fn ( - static_cast (*hir_trait_item)); - break; - - default: - return get_error (); - } - - gcc_unreachable (); - return get_error (); - } + TyTy::BaseType *get_tyty () const; Analysis::NodeMapping get_parent_trait_mappings () const; - // this is called when the trait is completed resolution and gives the items a - // chance to run their specific type resolution passes. If we call their + // this is called when the trait is completed resolution and gives the items + // a chance to run their specific type resolution passes. If we call their // resolution on construction it can lead to a case where the trait being // resolved recursively trying to resolve the trait itself infinitely since // the trait will not be stored in its own map yet @@ -144,10 +111,7 @@ public: bool is_object_safe () const; private: - TyTy::ErrorType *get_error () const - { - return new TyTy::ErrorType (get_mappings ().get_hirid ()); - } + TyTy::ErrorType *get_error () const; TyTy::BaseType *get_type_from_typealias (/*const*/ HIR::TraitItemType &type) const; @@ -182,39 +146,11 @@ public: TraitReference (const HIR::Trait *hir_trait_ref, std::vector item_refs, std::vector super_traits, - std::vector substs) - : hir_trait_ref (hir_trait_ref), item_refs (item_refs), - super_traits (super_traits) - { - trait_substs.clear (); - trait_substs.reserve (substs.size ()); - for (const auto &p : substs) - trait_substs.push_back (p.clone ()); - } - - TraitReference (TraitReference const &other) - : hir_trait_ref (other.hir_trait_ref), item_refs (other.item_refs), - super_traits (other.super_traits) - { - trait_substs.clear (); - trait_substs.reserve (other.trait_substs.size ()); - for (const auto &p : other.trait_substs) - trait_substs.push_back (p.clone ()); - } - - TraitReference &operator= (TraitReference const &other) - { - hir_trait_ref = other.hir_trait_ref; - item_refs = other.item_refs; - super_traits = other.super_traits; + std::vector substs); - trait_substs.clear (); - trait_substs.reserve (other.trait_substs.size ()); - for (const auto &p : other.trait_substs) - trait_substs.push_back (p.clone ()); + TraitReference (TraitReference const &other); - return *this; - } + TraitReference &operator= (TraitReference const &other); TraitReference (TraitReference &&other) = default; TraitReference &operator= (TraitReference &&other) = default; @@ -224,7 +160,7 @@ public: return TraitReference (nullptr, {}, {}, {}); } - bool is_error () const { return hir_trait_ref == nullptr; } + bool is_error () const; static TraitReference &error_node () { @@ -232,248 +168,63 @@ public: return trait_error_node; } - Location get_locus () const { return hir_trait_ref->get_locus (); } + Location get_locus () const; - std::string get_name () const - { - rust_assert (!is_error ()); - return hir_trait_ref->get_name (); - } + std::string get_name () const; - std::string as_string () const - { - if (is_error ()) - return ""; - - std::string item_buf; - for (auto &item : item_refs) - { - item_buf += item.as_string () + ", "; - } - return "HIR Trait: " + get_name () + "->" - + hir_trait_ref->get_mappings ().as_string () + " [" + item_buf - + "]"; - } + std::string as_string () const; - const HIR::Trait *get_hir_trait_ref () const { return hir_trait_ref; } + const HIR::Trait *get_hir_trait_ref () const; - const Analysis::NodeMapping &get_mappings () const - { - return hir_trait_ref->get_mappings (); - } + const Analysis::NodeMapping &get_mappings () const; - DefId get_defid () const { return get_mappings ().get_defid (); } + DefId get_defid () const; bool lookup_hir_trait_item (const HIR::TraitItem &item, - TraitItemReference **ref) - { - return lookup_trait_item (item.trait_identifier (), ref); - } + TraitItemReference **ref); - bool lookup_trait_item (const std::string &ident, TraitItemReference **ref) - { - for (auto &item : item_refs) - { - if (ident.compare (item.get_identifier ()) == 0) - { - *ref = &item; - return true; - } - } - return false; - } + bool lookup_trait_item (const std::string &ident, TraitItemReference **ref); bool lookup_trait_item_by_type (const std::string &ident, TraitItemReference::TraitItemType type, - TraitItemReference **ref) - { - for (auto &item : item_refs) - { - if (item.get_trait_item_type () != type) - continue; - - if (ident.compare (item.get_identifier ()) == 0) - { - *ref = &item; - return true; - } - } - return false; - } + TraitItemReference **ref); bool lookup_trait_item_by_type (const std::string &ident, TraitItemReference::TraitItemType type, - const TraitItemReference **ref) const - { - for (auto &item : item_refs) - { - if (item.get_trait_item_type () != type) - continue; - - if (ident.compare (item.get_identifier ()) == 0) - { - *ref = &item; - return true; - } - } - return false; - } + const TraitItemReference **ref) const; bool lookup_hir_trait_item (const HIR::TraitItem &item, - const TraitItemReference **ref) const - { - return lookup_trait_item (item.trait_identifier (), ref); - } + const TraitItemReference **ref) const; bool lookup_trait_item (const std::string &ident, - const TraitItemReference **ref) const - { - for (auto &item : item_refs) - { - if (ident.compare (item.get_identifier ()) == 0) - { - *ref = &item; - return true; - } - } - - // lookup super traits - for (const auto &super_trait : super_traits) - { - bool found = super_trait->lookup_trait_item (ident, ref); - if (found) - return true; - } - - return false; - } + const TraitItemReference **ref) const; const TraitItemReference * lookup_trait_item (const std::string &ident, - TraitItemReference::TraitItemType type) const - { - for (auto &item : item_refs) - { - if (item.get_trait_item_type () != type) - continue; + TraitItemReference::TraitItemType type) const; - if (ident.compare (item.get_identifier ()) == 0) - return &item; - } + size_t size () const; - // lookup super traits - for (const auto &super_trait : super_traits) - { - const TraitItemReference *res - = super_trait->lookup_trait_item (ident, type); - if (!res->is_error ()) - return res; - } - - return &TraitItemReference::error_node (); - } - - size_t size () const { return item_refs.size (); } - - const std::vector &get_trait_items () const - { - return item_refs; - } + const std::vector &get_trait_items () const; void get_trait_items_and_supers ( - std::vector &result) const - { - for (const auto &item : item_refs) - result.push_back (&item); - - for (const auto &super_trait : super_traits) - super_trait->get_trait_items_and_supers (result); - } - - void on_resolved () - { - for (auto &item : item_refs) - { - item.on_resolved (); - } - } - - void clear_associated_types () - { - for (auto &item : item_refs) - { - bool is_assoc_type = item.get_trait_item_type () - == TraitItemReference::TraitItemType::TYPE; - if (is_assoc_type) - item.associated_type_reset (); - } - } - - bool is_equal (const TraitReference &other) const - { - DefId this_id = get_mappings ().get_defid (); - DefId other_id = other.get_mappings ().get_defid (); - return this_id == other_id; - } - - const std::vector get_super_traits () const - { - return super_traits; - } - - bool is_object_safe (bool emit_error, Location locus) const - { - // https: // doc.rust-lang.org/reference/items/traits.html#object-safety - std::vector non_object_super_traits; - for (auto &item : super_traits) - { - if (!item->is_object_safe (false, Location ())) - non_object_super_traits.push_back (item); - } + std::vector &result) const; - std::vector non_object_safe_items; - for (auto &item : get_trait_items ()) - { - if (!item.is_object_safe ()) - non_object_safe_items.push_back (&item); - } + void on_resolved (); - bool is_safe - = non_object_super_traits.empty () && non_object_safe_items.empty (); - if (emit_error && !is_safe) - { - RichLocation r (locus); - for (auto &item : non_object_super_traits) - r.add_range (item->get_locus ()); - for (auto &item : non_object_safe_items) - r.add_range (item->get_locus ()); + void clear_associated_types (); - rust_error_at (r, "trait bound is not object safe"); - } + bool is_equal (const TraitReference &other) const; - return is_safe; - } + const std::vector get_super_traits () const; - bool trait_has_generics () const { return !trait_substs.empty (); } + bool is_object_safe (bool emit_error, Location locus) const; - std::vector get_trait_substs () const - { - return trait_substs; - } - - bool satisfies_bound (const TraitReference &reference) const - { - if (is_equal (reference)) - return true; + bool trait_has_generics () const; - for (const auto &super_trait : super_traits) - { - if (super_trait->satisfies_bound (reference)) - return true; - } + std::vector get_trait_substs () const; - return false; - } + bool satisfies_bound (const TraitReference &reference) const; private: const HIR::Trait *hir_trait_ref; @@ -487,16 +238,14 @@ class AssociatedImplTrait public: AssociatedImplTrait (TraitReference *trait, HIR::ImplBlock *impl, TyTy::BaseType *self, - Resolver::TypeCheckContext *context) - : trait (trait), impl (impl), self (self), context (context) - {} + Resolver::TypeCheckContext *context); - TraitReference *get_trait () { return trait; } + TraitReference *get_trait (); - HIR::ImplBlock *get_impl_block () { return impl; } + HIR::ImplBlock *get_impl_block (); - TyTy::BaseType *get_self () { return self; } - const TyTy::BaseType *get_self () const { return self; } + TyTy::BaseType *get_self (); + const TyTy::BaseType *get_self () const; TyTy::BaseType * setup_associated_types (const TyTy::BaseType *self, -- 2.7.4