(root)/
gcc-13.2.0/
gcc/
rust/
typecheck/
rust-hir-type-check.h
       1  // Copyright (C) 2020-2023 Free Software Foundation, Inc.
       2  
       3  // This file is part of GCC.
       4  
       5  // GCC is free software; you can redistribute it and/or modify it under
       6  // the terms of the GNU General Public License as published by the Free
       7  // Software Foundation; either version 3, or (at your option) any later
       8  // version.
       9  
      10  // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11  // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13  // for more details.
      14  
      15  // You should have received a copy of the GNU General Public License
      16  // along with GCC; see the file COPYING3.  If not see
      17  // <http://www.gnu.org/licenses/>.
      18  
      19  #ifndef RUST_HIR_TYPE_CHECK
      20  #define RUST_HIR_TYPE_CHECK
      21  
      22  #include "rust-type-util.h"
      23  #include "rust-hir-full-decls.h"
      24  #include "rust-hir-map.h"
      25  #include "rust-tyty.h"
      26  #include "rust-hir-trait-reference.h"
      27  #include "rust-autoderef.h"
      28  
      29  namespace Rust {
      30  namespace Resolver {
      31  
      32  class TypeCheckContextItem
      33  {
      34  public:
      35    enum ItemType
      36    {
      37      ITEM,
      38      IMPL_ITEM,
      39      TRAIT_ITEM,
      40    };
      41  
      42    TypeCheckContextItem (HIR::Function *item);
      43    TypeCheckContextItem (HIR::ImplBlock *impl_block, HIR::Function *item);
      44    TypeCheckContextItem (HIR::TraitItemFunc *trait_item);
      45  
      46    ItemType get_type () const;
      47  
      48    HIR::Function *get_item ();
      49  
      50    std::pair<HIR::ImplBlock *, HIR::Function *> &get_impl_item ();
      51  
      52    HIR::TraitItemFunc *get_trait_item ();
      53  
      54    TyTy::FnType *get_context_type ();
      55  
      56  private:
      57    union Item
      58    {
      59      HIR::Function *item;
      60      std::pair<HIR::ImplBlock *, HIR::Function *> impl_item;
      61      HIR::TraitItemFunc *trait_item;
      62  
      63      Item (HIR::Function *item);
      64      Item (HIR::ImplBlock *impl_block, HIR::Function *item);
      65      Item (HIR::TraitItemFunc *trait_item);
      66    };
      67  
      68    ItemType type;
      69    Item item;
      70  };
      71  
      72  class TypeCheckContext
      73  {
      74  public:
      75    static TypeCheckContext *get ();
      76  
      77    ~TypeCheckContext ();
      78  
      79    bool lookup_builtin (NodeId id, TyTy::BaseType **type);
      80    bool lookup_builtin (std::string name, TyTy::BaseType **type);
      81    void insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type);
      82  
      83    void insert_type (const Analysis::NodeMapping &mappings,
      84  		    TyTy::BaseType *type);
      85    void insert_implicit_type (TyTy::BaseType *type);
      86    bool lookup_type (HirId id, TyTy::BaseType **type) const;
      87  
      88    void insert_implicit_type (HirId id, TyTy::BaseType *type);
      89  
      90    void insert_type_by_node_id (NodeId ref, HirId id);
      91    bool lookup_type_by_node_id (NodeId ref, HirId *id);
      92  
      93    TyTy::BaseType *peek_return_type ();
      94    TypeCheckContextItem &peek_context ();
      95    void push_return_type (TypeCheckContextItem item,
      96  			 TyTy::BaseType *return_type);
      97    void pop_return_type ();
      98    void iterate (std::function<bool (HirId, TyTy::BaseType *)> cb);
      99  
     100    bool have_loop_context () const;
     101    void push_new_loop_context (HirId id, Location locus);
     102    void push_new_while_loop_context (HirId id);
     103    TyTy::BaseType *peek_loop_context ();
     104    TyTy::BaseType *pop_loop_context ();
     105  
     106    void swap_head_loop_context (TyTy::BaseType *val);
     107  
     108    void insert_trait_reference (DefId id, TraitReference &&ref);
     109    bool lookup_trait_reference (DefId id, TraitReference **ref);
     110  
     111    void insert_receiver (HirId id, TyTy::BaseType *t);
     112    bool lookup_receiver (HirId id, TyTy::BaseType **ref);
     113  
     114    void insert_associated_trait_impl (HirId id,
     115  				     AssociatedImplTrait &&associated);
     116    bool lookup_associated_trait_impl (HirId id,
     117  				     AssociatedImplTrait **associated);
     118  
     119    void insert_associated_type_mapping (HirId id, HirId mapping);
     120    void clear_associated_type_mapping (HirId id);
     121  
     122    // lookup any associated type mappings, the out parameter of mapping is
     123    // allowed to be nullptr which allows this interface to do a simple does exist
     124    // check
     125    bool lookup_associated_type_mapping (HirId id, HirId *mapping);
     126  
     127    void insert_associated_impl_mapping (HirId trait_id,
     128  				       const TyTy::BaseType *impl_type,
     129  				       HirId impl_id);
     130    bool lookup_associated_impl_mapping_for_self (HirId trait_id,
     131  						const TyTy::BaseType *self,
     132  						HirId *mapping);
     133  
     134    void insert_autoderef_mappings (HirId id,
     135  				  std::vector<Adjustment> &&adjustments);
     136    bool lookup_autoderef_mappings (HirId id,
     137  				  std::vector<Adjustment> **adjustments);
     138  
     139    void insert_cast_autoderef_mappings (HirId id,
     140  				       std::vector<Adjustment> &&adjustments);
     141    bool lookup_cast_autoderef_mappings (HirId id,
     142  				       std::vector<Adjustment> **adjustments);
     143  
     144    void insert_variant_definition (HirId id, HirId variant);
     145    bool lookup_variant_definition (HirId id, HirId *variant);
     146  
     147    void insert_operator_overload (HirId id, TyTy::FnType *call_site);
     148    bool lookup_operator_overload (HirId id, TyTy::FnType **call);
     149  
     150    void insert_unconstrained_check_marker (HirId id, bool status);
     151    bool have_checked_for_unconstrained (HirId id, bool *result);
     152  
     153    void insert_resolved_predicate (HirId id, TyTy::TypeBoundPredicate predicate);
     154    bool lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result);
     155  
     156    void insert_query (HirId id);
     157    void query_completed (HirId id);
     158    bool query_in_progress (HirId id) const;
     159  
     160    void insert_trait_query (DefId id);
     161    void trait_query_completed (DefId id);
     162    bool trait_query_in_progress (DefId id) const;
     163  
     164  private:
     165    TypeCheckContext ();
     166  
     167    std::map<NodeId, HirId> node_id_refs;
     168    std::map<HirId, TyTy::BaseType *> resolved;
     169    std::vector<std::unique_ptr<TyTy::BaseType>> builtins;
     170    std::vector<std::pair<TypeCheckContextItem, TyTy::BaseType *>>
     171      return_type_stack;
     172    std::vector<TyTy::BaseType *> loop_type_stack;
     173    std::map<DefId, TraitReference> trait_context;
     174    std::map<HirId, TyTy::BaseType *> receiver_context;
     175    std::map<HirId, AssociatedImplTrait> associated_impl_traits;
     176  
     177    // trait-id -> list of < self-tyty:impl-id>
     178    std::map<HirId, std::vector<std::pair<const TyTy::BaseType *, HirId>>>
     179      associated_traits_to_impls;
     180  
     181    std::map<HirId, HirId> associated_type_mappings;
     182  
     183    // adjustment mappings
     184    std::map<HirId, std::vector<Adjustment>> autoderef_mappings;
     185    std::map<HirId, std::vector<Adjustment>> cast_autoderef_mappings;
     186  
     187    // operator overloads
     188    std::map<HirId, TyTy::FnType *> operator_overloads;
     189  
     190    // variants
     191    std::map<HirId, HirId> variants;
     192  
     193    // unconstrained type-params check
     194    std::map<HirId, bool> unconstrained;
     195  
     196    // predicates
     197    std::map<HirId, TyTy::TypeBoundPredicate> predicates;
     198  
     199    // query context lookups
     200    std::set<HirId> querys_in_progress;
     201    std::set<DefId> trait_queries_in_progress;
     202  };
     203  
     204  class TypeResolution
     205  {
     206  public:
     207    static void Resolve (HIR::Crate &crate);
     208  };
     209  
     210  class TraitQueryGuard
     211  {
     212  public:
     213    TraitQueryGuard (DefId id) : id (id), ctx (*TypeCheckContext::get ())
     214    {
     215      ctx.insert_trait_query (id);
     216    }
     217  
     218    ~TraitQueryGuard () { ctx.trait_query_completed (id); }
     219  
     220  private:
     221    DefId id;
     222    TypeCheckContext &ctx;
     223  };
     224  
     225  } // namespace Resolver
     226  } // namespace Rust
     227  
     228  #endif // RUST_HIR_TYPE_CHECK