| // Copyright (C) 2021-2023 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_HIR_TRAIT_REF_H |
| #define RUST_HIR_TRAIT_REF_H |
| |
| #include "rust-hir-full.h" |
| #include "rust-hir-type-check-util.h" |
| #include "rust-tyty-visitor.h" |
| |
| namespace Rust { |
| namespace Resolver { |
| |
| // Data Objects for the associated trait items in a structure we can work with |
| // https://doc.rust-lang.org/edition-guide/rust-2018/trait-system/associated-constants.html |
| class TypeCheckContext; |
| class TraitItemReference |
| { |
| public: |
| enum TraitItemType |
| { |
| FN, |
| CONST, |
| TYPE, |
| ERROR |
| }; |
| |
| TraitItemReference (std::string identifier, bool optional, TraitItemType type, |
| HIR::TraitItem *hir_trait_item, TyTy::BaseType *self, |
| std::vector<TyTy::SubstitutionParamMapping> substitutions, |
| Location locus); |
| |
| TraitItemReference (TraitItemReference const &other); |
| |
| TraitItemReference &operator= (TraitItemReference const &other); |
| |
| static TraitItemReference error () |
| { |
| return TraitItemReference ("", false, ERROR, nullptr, nullptr, {}, |
| Location ()); |
| } |
| |
| static TraitItemReference &error_node () |
| { |
| static TraitItemReference error = TraitItemReference::error (); |
| return error; |
| } |
| |
| bool is_error () const; |
| |
| std::string as_string () const; |
| |
| static std::string trait_item_type_as_string (TraitItemType ty) |
| { |
| switch (ty) |
| { |
| case FN: |
| return "FN"; |
| case CONST: |
| return "CONST"; |
| case TYPE: |
| return "TYPE"; |
| case ERROR: |
| return "ERROR"; |
| } |
| return "ERROR"; |
| } |
| |
| bool is_optional () const; |
| |
| std::string get_identifier () const; |
| |
| TraitItemType get_trait_item_type () const; |
| |
| HIR::TraitItem *get_hir_trait_item () const; |
| |
| Location get_locus () const; |
| |
| const Analysis::NodeMapping get_mappings () const; |
| |
| 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 |
| // 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 |
| void on_resolved (); |
| |
| void associated_type_set (TyTy::BaseType *ty) const; |
| |
| void associated_type_reset (bool only_projections) const; |
| |
| bool is_object_safe () const; |
| |
| private: |
| TyTy::ErrorType *get_error () const; |
| |
| TyTy::BaseType *get_type_from_typealias (/*const*/ |
| HIR::TraitItemType &type) const; |
| |
| TyTy::BaseType * |
| get_type_from_constant (/*const*/ HIR::TraitItemConst &constant) const; |
| |
| TyTy::BaseType *get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const; |
| |
| bool is_item_resolved () const; |
| void resolve_item (HIR::TraitItemType &type); |
| void resolve_item (HIR::TraitItemConst &constant); |
| void resolve_item (HIR::TraitItemFunc &func); |
| |
| std::string identifier; |
| bool optional_flag; |
| TraitItemType type; |
| HIR::TraitItem *hir_trait_item; |
| std::vector<TyTy::SubstitutionParamMapping> inherited_substitutions; |
| Location locus; |
| |
| TyTy::BaseType |
| *self; // this is the implict Self TypeParam required for methods |
| Resolver::TypeCheckContext *context; |
| }; |
| |
| // this wraps up the HIR::Trait so we can do analysis on it |
| |
| class TraitReference |
| { |
| public: |
| TraitReference (const HIR::Trait *hir_trait_ref, |
| std::vector<TraitItemReference> item_refs, |
| std::vector<const TraitReference *> super_traits, |
| std::vector<TyTy::SubstitutionParamMapping> substs); |
| |
| TraitReference (TraitReference const &other); |
| |
| TraitReference &operator= (TraitReference const &other); |
| |
| TraitReference (TraitReference &&other) = default; |
| TraitReference &operator= (TraitReference &&other) = default; |
| |
| static TraitReference error () |
| { |
| return TraitReference (nullptr, {}, {}, {}); |
| } |
| |
| bool is_error () const; |
| |
| static TraitReference &error_node () |
| { |
| static TraitReference trait_error_node = TraitReference::error (); |
| return trait_error_node; |
| } |
| |
| Location get_locus () const; |
| |
| std::string get_name () const; |
| |
| std::string as_string () const; |
| |
| const HIR::Trait *get_hir_trait_ref () const; |
| |
| const Analysis::NodeMapping &get_mappings () const; |
| |
| DefId get_defid () const; |
| |
| bool lookup_hir_trait_item (const HIR::TraitItem &item, |
| TraitItemReference **ref); |
| |
| 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); |
| |
| bool lookup_trait_item_by_type (const std::string &ident, |
| TraitItemReference::TraitItemType type, |
| const TraitItemReference **ref) const; |
| |
| bool lookup_hir_trait_item (const HIR::TraitItem &item, |
| const TraitItemReference **ref) const; |
| |
| bool lookup_trait_item (const std::string &ident, |
| const TraitItemReference **ref) const; |
| |
| const TraitItemReference * |
| lookup_trait_item (const std::string &ident, |
| TraitItemReference::TraitItemType type) const; |
| |
| size_t size () const; |
| |
| const std::vector<TraitItemReference> &get_trait_items () const; |
| |
| void get_trait_items_and_supers ( |
| std::vector<const TraitItemReference *> &result) const; |
| |
| void on_resolved (); |
| |
| void clear_associated_types () const; |
| |
| void clear_associated_type_projections () const; |
| |
| bool is_equal (const TraitReference &other) const; |
| |
| const std::vector<const TraitReference *> get_super_traits () const; |
| |
| bool is_object_safe (bool emit_error, Location locus) const; |
| |
| bool trait_has_generics () const; |
| |
| std::vector<TyTy::SubstitutionParamMapping> get_trait_substs () const; |
| |
| bool satisfies_bound (const TraitReference &reference) const; |
| |
| private: |
| const HIR::Trait *hir_trait_ref; |
| std::vector<TraitItemReference> item_refs; |
| std::vector<const TraitReference *> super_traits; |
| std::vector<TyTy::SubstitutionParamMapping> trait_substs; |
| }; |
| |
| class AssociatedImplTrait |
| { |
| public: |
| AssociatedImplTrait (TraitReference *trait, HIR::ImplBlock *impl, |
| TyTy::BaseType *self, |
| Resolver::TypeCheckContext *context); |
| |
| TraitReference *get_trait (); |
| |
| HIR::ImplBlock *get_impl_block (); |
| |
| TyTy::BaseType *get_self (); |
| const TyTy::BaseType *get_self () const; |
| |
| TyTy::BaseType * |
| setup_associated_types (const TyTy::BaseType *self, |
| const TyTy::TypeBoundPredicate &bound); |
| |
| void reset_associated_types (); |
| |
| private: |
| TraitReference *trait; |
| HIR::ImplBlock *impl; |
| TyTy::BaseType *self; |
| Resolver::TypeCheckContext *context; |
| }; |
| |
| } // namespace Resolver |
| } // namespace Rust |
| |
| #endif // RUST_HIR_TRAIT_REF_H |