LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-hir-type-check.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.0 % 87 80
Test Date: 2026-10-24 16:24:59 Functions: 91.7 % 12 11
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-2026 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-hir-map.h"
      23              : #include "rust-mapping-common.h"
      24              : #include "rust-tyty.h"
      25              : #include "rust-hir-impl-trait-context.h"
      26              : #include "rust-hir-trait-reference.h"
      27              : #include "rust-stacked-contexts.h"
      28              : #include "rust-autoderef.h"
      29              : #include "rust-tyty-region.h"
      30              : #include "rust-tyty-variance-analysis.h"
      31              : #include "rust-system.h"
      32              : 
      33              : namespace Rust {
      34              : namespace Resolver {
      35              : 
      36              : class TypeCheckContextItem
      37              : {
      38              : public:
      39              :   enum ItemType
      40              :   {
      41              :     ITEM,
      42              :     IMPL_ITEM,
      43              :     TRAIT_ITEM,
      44              :     ERROR
      45              :   };
      46              : 
      47              :   TypeCheckContextItem (HIR::Function *item);
      48              :   TypeCheckContextItem (HIR::ImplBlock &impl_block, HIR::Function *item);
      49              :   TypeCheckContextItem (HIR::TraitItemFunc *trait_item);
      50              :   TypeCheckContextItem (const TypeCheckContextItem &other);
      51              : 
      52              :   TypeCheckContextItem &operator= (const TypeCheckContextItem &other);
      53              : 
      54              :   static TypeCheckContextItem get_error ();
      55              : 
      56              :   bool is_error () const;
      57              : 
      58              :   ItemType get_type () const;
      59              : 
      60              :   HIR::Function *get_item ();
      61              : 
      62              :   std::pair<HIR::ImplBlock *, HIR::Function *> &get_impl_item ();
      63              : 
      64              :   HIR::TraitItemFunc *get_trait_item ();
      65              : 
      66              :   TyTy::FnType *get_context_type ();
      67              : 
      68              :   DefId get_defid () const;
      69              : 
      70              : private:
      71              :   TypeCheckContextItem ();
      72              : 
      73              :   union Item
      74              :   {
      75              :     HIR::Function *item;
      76              :     std::pair<HIR::ImplBlock *, HIR::Function *> impl_item;
      77              :     HIR::TraitItemFunc *trait_item;
      78              : 
      79              :     Item (HIR::Function *item);
      80              :     Item (HIR::ImplBlock *impl_block, HIR::Function *item);
      81              :     Item (HIR::TraitItemFunc *trait_item);
      82              :   };
      83              : 
      84              :   ItemType type;
      85              :   Item item;
      86              : };
      87              : 
      88              : class TypeCheckBlockContextItem
      89              : {
      90              : public:
      91              :   enum ItemType
      92              :   {
      93              :     IMPL_BLOCK,
      94              :     TRAIT
      95              :   };
      96              : 
      97              :   TypeCheckBlockContextItem (HIR::ImplBlock *block);
      98              :   TypeCheckBlockContextItem (HIR::Trait *trait);
      99              : 
     100              :   bool is_impl_block () const;
     101              :   bool is_trait_block () const;
     102              : 
     103              :   HIR::ImplBlock &get_impl_block ();
     104              :   HIR::Trait &get_trait ();
     105              : 
     106              : private:
     107              :   union Item
     108              :   {
     109              :     HIR::ImplBlock *block;
     110              :     HIR::Trait *trait;
     111              : 
     112              :     Item (HIR::ImplBlock *block);
     113              :     Item (HIR::Trait *trait);
     114              :   };
     115              :   ItemType type;
     116              :   Item item;
     117              : };
     118              : 
     119              : /**
     120              :  * Interned lifetime representation in TyTy
     121              :  *
     122              :  * On the HIR->TyTy boundary HIR::Lifetime is interned into this struct.
     123              :  */
     124              : class Lifetime
     125              : {
     126              :   uint32_t interner_index;
     127              : 
     128              : public:
     129          110 :   explicit constexpr Lifetime (uint32_t interner_index)
     130              :     : interner_index (interner_index)
     131              :   {}
     132              : 
     133              :   Lifetime () = default;
     134              : 
     135         9889 :   WARN_UNUSED_RESULT bool is_static () const { return interner_index == 0; }
     136              : 
     137              :   WARN_UNUSED_RESULT static constexpr Lifetime static_lifetime ()
     138              :   {
     139              :     return Lifetime (0);
     140              :   }
     141              : 
     142              :   WARN_UNUSED_RESULT static constexpr Lifetime anonymous_lifetime ()
     143              :   {
     144              :     return Lifetime (1);
     145              :   }
     146              : 
     147              :   static constexpr uint32_t FIRST_NAMED_LIFETIME = 2;
     148              : 
     149          358 :   friend bool operator== (const Lifetime &lhs, const Lifetime &rhs)
     150              :   {
     151          358 :     return lhs.interner_index == rhs.interner_index;
     152              :   }
     153              : 
     154              :   friend bool operator!= (const Lifetime &lhs, const Lifetime &rhs)
     155              :   {
     156              :     return !(lhs == rhs);
     157              :   }
     158              : 
     159          110 :   WARN_UNUSED_RESULT Lifetime next () { return Lifetime (interner_index++); }
     160              : };
     161              : 
     162           45 : struct DeferredOpOverload
     163              : {
     164              :   HirId expr_id;
     165              :   LangItem::Kind lang_item_type;
     166              :   HIR::PathIdentSegment specified_segment;
     167              :   HIR::OperatorExprMeta op;
     168              :   TyTy::TyVar result_type;
     169              : 
     170           15 :   DeferredOpOverload (HirId expr_id, LangItem::Kind lang_item_type,
     171              :                       HIR::PathIdentSegment specified_segment,
     172              :                       HIR::OperatorExprMeta op, TyTy::TyVar result_type)
     173           15 :     : expr_id (expr_id), lang_item_type (lang_item_type),
     174           15 :       specified_segment (specified_segment), op (op), result_type (result_type)
     175           15 :   {}
     176              : 
     177           45 :   DeferredOpOverload (const struct DeferredOpOverload &other)
     178           45 :     : expr_id (other.expr_id), lang_item_type (other.lang_item_type),
     179           45 :       specified_segment (other.specified_segment), op (other.op),
     180           45 :       result_type (other.result_type)
     181           45 :   {}
     182              : 
     183            0 :   DeferredOpOverload &operator= (struct DeferredOpOverload const &other)
     184              :   {
     185            0 :     expr_id = other.expr_id;
     186            0 :     lang_item_type = other.lang_item_type;
     187            0 :     specified_segment = other.specified_segment;
     188            0 :     op = other.op;
     189            0 :     result_type = other.result_type;
     190              : 
     191            0 :     return *this;
     192              :   }
     193              : };
     194              : 
     195              : class TypeCheckContext
     196              : {
     197              : public:
     198              :   static TypeCheckContext *get ();
     199              : 
     200              :   ~TypeCheckContext ();
     201              : 
     202              :   bool lookup_builtin (NodeId id, TyTy::BaseType **type);
     203              :   bool lookup_builtin (std::string name, TyTy::BaseType **type);
     204              :   void insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type);
     205              :   const std::vector<std::unique_ptr<TyTy::BaseType>> &get_builtins () const;
     206              : 
     207              :   void insert_type (const Analysis::NodeMapping &mappings,
     208              :                     TyTy::BaseType *type);
     209              :   bool lookup_type (HirId id, TyTy::BaseType **type) const;
     210              :   void clear_type (TyTy::BaseType *ty);
     211              : 
     212              :   void mark_function_body_pending (DefId id);
     213              :   void clear_function_body_pending (DefId id);
     214              :   bool function_body_pending (DefId id) const;
     215              : 
     216              :   void insert_implicit_type (HirId id, TyTy::BaseType *type);
     217              : 
     218              :   bool
     219              :   lookup_adt_substitution (DefId id,
     220              :                            const TyTy::SubstitutionArgumentMappings &mappings,
     221              :                            TyTy::ADTType **type) const;
     222              :   void
     223              :   insert_adt_substitution (DefId id,
     224              :                            const TyTy::SubstitutionArgumentMappings &mappings,
     225              :                            TyTy::ADTType *type);
     226              : 
     227              :   void insert_type_by_node_id (NodeId ref, HirId id);
     228              :   bool lookup_type_by_node_id (NodeId ref, HirId *id);
     229              : 
     230              :   bool have_function_context () const;
     231              :   TyTy::BaseType *peek_return_type ();
     232              :   TypeCheckContextItem peek_context ();
     233              :   void push_return_type (TypeCheckContextItem item,
     234              :                          TyTy::BaseType *return_type);
     235              :   void pop_return_type ();
     236              : 
     237              :   void push_expected_type (TyTy::BaseType *expected);
     238              :   void pop_expected_type ();
     239              :   TyTy::BaseType *peek_expected_type () const;
     240              : 
     241              :   StackedContexts<TypeCheckBlockContextItem> &block_context ();
     242              : 
     243              :   void iterate (std::function<bool (HirId, TyTy::BaseType *)> cb);
     244              : 
     245              :   bool have_loop_context () const;
     246              :   void push_new_loop_context (HirId id, location_t locus);
     247              :   void push_new_while_loop_context (HirId id);
     248              :   TyTy::BaseType *peek_loop_context ();
     249              :   TyTy::BaseType *pop_loop_context ();
     250              : 
     251              :   void swap_head_loop_context (TyTy::BaseType *val);
     252              : 
     253              :   bool
     254              :   find_matching_impl_trait_frame (const TraitReference &tref,
     255              :                                   TyTy::BaseType &self,
     256              :                                   struct ImplTraitContextFrame *find) const;
     257              :   bool have_impl_trait_context () const;
     258              :   void push_impl_trait_context (struct ImplTraitContextFrame frame);
     259              :   struct ImplTraitContextFrame pop_impl_trait_context ();
     260              :   struct ImplTraitContextFrame peek_impl_trait_context ();
     261              : 
     262              :   void insert_trait_reference (DefId id, TraitReference &&ref);
     263              :   bool lookup_trait_reference (DefId id, TraitReference **ref);
     264              : 
     265              :   bool insert_associated_trait_impl (HirId id,
     266              :                                      AssociatedImplTrait &&associated);
     267              :   bool lookup_associated_trait_impl (HirId id,
     268              :                                      AssociatedImplTrait **associated);
     269              : 
     270              :   void insert_associated_type_mapping (HirId id, HirId mapping);
     271              :   void clear_associated_type_mapping (HirId id);
     272              : 
     273              :   // lookup any associated type mappings, the out parameter of mapping is
     274              :   // allowed to be nullptr which allows this interface to do a simple does exist
     275              :   // check
     276              :   bool lookup_associated_type_mapping (HirId id, HirId *mapping);
     277              : 
     278              :   void insert_associated_impl_mapping (HirId trait_id,
     279              :                                        TyTy::BaseType *impl_type,
     280              :                                        HirId impl_id);
     281              :   bool lookup_associated_impl_mapping_for_self (HirId trait_id,
     282              :                                                 TyTy::BaseType *self,
     283              :                                                 HirId *mapping);
     284              : 
     285              :   void insert_autoderef_mappings (HirId id,
     286              :                                   std::vector<Adjustment> &&adjustments);
     287              :   bool lookup_autoderef_mappings (HirId id,
     288              :                                   std::vector<Adjustment> **adjustments);
     289              : 
     290              :   void insert_cast_autoderef_mappings (HirId id,
     291              :                                        std::vector<Adjustment> &&adjustments);
     292              :   bool lookup_cast_autoderef_mappings (HirId id,
     293              :                                        std::vector<Adjustment> **adjustments);
     294              : 
     295              :   void insert_variant_definition (HirId id, HirId variant);
     296              :   bool lookup_variant_definition (HirId id, HirId *variant);
     297              : 
     298              :   void insert_operator_overload (HirId id, TyTy::FnType *call_site);
     299              :   bool lookup_operator_overload (HirId id, TyTy::FnType **call);
     300              : 
     301              :   void insert_deferred_operator_overload (DeferredOpOverload deferred);
     302              :   bool lookup_deferred_operator_overload (HirId id,
     303              :                                           DeferredOpOverload *deferred);
     304              : 
     305              :   void iterate_deferred_operator_overloads (
     306              :     std::function<bool (HirId, DeferredOpOverload &)> cb);
     307              : 
     308              :   void insert_unconstrained_check_marker (HirId id, bool status);
     309              :   bool have_checked_for_unconstrained (HirId id, bool *result);
     310              : 
     311              :   void insert_resolved_predicate (HirId id,
     312              :                                   const TyTy::TypeBoundPredicate &predicate);
     313              :   bool lookup_predicate (HirId id, TyTy::TypeBoundPredicate *result);
     314              :   std::vector<TyTy::TypeBoundPredicate>
     315              :   predicates_for_type (const TyTy::BaseType *receiver) const;
     316              : 
     317              :   void insert_query (HirId id);
     318              :   void query_completed (HirId id);
     319              :   bool query_in_progress (HirId id) const;
     320              : 
     321              :   void insert_trait_query (DefId id);
     322              :   void trait_query_completed (DefId id);
     323              :   bool trait_query_in_progress (DefId id) const;
     324              : 
     325              :   Lifetime intern_lifetime (const HIR::Lifetime &name);
     326              :   WARN_UNUSED_RESULT tl::optional<Lifetime>
     327              :   lookup_lifetime (const HIR::Lifetime &lifetime) const;
     328              : 
     329              :   WARN_UNUSED_RESULT tl::optional<TyTy::Region>
     330              :   lookup_and_resolve_lifetime (const HIR::Lifetime &lifetime) const;
     331              : 
     332              :   void intern_and_insert_lifetime (const HIR::Lifetime &lifetime);
     333              : 
     334              :   WARN_UNUSED_RESULT std::vector<TyTy::Region>
     335              :   regions_from_generic_args (const HIR::GenericArgs &args) const;
     336              : 
     337              :   void compute_inference_variables (bool emit_error);
     338              : 
     339              :   TyTy::VarianceAnalysis::CrateCtx &get_variance_analysis_ctx ();
     340              : 
     341         1770 :   void push_const_context (void) { const_context++; }
     342         1769 :   void pop_const_context (void)
     343              :   {
     344         1769 :     if (const_context > 0)
     345         1769 :       const_context--;
     346              :   }
     347         2656 :   bool const_context_p (void) { return (const_context > 0); }
     348              : 
     349              : private:
     350              :   TypeCheckContext ();
     351              : 
     352              :   bool compute_infer_var (HirId id, TyTy::BaseType *ty, bool emit_error);
     353              :   bool compute_ambigious_op_overload (HirId id, DeferredOpOverload &op);
     354              : 
     355              :   std::map<NodeId, HirId> node_id_refs;
     356              :   std::map<HirId, TyTy::BaseType *> resolved;
     357              :   std::map<std::pair<DefId, std::vector<HirId>>, TyTy::ADTType *>
     358              :     adt_substitutions;
     359              :   std::set<DefId> function_bodies_pending;
     360              :   std::vector<std::unique_ptr<TyTy::BaseType>> builtins;
     361              :   std::vector<std::pair<TypeCheckContextItem, TyTy::BaseType *>>
     362              :     return_type_stack;
     363              :   std::vector<TyTy::BaseType *> expected_type_stack;
     364              :   std::vector<TyTy::BaseType *> loop_type_stack;
     365              :   StackedContexts<TypeCheckBlockContextItem> block_stack;
     366              :   std::map<DefId, TraitReference> trait_context;
     367              :   std::map<HirId, AssociatedImplTrait> associated_impl_traits;
     368              :   std::vector<ImplTraitContextFrame> impl_trait_frame_stack;
     369              : 
     370              :   // trait-id -> list of < self-tyty:impl-id>
     371              :   std::map<HirId, std::vector<std::pair<TyTy::BaseType *, HirId>>>
     372              :     associated_traits_to_impls;
     373              : 
     374              :   std::map<HirId, HirId> associated_type_mappings;
     375              : 
     376              :   // adjustment mappings
     377              :   std::map<HirId, std::vector<Adjustment>> autoderef_mappings;
     378              :   std::map<HirId, std::vector<Adjustment>> cast_autoderef_mappings;
     379              : 
     380              :   // operator overloads
     381              :   std::map<HirId, TyTy::FnType *> operator_overloads;
     382              : 
     383              :   // variants
     384              :   std::map<HirId, HirId> variants;
     385              : 
     386              :   // unconstrained type-params check
     387              :   std::map<HirId, bool> unconstrained;
     388              : 
     389              :   // predicates
     390              :   std::map<HirId, TyTy::TypeBoundPredicate> predicates;
     391              : 
     392              :   // query context lookups
     393              :   std::set<HirId> querys_in_progress;
     394              :   std::set<DefId> trait_queries_in_progress;
     395              : 
     396              :   // deferred operator overload
     397              :   std::map<HirId, DeferredOpOverload> deferred_operator_overloads;
     398              : 
     399              :   // variance analysis
     400              :   TyTy::VarianceAnalysis::CrateCtx variance_analysis_ctx;
     401              : 
     402              :   unsigned int const_context = 0;
     403              : 
     404              :   /** Used to resolve (interned) lifetime names to their bounding scope. */
     405       153031 :   class LifetimeResolver
     406              :   {
     407              :     /**
     408              :      * The level of nested scopes, where the lifetime was declared.
     409              :      *
     410              :      * Index 0 is used for `impl` blocks and is skipped if not explicitly
     411              :      * requested.
     412              :      * Index 1 for the top-level of declarations of items.
     413              :      * Index >1 is used for late-bound lifetimes.
     414              :      */
     415              :     using ScopeIndex = size_t;
     416              : 
     417              :     static constexpr ScopeIndex IMPL_SCOPE = 0;
     418              :     static constexpr ScopeIndex ITEM_SCOPE = 1;
     419              : 
     420              :     /**
     421              :      * A reference to a lifetime binder.
     422              :      *
     423              :      * This is used to resolve lifetimes to their scope.
     424              :      */
     425              :     struct LifetimeBinderRef
     426              :     {
     427              :       uint32_t scope; //> Depth of the scope where the lifetime was declared.
     428              :       uint32_t index; //> Index of the lifetime in the scope.
     429              :     };
     430              : 
     431              :     /**
     432              :      * A stack of the number of lifetimes declared in each scope.
     433              :      *
     434              :      * Used to pop the correct number of lifetimes when leaving a scope.
     435              :      */
     436              :     std::stack<uint32_t> binder_size_stack;
     437              : 
     438              :     /**
     439              :      * Merged stack of all lifetimes declared in all scopes.
     440              :      *
     441              :      * Use `binder_size_stack` to determine the number of lifetimes in each
     442              :      * scope.
     443              :      */
     444              :     std::vector<std::pair<Lifetime, LifetimeBinderRef>> lifetime_lookup;
     445              : 
     446              :     /**
     447              :      * Whether the current scope is a function body.
     448              :      *
     449              :      * In function header, lifetimes are resolved as early-bound, in the body as
     450              :      * named. This is because the header can be also used in call position.
     451              :      */
     452              :     bool is_body = false;
     453              : 
     454              :     /** Return the number of the current scope. */
     455          970 :     WARN_UNUSED_RESULT uint32_t get_current_scope () const
     456              :     {
     457         1910 :       return binder_size_stack.size () - 1;
     458              :     }
     459              : 
     460              :   public:
     461              :     /** Add new declaration of a lifetime. */
     462          940 :     void insert_mapping (Lifetime placeholder)
     463              :     {
     464          940 :       lifetime_lookup.push_back (
     465          940 :         {placeholder, {get_current_scope (), binder_size_stack.top ()++}});
     466          940 :     }
     467              : 
     468              :     WARN_UNUSED_RESULT tl::optional<TyTy::Region>
     469              :     resolve (const Lifetime &placeholder) const;
     470              : 
     471              :     /** Only to be used by the guard. */
     472       102272 :     void push_binder () { binder_size_stack.push (0); }
     473              :     /** Only to be used by the guard. */
     474        70593 :     void pop_binder () { binder_size_stack.pop (); }
     475              : 
     476        76302 :     bool binder_empty () { return binder_size_stack.empty (); }
     477              : 
     478              :     /**
     479              :      * Switch from resolving a function header to a function body.
     480              :      */
     481         7065 :     void switch_to_fn_body () { this->is_body = true; }
     482              : 
     483        23924 :     size_t get_num_bound_regions () const { return binder_size_stack.top (); }
     484              :   };
     485              : 
     486              :   // lifetime resolving
     487              :   std::unordered_map<std::string, Lifetime> lifetime_name_interner;
     488              :   Lifetime next_lifetime_index = Lifetime (Lifetime::FIRST_NAMED_LIFETIME);
     489              : 
     490              :   /**
     491              :    * Stack of lifetime resolvers.
     492              :    *
     493              :    * Due to the contruction of the type checker, it is possible to start
     494              :    * resolution of a new type in the middle of resolving another type. This
     495              :    * stack isolates the conexts in such cases.
     496              :    */
     497              :   std::stack<LifetimeResolver> lifetime_resolver_stack;
     498              : 
     499              : public:
     500        24864 :   WARN_UNUSED_RESULT LifetimeResolver &get_lifetime_resolver ()
     501              :   {
     502        24864 :     rust_assert (!lifetime_resolver_stack.empty ());
     503        24864 :     return lifetime_resolver_stack.top ();
     504              :   }
     505              : 
     506         9889 :   WARN_UNUSED_RESULT const LifetimeResolver &get_lifetime_resolver () const
     507              :   {
     508         9889 :     rust_assert (!lifetime_resolver_stack.empty ());
     509         9889 :     return lifetime_resolver_stack.top ();
     510              :   }
     511              : 
     512              :   /**
     513              :    * A guard that pushes a new lifetime resolver on the stack and pops it
     514              :    * when it goes out of scope.
     515              :    */
     516              :   class LifetimeResolverGuard
     517              :   {
     518              :   public:
     519              :     /** The kind of scope that is being pushed. */
     520              :     enum ScopeKind
     521              :     {
     522              :       IMPL_BLOCK_RESOLVER, //> A new `impl` block scope.
     523              :       RESOLVER,            //> A new scope for a function body.
     524              :       BINDER,              //> A new scope for late-bound lifetimes.
     525              :     };
     526              : 
     527              :   private:
     528              :     TypeCheckContext &ctx;
     529              :     ScopeKind kind;
     530              : 
     531              :   public:
     532        76303 :     LifetimeResolverGuard (TypeCheckContext &ctx, ScopeKind kind)
     533        76303 :       : ctx (ctx), kind (kind)
     534              :     {
     535        76303 :       if (kind == IMPL_BLOCK_RESOLVER)
     536              :         {
     537        70078 :           ctx.lifetime_resolver_stack.push (LifetimeResolver ());
     538              :         }
     539              : 
     540        76303 :       if (kind == RESOLVER)
     541              :         {
     542        25969 :           ctx.lifetime_resolver_stack.push (LifetimeResolver ());
     543              :           // Skip the `impl` block scope.
     544        25969 :           ctx.lifetime_resolver_stack.top ().push_binder ();
     545              :         }
     546        76303 :       rust_assert (!ctx.lifetime_resolver_stack.empty ());
     547        76303 :       ctx.lifetime_resolver_stack.top ().push_binder ();
     548        76303 :     }
     549              : 
     550        76302 :     ~LifetimeResolverGuard ()
     551              :     {
     552        76302 :       rust_assert (!ctx.lifetime_resolver_stack.empty ());
     553        76302 :       if (!ctx.lifetime_resolver_stack.top ().binder_empty ())
     554        70593 :         ctx.lifetime_resolver_stack.top ().pop_binder ();
     555        76302 :       if (kind == RESOLVER)
     556              :         {
     557        25969 :           ctx.lifetime_resolver_stack.pop ();
     558              :         }
     559        76302 :     }
     560              :   };
     561              : 
     562              :   /** Start new late bound lifetime scope. */
     563        15278 :   WARN_UNUSED_RESULT LifetimeResolverGuard push_lifetime_binder ()
     564              :   {
     565        15278 :     return LifetimeResolverGuard (*this, LifetimeResolverGuard::BINDER);
     566              :   }
     567              : 
     568              :   /** Start new function body scope. */
     569              :   WARN_UNUSED_RESULT LifetimeResolverGuard
     570        61008 :   push_clean_lifetime_resolver (bool is_impl_block = false)
     571              :   {
     572        61008 :     return LifetimeResolverGuard (*this,
     573              :                                   is_impl_block
     574              :                                     ? LifetimeResolverGuard::IMPL_BLOCK_RESOLVER
     575        61008 :                                     : LifetimeResolverGuard::RESOLVER);
     576              :   }
     577              : 
     578              :   /** Switch from resolving a function header to a function body. */
     579         7065 :   void switch_to_fn_body ()
     580              :   {
     581         7065 :     this->lifetime_resolver_stack.top ().switch_to_fn_body ();
     582              :   }
     583              : };
     584              : 
     585              : class TypeResolution
     586              : {
     587              : public:
     588              :   static void Resolve (HIR::Crate &crate);
     589              : };
     590              : 
     591              : class TraitQueryGuard
     592              : {
     593              : public:
     594         4257 :   TraitQueryGuard (DefId id) : id (id), ctx (*TypeCheckContext::get ())
     595              :   {
     596         4257 :     ctx.insert_trait_query (id);
     597         4257 :   }
     598              : 
     599         4257 :   ~TraitQueryGuard () { ctx.trait_query_completed (id); }
     600              : 
     601              : private:
     602              :   DefId id;
     603              :   TypeCheckContext &ctx;
     604              : };
     605              : 
     606              : template <typename T> class ScopedPush
     607              : {
     608              : public:
     609      2155835 :   ScopedPush (std::vector<T> &stack, T value, bool enabled = true)
     610      2155835 :     : stack (stack), enabled (enabled)
     611              :   {
     612        48675 :     if (enabled)
     613      2155835 :       stack.push_back (value);
     614              :   }
     615              : 
     616      2155835 :   ~ScopedPush ()
     617              :   {
     618        48675 :     if (enabled)
     619      2155835 :       stack.pop_back ();
     620              :   }
     621              : 
     622      3358706 :   static bool contains (const std::vector<T> &stack, const T &value)
     623              :   {
     624      6668695 :     return std::find (stack.begin (), stack.end (), value) != stack.end ();
     625              :   }
     626              : 
     627              : private:
     628              :   std::vector<T> &stack;
     629              :   bool enabled;
     630              : };
     631              : 
     632              : class ImplTraitFrameGuard
     633              : {
     634              : public:
     635        13554 :   ImplTraitFrameGuard (ImplTraitContextFrame frame)
     636        13554 :     : ctx (*TypeCheckContext::get ())
     637              :   {
     638        13554 :     ctx.push_impl_trait_context (frame);
     639        13554 :   }
     640              : 
     641        13554 :   ~ImplTraitFrameGuard () { ctx.pop_impl_trait_context (); }
     642              : 
     643              : private:
     644              :   Resolver::TypeCheckContext &ctx;
     645              : };
     646              : 
     647              : } // namespace Resolver
     648              : } // namespace Rust
     649              : 
     650              : #endif // RUST_HIR_TYPE_CHECK
        

Generated by: LCOV version 2.5.0-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.