LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-tyty.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 84.5 % 252 213
Test Date: 2026-04-20 14:57:17 Functions: 75.3 % 81 61
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_TYTY
      20              : #define RUST_TYTY
      21              : 
      22              : #include "optional.h"
      23              : #include "rust-hir-map.h"
      24              : #include "rust-common.h"
      25              : #include "rust-identifier.h"
      26              : #include "rust-abi.h"
      27              : #include "rust-tyty-util.h"
      28              : #include "rust-tyty-subst.h"
      29              : #include "rust-tyty-region.h"
      30              : #include "rust-system.h"
      31              : #include "rust-hir.h"
      32              : #include "tree.h"
      33              : 
      34              : namespace Rust {
      35              : 
      36              : namespace Resolver {
      37              : class TraitReference;
      38              : 
      39              : class TraitItemReference;
      40              : 
      41              : class AssociatedImplTrait;
      42              : } // namespace Resolver
      43              : 
      44              : namespace TyTy {
      45              : class ClosureType;
      46              : class FnPtr;
      47              : class FnType;
      48              : class CallableTypeInterface;
      49              : 
      50              : // https://rustc-dev-guide.rust-lang.org/type-inference.html#inference-variables
      51              : // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variants
      52              : enum TypeKind
      53              : {
      54              :   INFER,
      55              :   ADT,
      56              :   STR,
      57              :   REF,
      58              :   POINTER,
      59              :   PARAM,
      60              :   CONST,
      61              :   ARRAY,
      62              :   SLICE,
      63              :   FNDEF,
      64              :   FNPTR,
      65              :   TUPLE,
      66              :   BOOL,
      67              :   CHAR,
      68              :   INT,
      69              :   UINT,
      70              :   FLOAT,
      71              :   USIZE,
      72              :   ISIZE,
      73              :   NEVER,
      74              :   PLACEHOLDER,
      75              :   PROJECTION,
      76              :   DYNAMIC,
      77              :   CLOSURE,
      78              :   OPAQUE,
      79              :   // there are more to add...
      80              :   ERROR
      81              : };
      82              : 
      83              : extern bool is_primitive_type_kind (TypeKind kind);
      84              : 
      85              : class TypeKindFormat
      86              : {
      87              : public:
      88              :   static std::string to_string (TypeKind kind);
      89              : };
      90              : 
      91              : class TyVisitor;
      92              : class TyConstVisitor;
      93              : class BaseConstType;
      94              : 
      95              : class TypeBoundPredicate : public SubstitutionRef
      96              : {
      97              : public:
      98              :   TypeBoundPredicate (const Resolver::TraitReference &trait_reference,
      99              :                       BoundPolarity polarity, location_t locus);
     100              : 
     101              :   TypeBoundPredicate (DefId reference,
     102              :                       std::vector<SubstitutionParamMapping> substitutions,
     103              :                       BoundPolarity polarity, location_t locus);
     104              : 
     105              :   TypeBoundPredicate (const TypeBoundPredicate &other);
     106              : 
     107     59337184 :   virtual ~TypeBoundPredicate () {}
     108              : 
     109              :   TypeBoundPredicate &operator= (const TypeBoundPredicate &other);
     110              : 
     111              :   static TypeBoundPredicate error ();
     112              : 
     113              :   std::string as_string () const;
     114              : 
     115              :   std::string as_name () const;
     116              : 
     117              :   const Resolver::TraitReference *get () const;
     118              : 
     119        26738 :   location_t get_locus () const { return locus; }
     120              : 
     121              :   std::string get_name () const;
     122              : 
     123              :   // check that this  is object-safe see:
     124              :   // https://doc.rust-lang.org/reference/items/traits.html#object-safety
     125              :   bool is_object_safe (bool emit_error, location_t locus) const;
     126              : 
     127              :   void apply_generic_arguments (HIR::GenericArgs *generic_args,
     128              :                                 bool has_associated_self, bool is_super_trait);
     129              : 
     130              :   void apply_argument_mappings (SubstitutionArgumentMappings &arguments,
     131              :                                 bool is_super_trait);
     132              : 
     133              :   bool contains_item (const std::string &search) const;
     134              : 
     135              :   tl::optional<TypeBoundPredicateItem>
     136              :   lookup_associated_item (const std::string &search) const;
     137              : 
     138              :   tl::optional<TypeBoundPredicateItem>
     139              :   lookup_associated_item (const Resolver::TraitItemReference *ref) const;
     140              : 
     141              :   // WARNING THIS WILL ALWAYS RETURN NULLPTR
     142              :   BaseType *
     143              :   handle_substitions (SubstitutionArgumentMappings &mappings) override final;
     144              : 
     145              :   bool is_error () const;
     146              : 
     147              :   bool requires_generic_args () const;
     148              : 
     149              :   bool contains_associated_types () const;
     150              : 
     151        52026 :   DefId get_id () const { return reference; }
     152              : 
     153        13294 :   BoundPolarity get_polarity () const { return polarity; }
     154              : 
     155              :   std::vector<TypeBoundPredicateItem> get_associated_type_items ();
     156              : 
     157              :   size_t get_num_associated_bindings () const override final;
     158              : 
     159              :   TypeBoundPredicateItem
     160              :   lookup_associated_type (const std::string &search) override final;
     161              : 
     162              :   bool is_equal (const TypeBoundPredicate &other) const;
     163              : 
     164              :   bool validate_type_implements_super_traits (TyTy::BaseType &self,
     165              :                                               HIR::Type &impl_type,
     166              :                                               HIR::Type &trait) const;
     167              : 
     168              :   bool validate_type_implements_this (TyTy::BaseType &self,
     169              :                                       HIR::Type &impl_type,
     170              :                                       HIR::Type &trait) const;
     171              : 
     172              : private:
     173              :   struct mark_is_error
     174              :   {
     175              :   };
     176              : 
     177              :   TypeBoundPredicate (mark_is_error);
     178              : 
     179              :   void get_trait_hierachy (
     180              :     std::function<void (const Resolver::TraitReference &)> callback) const;
     181              : 
     182              :   DefId reference;
     183              :   location_t locus;
     184              :   bool error_flag;
     185              :   BoundPolarity polarity;
     186              :   std::vector<TyTy::TypeBoundPredicate> super_traits;
     187              : };
     188              : 
     189        96068 : class TypeBoundsMappings
     190              : {
     191              : protected:
     192              :   TypeBoundsMappings (std::vector<TypeBoundPredicate> specified_bounds);
     193              : 
     194              : public:
     195              :   std::vector<TypeBoundPredicate> &get_specified_bounds ();
     196              : 
     197              :   const std::vector<TypeBoundPredicate> &get_specified_bounds () const;
     198              : 
     199              :   TypeBoundPredicate lookup_predicate (DefId id);
     200              : 
     201              :   size_t num_specified_bounds () const;
     202              : 
     203              :   std::string raw_bounds_as_string () const;
     204              : 
     205              :   std::string bounds_as_string () const;
     206              : 
     207              :   std::string raw_bounds_as_name () const;
     208              : 
     209              : protected:
     210              :   void add_bound (TypeBoundPredicate predicate);
     211              : 
     212              :   std::vector<TypeBoundPredicate> specified_bounds;
     213              : };
     214              : 
     215              : class BaseType : public TypeBoundsMappings
     216              : {
     217              : public:
     218              :   virtual ~BaseType ();
     219              : 
     220              :   HirId get_ref () const;
     221              :   void set_ref (HirId id);
     222              : 
     223              :   HirId get_ty_ref () const;
     224              :   void set_ty_ref (HirId id);
     225              : 
     226              :   HirId get_orig_ref () const;
     227              : 
     228              :   virtual void accept_vis (TyVisitor &vis) = 0;
     229              :   virtual void accept_vis (TyConstVisitor &vis) const = 0;
     230              : 
     231              :   virtual std::string as_string () const = 0;
     232              :   virtual std::string get_name () const = 0;
     233              : 
     234              :   // Check value equality between two ty. Type inference rules are ignored. Two
     235              :   //   ty are considered equal if they're of the same kind, and
     236              :   //     1. (For ADTs, arrays, tuples, refs) have the same underlying ty
     237              :   //     2. (For functions) have the same signature
     238              :   virtual bool is_equal (const BaseType &other) const;
     239              : 
     240              :   bool satisfies_bound (const TypeBoundPredicate &predicate, bool emit_error);
     241              : 
     242              :   bool bounds_compatible (BaseType &other, location_t locus, bool emit_error);
     243              : 
     244              :   void inherit_bounds (const BaseType &other);
     245              : 
     246              :   void inherit_bounds (
     247              :     const std::vector<TyTy::TypeBoundPredicate> &specified_bounds);
     248              : 
     249              :   // contains_infer checks if there is an inference variable inside the type
     250              :   const TyTy::BaseType *contains_infer () const;
     251              : 
     252              :   // is_unit returns whether this is just a unit-struct
     253              :   bool is_unit () const;
     254              : 
     255              :   // is_concrete returns true if the type is fully resolved to concrete
     256              :   // primitives
     257              :   bool is_concrete () const;
     258              : 
     259              :   // return the type-kind
     260              :   TypeKind get_kind () const;
     261              : 
     262              :   // monomorphized clone is a clone which destructures the types to get rid of
     263              :   // generics
     264              :   BaseType *monomorphized_clone () const;
     265              : 
     266              :   // get_combined_refs returns the chain of node refs involved in unification
     267              :   std::set<HirId> get_combined_refs () const;
     268              : 
     269              :   void append_reference (HirId id);
     270              : 
     271              :   std::string mappings_str () const;
     272              : 
     273              :   std::string debug_str () const;
     274              : 
     275              :   void debug () const;
     276              : 
     277              :   BaseType *get_root ();
     278              : 
     279              :   // This will get the monomorphized type from Params, Placeholders or
     280              :   // Projections if available or error
     281              :   BaseType *destructure ();
     282              :   const BaseType *destructure () const;
     283              : 
     284              :   const RustIdent &get_ident () const;
     285              :   location_t get_locus () const;
     286              : 
     287              :   bool has_substitutions_defined () const;
     288              :   bool needs_generic_substitutions () const;
     289              :   const SubstitutionArgumentMappings &get_subst_argument_mappings () const;
     290              : 
     291        31285 :   std::string mangle_string () const
     292              :   {
     293        93855 :     return TypeKindFormat::to_string (get_kind ()) + ":" + as_string () + ":"
     294       125140 :            + mappings_str () + ":" + bounds_as_string ();
     295              :   }
     296              : 
     297              :   /* Returns a pointer to a clone of this. The caller is responsible for
     298              :    * releasing the memory of the returned ty. */
     299              :   virtual BaseType *clone () const = 0;
     300              : 
     301              :   // Check if TyTy::BaseType is of a specific type.
     302    136426316 :   template <typename T> WARN_UNUSED_RESULT bool is () const
     303              :   {
     304              :     static_assert (std::is_base_of<BaseType, T>::value,
     305              :                    "Can only safely cast to TyTy types.");
     306     42707562 :     return this->get_kind () == T::KIND;
     307              :   }
     308              : 
     309       809252 :   template <typename T> T *as () const
     310              :   {
     311              :     static_assert (std::is_base_of<BaseType, T>::value,
     312              :                    "Can only safely cast to TyTy types.");
     313       809252 :     rust_assert (this->is<T> ());
     314       809252 :     return static_cast<T *> (this);
     315              :   }
     316              : 
     317        50438 :   template <typename T> T *as ()
     318              :   {
     319              :     static_assert (std::is_base_of<BaseType, T>::value,
     320              :                    "Can only safely cast to TyTy types.");
     321        50438 :     rust_assert (this->is<T> ());
     322        50438 :     return static_cast<T *> (this);
     323              :   }
     324              : 
     325              :   // Check if TyTy::BaseType is of a specific type and convert it to that type
     326              :   // if so.
     327              :   // Returns nullptr otherwise. Works as a dynamic_cast, but without compiler
     328              :   // RTTI.
     329     77133463 :   template <typename T> T *try_as () const
     330              :   {
     331              :     static_assert (std::is_base_of<BaseType, T>::value,
     332              :                    "Can only safely cast to TyTy types.");
     333     77133463 :     if (!this->is<T> ())
     334              :       return nullptr;
     335              : 
     336              :     return static_cast<T *> (this);
     337              :   }
     338              : 
     339              :   // See above.
     340     15829338 :   template <typename T> T *try_as ()
     341              :   {
     342              :     static_assert (std::is_base_of<BaseType, T>::value,
     343              :                    "Can only safely cast to TyTy types.");
     344     15829338 :     if (!this->is<T> ())
     345            0 :       return nullptr;
     346              : 
     347              :     return static_cast<T *> (this);
     348              :   }
     349              : 
     350              :   // Helper to get BaseConstType interface for CONST types
     351              :   // Overridden by const types that also inherit from BaseConstType
     352            0 :   virtual BaseConstType *as_const_type () { return nullptr; }
     353            0 :   virtual const BaseConstType *as_const_type () const { return nullptr; }
     354              : 
     355              : protected:
     356              :   BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
     357              :             std::set<HirId> refs = std::set<HirId> ());
     358              : 
     359              :   BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
     360              :             std::vector<TypeBoundPredicate> specified_bounds,
     361              :             std::set<HirId> refs = std::set<HirId> ());
     362              : 
     363              :   TypeKind kind;
     364              :   HirId ref;
     365              :   HirId ty_ref;
     366              :   const HirId orig_ref;
     367              :   std::set<HirId> combined;
     368              :   RustIdent ident;
     369              : 
     370              :   Analysis::Mappings &mappings;
     371              : };
     372              : 
     373              : /** Unified interface for all function-like types. */
     374              : class CallableTypeInterface : public BaseType
     375              : {
     376              : public:
     377        56017 :   explicit CallableTypeInterface (HirId ref, HirId ty_ref, TypeKind kind,
     378              :                                   RustIdent ident,
     379              :                                   std::set<HirId> refs = std::set<HirId> ())
     380        56017 :     : BaseType (ref, ty_ref, kind, ident, refs)
     381        56017 :   {}
     382              : 
     383              :   WARN_UNUSED_RESULT virtual size_t get_num_params () const = 0;
     384              :   WARN_UNUSED_RESULT virtual BaseType *get_param_type_at (size_t index) const
     385              :     = 0;
     386              :   WARN_UNUSED_RESULT virtual BaseType *get_return_type () const = 0;
     387              : };
     388              : 
     389              : class InferType : public BaseType
     390              : {
     391              : public:
     392              :   static constexpr auto KIND = TypeKind::INFER;
     393              : 
     394              :   enum InferTypeKind
     395              :   {
     396              :     GENERAL,
     397              :     INTEGRAL,
     398              :     FLOAT
     399              :   };
     400              : 
     401              :   struct TypeHint
     402              :   {
     403              :     enum SignedHint
     404              :     {
     405              :       SIGNED,
     406              :       UNSIGNED,
     407              : 
     408              :       UNKNOWN
     409              :     };
     410              :     enum SizeHint
     411              :     {
     412              :       S8,
     413              :       S16,
     414              :       S32,
     415              :       S64,
     416              :       S128,
     417              :       SUNKNOWN
     418              :     };
     419              : 
     420              :     TyTy::TypeKind kind;
     421              :     SignedHint shint;
     422              :     SizeHint szhint;
     423              : 
     424              :     static TypeHint Default ()
     425              :     {
     426              :       return TypeHint{TypeKind::ERROR, UNKNOWN, SUNKNOWN};
     427              :     }
     428              :   };
     429              : 
     430              :   InferType (HirId ref, InferTypeKind infer_kind, TypeHint hint,
     431              :              location_t locus, std::set<HirId> refs = std::set<HirId> ());
     432              : 
     433              :   InferType (HirId ref, HirId ty_ref, InferTypeKind infer_kind, TypeHint hint,
     434              :              location_t locus, std::set<HirId> refs = std::set<HirId> ());
     435              : 
     436              :   void accept_vis (TyVisitor &vis) override;
     437              : 
     438              :   void accept_vis (TyConstVisitor &vis) const override;
     439              : 
     440              :   std::string as_string () const override;
     441              : 
     442              :   BaseType *clone () const final override;
     443              : 
     444              :   InferTypeKind get_infer_kind () const;
     445              : 
     446              :   std::string get_name () const override final;
     447              : 
     448              :   bool default_type (BaseType **type) const;
     449              : 
     450              :   void apply_primitive_type_hint (const TyTy::BaseType &hint);
     451              : 
     452              : private:
     453              :   InferTypeKind infer_kind;
     454              :   TypeHint default_hint;
     455              : };
     456              : 
     457              : class ErrorType : public BaseType
     458              : {
     459              : public:
     460              :   static constexpr auto KIND = TypeKind::ERROR;
     461              : 
     462              :   ErrorType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
     463              : 
     464              :   ErrorType (HirId ref, HirId ty_ref,
     465              :              std::set<HirId> refs = std::set<HirId> ());
     466              : 
     467              :   void accept_vis (TyVisitor &vis) override;
     468              :   void accept_vis (TyConstVisitor &vis) const override;
     469              : 
     470              :   std::string as_string () const override;
     471              : 
     472              :   BaseType *clone () const final override;
     473              : 
     474              :   std::string get_name () const override final;
     475              : };
     476              : 
     477              : class BaseGeneric : public BaseType
     478              : {
     479              : public:
     480              :   virtual std::string get_symbol () const = 0;
     481              : 
     482              :   virtual bool can_resolve () const = 0;
     483              : 
     484              :   virtual BaseType *resolve () const = 0;
     485              : 
     486              : protected:
     487     85902804 :   BaseGeneric (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
     488              :                std::vector<TypeBoundPredicate> specified_bounds,
     489              :                std::set<HirId> refs = std::set<HirId> ())
     490     85902804 :     : BaseType (ref, ty_ref, kind, ident, specified_bounds, refs)
     491     85902804 :   {}
     492              : };
     493              : 
     494              : class ParamType : public BaseGeneric
     495              : {
     496              : public:
     497              :   static constexpr auto KIND = TypeKind::PARAM;
     498              : 
     499              :   ParamType (std::string symbol, location_t locus, HirId ref,
     500              :              std::vector<TypeBoundPredicate> specified_bounds,
     501              :              std::set<HirId> refs = std::set<HirId> ());
     502              : 
     503              :   ParamType (bool is_trait_self, std::string symbol, location_t locus,
     504              :              HirId ref, HirId ty_ref,
     505              :              std::vector<TypeBoundPredicate> specified_bounds,
     506              :              std::set<HirId> refs = std::set<HirId> ());
     507              : 
     508              :   void accept_vis (TyVisitor &vis) override;
     509              :   void accept_vis (TyConstVisitor &vis) const override;
     510              : 
     511              :   std::string as_string () const override;
     512              : 
     513              :   BaseType *clone () const final override;
     514              : 
     515              :   std::string get_symbol () const override final;
     516              : 
     517              :   bool can_resolve () const override final;
     518              : 
     519              :   BaseType *resolve () const override final;
     520              : 
     521              :   std::string get_name () const override final;
     522              : 
     523              :   bool is_equal (const BaseType &other) const override;
     524              : 
     525              :   ParamType *handle_substitions (SubstitutionArgumentMappings &mappings);
     526              : 
     527              :   void set_implicit_self_trait ();
     528              :   bool is_implicit_self_trait () const;
     529              : 
     530              : private:
     531              :   bool is_trait_self;
     532              :   std::string symbol;
     533              : };
     534              : 
     535         3326 : class BaseConstType
     536              : {
     537              : public:
     538              :   static constexpr auto KIND = TypeKind::CONST;
     539              : 
     540              :   enum ConstKind
     541              :   {
     542              :     Decl,
     543              :     Value,
     544              :     Infer,
     545              :     Error
     546              :   };
     547              : 
     548              :   virtual ConstKind const_kind () const = 0;
     549              : 
     550         2013 :   BaseType *get_specified_type () const { return specified_type; }
     551              : 
     552              :   // Helper to get BaseType interface (all const types also inherit BaseType)
     553              :   // This must be implemented by concrete classes since BaseConstType doesn't
     554              :   // inherit from BaseType, but all concrete const types do.
     555              :   virtual BaseType *as_base_type () = 0;
     556              :   virtual const BaseType *as_base_type () const = 0;
     557              : 
     558              : protected:
     559          813 :   BaseConstType (BaseType *type) : specified_type (type) {}
     560              : 
     561              :   BaseType *specified_type;
     562              : };
     563              : 
     564              : class ConstParamType : public BaseConstType, public BaseGeneric
     565              : {
     566              : public:
     567              :   ConstParamType (std::string symbol, location_t locus, BaseType *type,
     568              :                   HirId ref, HirId ty_ref,
     569              :                   std::set<HirId> refs = std::set<HirId> ());
     570              : 
     571              :   ConstKind const_kind () const override final;
     572              : 
     573              :   std::string get_symbol () const override final;
     574              : 
     575              :   bool can_resolve () const override final;
     576              : 
     577              :   BaseType *resolve () const override final;
     578              : 
     579              :   void accept_vis (TyVisitor &vis) override;
     580              :   void accept_vis (TyConstVisitor &vis) const override;
     581              : 
     582              :   std::string as_string () const override;
     583              : 
     584              :   BaseType *clone () const final override;
     585              :   std::string get_name () const override final;
     586              : 
     587              :   bool is_equal (const BaseType &other) const override;
     588              : 
     589              :   BaseType *handle_substitions (SubstitutionArgumentMappings &mappings);
     590              : 
     591          117 :   BaseType *as_base_type () override { return static_cast<BaseType *> (this); }
     592         2649 :   const BaseType *as_base_type () const override
     593              :   {
     594         2649 :     return static_cast<const BaseType *> (this);
     595              :   }
     596              : 
     597         2254 :   BaseConstType *as_const_type () override { return this; }
     598         2473 :   const BaseConstType *as_const_type () const override { return this; }
     599              : 
     600              : private:
     601              :   std::string symbol;
     602              : };
     603              : 
     604         3326 : class ConstValueType : public BaseType, public BaseConstType
     605              : {
     606              : public:
     607              :   static constexpr auto KIND = TypeKind::CONST;
     608              : 
     609              :   ConstValueType (tree value, BaseType *type, HirId ref, HirId ty_ref,
     610              :                   std::set<HirId> refs = std::set<HirId> ());
     611              : 
     612              :   ConstKind const_kind () const override final;
     613              : 
     614              :   void accept_vis (TyVisitor &vis) override;
     615              :   void accept_vis (TyConstVisitor &vis) const override;
     616              : 
     617              :   std::string as_string () const override;
     618              : 
     619              :   BaseType *clone () const final override;
     620              :   std::string get_name () const override final;
     621              : 
     622              :   bool is_equal (const BaseType &other) const override;
     623              : 
     624              :   tree get_value () const;
     625              : 
     626         5460 :   BaseType *as_base_type () override { return static_cast<BaseType *> (this); }
     627            0 :   const BaseType *as_base_type () const override
     628              :   {
     629            0 :     return static_cast<const BaseType *> (this);
     630              :   }
     631              : 
     632        26428 :   BaseConstType *as_const_type () override { return this; }
     633        36462 :   const BaseConstType *as_const_type () const override { return this; }
     634              : 
     635              : private:
     636              :   tree folded_val;
     637              : };
     638              : 
     639              : class ConstInferType : public BaseType, public BaseConstType
     640              : {
     641              : public:
     642              :   static constexpr auto KIND = TypeKind::CONST;
     643              : 
     644              :   ConstInferType (BaseType *type, HirId ref, HirId ty_ref,
     645              :                   std::set<HirId> refs = std::set<HirId> ());
     646              : 
     647              :   ConstKind const_kind () const override final;
     648              : 
     649              :   void accept_vis (TyVisitor &vis) override;
     650              :   void accept_vis (TyConstVisitor &vis) const override;
     651              : 
     652              :   std::string as_string () const override;
     653              : 
     654              :   BaseType *clone () const final override;
     655              :   std::string get_name () const override final;
     656              : 
     657              :   bool is_equal (const BaseType &other) const override;
     658              : 
     659           10 :   BaseType *as_base_type () override { return static_cast<BaseType *> (this); }
     660            0 :   const BaseType *as_base_type () const override
     661              :   {
     662            0 :     return static_cast<const BaseType *> (this);
     663              :   }
     664              : 
     665          603 :   BaseConstType *as_const_type () override { return this; }
     666           62 :   const BaseConstType *as_const_type () const override { return this; }
     667              : };
     668              : 
     669              : class ConstErrorType : public BaseType, public BaseConstType
     670              : {
     671              : public:
     672              :   static constexpr auto KIND = TypeKind::CONST;
     673              : 
     674              :   ConstErrorType (BaseType *type, HirId ref, HirId ty_ref,
     675              :                   std::set<HirId> refs = std::set<HirId> ());
     676              : 
     677              :   ConstKind const_kind () const override final;
     678              : 
     679              :   void accept_vis (TyVisitor &vis) override;
     680              :   void accept_vis (TyConstVisitor &vis) const override;
     681              : 
     682              :   std::string as_string () const override;
     683              : 
     684              :   BaseType *clone () const final override;
     685              :   std::string get_name () const override final;
     686              : 
     687              :   bool is_equal (const BaseType &other) const override;
     688              : 
     689            1 :   BaseType *as_base_type () override { return static_cast<BaseType *> (this); }
     690            0 :   const BaseType *as_base_type () const override
     691              :   {
     692            0 :     return static_cast<const BaseType *> (this);
     693              :   }
     694              : 
     695            0 :   BaseConstType *as_const_type () override { return this; }
     696            0 :   const BaseConstType *as_const_type () const override { return this; }
     697              : };
     698              : 
     699          168 : class OpaqueType : public BaseType
     700              : {
     701              : public:
     702              :   static constexpr auto KIND = TypeKind::OPAQUE;
     703              : 
     704              :   OpaqueType (location_t locus, HirId ref,
     705              :               std::vector<TypeBoundPredicate> specified_bounds,
     706              :               std::set<HirId> refs = std::set<HirId> ());
     707              : 
     708              :   OpaqueType (location_t locus, HirId ref, HirId ty_ref,
     709              :               std::vector<TypeBoundPredicate> specified_bounds,
     710              :               std::set<HirId> refs = std::set<HirId> ());
     711              : 
     712              :   void accept_vis (TyVisitor &vis) override;
     713              :   void accept_vis (TyConstVisitor &vis) const override;
     714              : 
     715              :   std::string as_string () const override;
     716              : 
     717              :   BaseType *clone () const final override;
     718              : 
     719              :   bool can_resolve () const;
     720              : 
     721              :   BaseType *resolve () const;
     722              : 
     723              :   std::string get_name () const override final;
     724              : 
     725              :   bool is_equal (const BaseType &other) const override;
     726              : };
     727              : 
     728              : class StructFieldType
     729              : {
     730              : public:
     731              :   StructFieldType (HirId ref, std::string name, BaseType *ty, location_t locus);
     732              : 
     733              :   HirId get_ref () const;
     734              : 
     735              :   bool is_equal (const StructFieldType &other) const;
     736              : 
     737              :   std::string get_name () const;
     738              : 
     739              :   BaseType *get_field_type () const;
     740              :   void set_field_type (BaseType *fty);
     741              : 
     742              :   StructFieldType *clone () const;
     743              :   StructFieldType *monomorphized_clone () const;
     744              : 
     745              :   void debug () const;
     746              :   location_t get_locus () const;
     747              :   std::string as_string () const;
     748              : 
     749              : private:
     750              :   HirId ref;
     751              :   std::string name;
     752              :   BaseType *ty;
     753              :   location_t locus;
     754              : };
     755              : 
     756              : class TupleType : public BaseType
     757              : {
     758              : public:
     759              :   static constexpr auto KIND = TypeKind::TUPLE;
     760              : 
     761              :   TupleType (HirId ref, location_t locus,
     762              :              std::vector<TyVar> fields = std::vector<TyVar> (),
     763              :              std::set<HirId> refs = std::set<HirId> ());
     764              : 
     765              :   TupleType (HirId ref, HirId ty_ref, location_t locus,
     766              :              std::vector<TyVar> fields = std::vector<TyVar> (),
     767              :              std::set<HirId> refs = std::set<HirId> ());
     768              : 
     769              :   static TupleType *get_unit_type ();
     770              : 
     771              :   void accept_vis (TyVisitor &vis) override;
     772              :   void accept_vis (TyConstVisitor &vis) const override;
     773              : 
     774              :   std::string as_string () const override;
     775              : 
     776              :   bool is_equal (const BaseType &other) const override;
     777              : 
     778              :   size_t num_fields () const;
     779              : 
     780              :   BaseType *get_field (size_t index) const;
     781              : 
     782              :   BaseType *clone () const final override;
     783              : 
     784              :   const std::vector<TyVar> &get_fields () const;
     785              : 
     786              :   std::string get_name () const override final;
     787              : 
     788              :   TupleType *handle_substitions (SubstitutionArgumentMappings &mappings);
     789              : 
     790              : private:
     791              :   std::vector<TyVar> fields;
     792              : };
     793              : 
     794        54742 : class TypeBoundPredicateItem
     795              : {
     796              : public:
     797              :   TypeBoundPredicateItem (const TypeBoundPredicate parent,
     798              :                           const Resolver::TraitItemReference *trait_item_ref);
     799              : 
     800              :   TypeBoundPredicateItem (const TypeBoundPredicateItem &other);
     801              : 
     802              :   TypeBoundPredicateItem &operator= (const TypeBoundPredicateItem &other);
     803              : 
     804              :   static TypeBoundPredicateItem error ();
     805              : 
     806              :   bool is_error () const;
     807              : 
     808              :   BaseType *get_tyty_for_receiver (const TyTy::BaseType *receiver);
     809              : 
     810              :   const Resolver::TraitItemReference *get_raw_item () const;
     811              : 
     812              :   bool needs_implementation () const;
     813              : 
     814              :   const TypeBoundPredicate *get_parent () const;
     815              : 
     816              :   location_t get_locus () const;
     817              : 
     818              : private:
     819              :   TypeBoundPredicate parent;
     820              :   const Resolver::TraitItemReference *trait_item_ref;
     821              : };
     822              : 
     823              : // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.VariantDef.html
     824              : class VariantDef
     825              : {
     826              : public:
     827              :   enum VariantType
     828              :   {
     829              :     NUM,
     830              :     TUPLE,
     831              :     STRUCT,
     832              :     UNIT
     833              :   };
     834              : 
     835              :   static std::string variant_type_string (VariantType type);
     836              : 
     837              :   VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
     838              :               tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant);
     839              : 
     840              :   VariantDef (HirId id, DefId defid, std::string identifier, RustIdent ident,
     841              :               VariantType type,
     842              :               tl::optional<std::unique_ptr<HIR::Expr>> &&discriminant,
     843              :               std::vector<StructFieldType *> fields);
     844              : 
     845              :   static VariantDef &get_error_node ();
     846              :   bool is_error () const;
     847              : 
     848              :   HirId get_id () const;
     849              :   DefId get_defid () const;
     850              : 
     851              :   VariantType get_variant_type () const;
     852              :   bool is_data_variant () const;
     853              :   bool is_dataless_variant () const;
     854              : 
     855              :   std::string get_identifier () const;
     856              : 
     857              :   size_t num_fields () const;
     858              :   StructFieldType *get_field_at_index (size_t index);
     859              : 
     860              :   std::vector<StructFieldType *> &get_fields ();
     861              : 
     862              :   bool lookup_field (const std::string &lookup, StructFieldType **field_lookup,
     863              :                      size_t *index) const;
     864              : 
     865              :   bool has_discriminant () const;
     866              : 
     867              :   HIR::Expr &get_discriminant ();
     868              :   const HIR::Expr &get_discriminant () const;
     869              : 
     870              :   std::string as_string () const;
     871              : 
     872              :   bool is_equal (const VariantDef &other) const;
     873              : 
     874              :   VariantDef *clone () const;
     875              : 
     876              :   VariantDef *monomorphized_clone () const;
     877              : 
     878              :   const RustIdent &get_ident () const;
     879              : 
     880              : private:
     881              :   HirId id;
     882              :   DefId defid;
     883              :   std::string identifier;
     884              :   RustIdent ident;
     885              :   VariantType type;
     886              : 
     887              :   // can either be a structure or a discriminant value
     888              :   tl::optional<std::unique_ptr<HIR::Expr>> discriminant;
     889              : 
     890              :   std::vector<StructFieldType *> fields;
     891              : };
     892              : 
     893              : class ADTType : public BaseType, public SubstitutionRef
     894              : {
     895              : public:
     896              :   static constexpr auto KIND = TypeKind::ADT;
     897              : 
     898              :   enum ADTKind
     899              :   {
     900              :     STRUCT_STRUCT,
     901              :     TUPLE_STRUCT,
     902              :     UNION,
     903              :     ENUM
     904              :   };
     905              : 
     906              :   enum ReprKind
     907              :   {
     908              :     RUST,
     909              :     C,
     910              :     INT,
     911              :     ALIGN,
     912              :     PACKED,
     913              :     // TRANSPARENT,
     914              :     // SIMD,
     915              :     // ...
     916              :   };
     917              : 
     918              :   // Representation options, specified via attributes e.g. #[repr(packed)]
     919          104 :   struct ReprOptions
     920              :   {
     921              :     ReprKind repr_kind = ReprKind::RUST;
     922              : 
     923              :     // For align and pack: 0 = unspecified. Nonzero = byte alignment.
     924              :     // It is an error for both to be nonzero, this should be caught when
     925              :     // parsing the #[repr] attribute.
     926              :     unsigned char align = 0;
     927              :     unsigned char pack = 0;
     928              :     BaseType *repr = nullptr;
     929              :   };
     930              : 
     931              :   ADTType (DefId id, HirId ref, std::string identifier, RustIdent ident,
     932              :            ADTKind adt_kind, std::vector<VariantDef *> variants,
     933              :            std::vector<SubstitutionParamMapping> subst_refs,
     934              :            SubstitutionArgumentMappings generic_arguments
     935              :            = SubstitutionArgumentMappings::error (),
     936              :            RegionConstraints region_constraints = RegionConstraints{},
     937              :            std::set<HirId> refs = std::set<HirId> ());
     938              : 
     939              :   ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
     940              :            RustIdent ident, ADTKind adt_kind,
     941              :            std::vector<VariantDef *> variants,
     942              :            std::vector<SubstitutionParamMapping> subst_refs,
     943              :            SubstitutionArgumentMappings generic_arguments
     944              :            = SubstitutionArgumentMappings::error (),
     945              :            RegionConstraints region_constraints = RegionConstraints{},
     946              :            std::set<HirId> refs = std::set<HirId> ());
     947              : 
     948              :   ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
     949              :            RustIdent ident, ADTKind adt_kind,
     950              :            std::vector<VariantDef *> variants,
     951              :            std::vector<SubstitutionParamMapping> subst_refs, ReprOptions repr,
     952              :            SubstitutionArgumentMappings generic_arguments
     953              :            = SubstitutionArgumentMappings::error (),
     954              :            RegionConstraints region_constraints = RegionConstraints{},
     955              :            std::set<HirId> refs = std::set<HirId> ());
     956              : 
     957       306579 :   ADTKind get_adt_kind () const { return adt_kind; }
     958              : 
     959       185489 :   ReprOptions get_repr_options () const { return repr; }
     960              : 
     961          915 :   bool is_struct_struct () const { return adt_kind == STRUCT_STRUCT; }
     962              : 
     963          746 :   bool is_tuple_struct () const { return adt_kind == TUPLE_STRUCT; }
     964              : 
     965        18866 :   bool is_union () const { return adt_kind == UNION; }
     966              : 
     967       799388 :   bool is_enum () const { return adt_kind == ENUM; }
     968              : 
     969              :   void accept_vis (TyVisitor &vis) override;
     970              : 
     971              :   void accept_vis (TyConstVisitor &vis) const override;
     972              : 
     973              :   std::string as_string () const override;
     974              : 
     975              :   bool is_equal (const BaseType &other) const override;
     976              : 
     977       271942 :   std::string get_identifier () const { return identifier; }
     978              : 
     979      1572287 :   std::string get_name () const override final
     980              :   {
     981      1572287 :     return identifier + subst_as_string ();
     982              :   }
     983              : 
     984              :   DefId get_id () const;
     985              : 
     986              :   BaseType *clone () const final override;
     987              : 
     988       483280 :   size_t number_of_variants () const { return variants.size (); }
     989              : 
     990       127916 :   std::vector<VariantDef *> &get_variants () { return variants; }
     991              : 
     992      1273165 :   const std::vector<VariantDef *> &get_variants () const { return variants; }
     993              : 
     994            6 :   bool lookup_variant (const std::string &lookup,
     995              :                        VariantDef **found_variant) const
     996              :   {
     997           13 :     for (auto &variant : variants)
     998              :       {
     999           10 :         if (variant->get_identifier ().compare (lookup) == 0)
    1000              :           {
    1001            3 :             *found_variant = variant;
    1002            3 :             return true;
    1003              :           }
    1004              :       }
    1005              :     return false;
    1006              :   }
    1007              : 
    1008         8348 :   bool lookup_variant_by_id (HirId id, VariantDef **found_variant,
    1009              :                              int *index = nullptr) const
    1010              :   {
    1011         8348 :     int i = 0;
    1012        15789 :     for (auto &variant : variants)
    1013              :       {
    1014        15789 :         if (variant->get_id () == id)
    1015              :           {
    1016         8348 :             if (index != nullptr)
    1017         4421 :               *index = i;
    1018              : 
    1019         8348 :             *found_variant = variant;
    1020         8348 :             return true;
    1021              :           }
    1022         7441 :         i++;
    1023              :       }
    1024              :     return false;
    1025              :   }
    1026              : 
    1027              :   ADTType *
    1028              :   handle_substitions (SubstitutionArgumentMappings &mappings) override final;
    1029              : 
    1030              : private:
    1031              :   DefId id;
    1032              :   std::string identifier;
    1033              :   std::vector<VariantDef *> variants;
    1034              :   ADTType::ADTKind adt_kind;
    1035              :   ReprOptions repr;
    1036              : };
    1037              : 
    1038        51527 : class FnParam
    1039              : {
    1040              : public:
    1041        78216 :   FnParam (std::unique_ptr<HIR::Pattern> pattern, BaseType *type)
    1042        78216 :     : pattern (std::move (pattern)), type (type)
    1043              :   {}
    1044              : 
    1045              :   FnParam (const FnParam &) = delete;
    1046        51527 :   FnParam (FnParam &&) = default;
    1047              :   FnParam &operator= (FnParam &&) = default;
    1048              : 
    1049        16524 :   HIR::Pattern &get_pattern () { return *pattern; }
    1050       142272 :   const HIR::Pattern &get_pattern () const { return *pattern; }
    1051              : 
    1052        12670 :   bool has_pattern () { return pattern != nullptr; }
    1053       224722 :   BaseType *get_type () const { return type; }
    1054        13010 :   void set_type (BaseType *new_type) { type = new_type; }
    1055              : 
    1056        20093 :   FnParam clone () const
    1057              :   {
    1058        20093 :     return FnParam (pattern->clone_pattern (), type->clone ());
    1059              :   }
    1060              : 
    1061            0 :   FnParam monomorphized_clone () const
    1062              :   {
    1063            0 :     return FnParam (pattern->clone_pattern (), type->monomorphized_clone ());
    1064              :   }
    1065              : 
    1066              : private:
    1067              :   std::unique_ptr<HIR::Pattern> pattern;
    1068              :   BaseType *type;
    1069              : };
    1070              : 
    1071              : class FnType : public CallableTypeInterface, public SubstitutionRef
    1072              : {
    1073              : public:
    1074              :   static constexpr auto KIND = TypeKind::FNDEF;
    1075              : 
    1076              :   static const uint8_t FNTYPE_DEFAULT_FLAGS = 0x00;
    1077              :   static const uint8_t FNTYPE_IS_METHOD_FLAG = 0x01;
    1078              :   static const uint8_t FNTYPE_IS_EXTERN_FLAG = 0x02;
    1079              :   static const uint8_t FNTYPE_IS_VARADIC_FLAG = 0X04;
    1080              :   static const uint8_t FNTYPE_IS_SYN_CONST_FLAG = 0X08;
    1081              : 
    1082        40587 :   FnType (HirId ref, DefId id, std::string identifier, RustIdent ident,
    1083              :           uint8_t flags, ABI abi, std::vector<FnParam> params, BaseType *type,
    1084              :           std::vector<SubstitutionParamMapping> subst_refs,
    1085              :           SubstitutionArgumentMappings substitution_argument_mappings,
    1086              :           RegionConstraints region_constraints,
    1087              :           std::set<HirId> refs = std::set<HirId> ())
    1088        40587 :     : CallableTypeInterface (ref, ref, TypeKind::FNDEF, ident, refs),
    1089              :       SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
    1090              :                        region_constraints),
    1091        40587 :       params (std::move (params)), type (type), flags (flags),
    1092        81174 :       identifier (identifier), id (id), abi (abi)
    1093              :   {
    1094        40587 :     LocalDefId local_def_id = id.localDefId;
    1095        40587 :     rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
    1096        40587 :   }
    1097              : 
    1098        13602 :   FnType (HirId ref, HirId ty_ref, DefId id, std::string identifier,
    1099              :           RustIdent ident, uint8_t flags, ABI abi, std::vector<FnParam> params,
    1100              :           BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
    1101              :           SubstitutionArgumentMappings substitution_argument_mappings,
    1102              :           RegionConstraints region_constraints,
    1103              :           std::set<HirId> refs = std::set<HirId> ())
    1104        13602 :     : CallableTypeInterface (ref, ty_ref, TypeKind::FNDEF, ident, refs),
    1105              :       SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
    1106              :                        region_constraints),
    1107        13602 :       params (std::move (params)), type (type), flags (flags),
    1108        27204 :       identifier (identifier), id (id), abi (abi)
    1109              :   {
    1110        13602 :     LocalDefId local_def_id = id.localDefId;
    1111        13602 :     rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
    1112        13602 :   }
    1113              : 
    1114              :   FnType (const FnType &) = delete;
    1115              :   FnType (FnType &&) = default;
    1116              : 
    1117              :   void accept_vis (TyVisitor &vis) override;
    1118              :   void accept_vis (TyConstVisitor &vis) const override;
    1119              : 
    1120              :   std::string as_string () const override;
    1121              : 
    1122        65105 :   std::string get_name () const override final { return as_string (); }
    1123              : 
    1124        65440 :   std::string get_identifier () const { return identifier; }
    1125              : 
    1126              :   bool is_equal (const BaseType &other) const override;
    1127              : 
    1128        86629 :   size_t num_params () const { return params.size (); }
    1129              : 
    1130        85386 :   bool is_method () const
    1131              :   {
    1132        85386 :     if (num_params () == 0)
    1133              :       return false;
    1134              : 
    1135        47286 :     return (flags & FNTYPE_IS_METHOD_FLAG) != 0;
    1136              :   }
    1137              : 
    1138              :   bool is_extern () const { return (flags & FNTYPE_IS_EXTERN_FLAG) != 0; }
    1139              : 
    1140        28270 :   bool is_variadic () const { return (flags & FNTYPE_IS_VARADIC_FLAG) != 0; }
    1141              : 
    1142        10671 :   bool is_syn_constant () const
    1143              :   {
    1144        10671 :     return (flags & FNTYPE_IS_SYN_CONST_FLAG) != 0;
    1145              :   }
    1146              : 
    1147        57986 :   DefId get_id () const { return id; }
    1148              : 
    1149              :   // get the Self type for the method
    1150        40969 :   BaseType *get_self_type () const
    1151              :   {
    1152        81938 :     rust_assert (is_method ());
    1153        81938 :     return param_at (0).get_type ();
    1154              :   }
    1155              : 
    1156        15853 :   std::vector<FnParam> &get_params () { return params; }
    1157              : 
    1158        25479 :   const std::vector<FnParam> &get_params () const { return params; }
    1159              : 
    1160        29624 :   FnParam &param_at (size_t idx) { return params.at (idx); }
    1161              : 
    1162        57847 :   const FnParam &param_at (size_t idx) const { return params.at (idx); }
    1163              : 
    1164              :   BaseType *clone () const final override;
    1165              : 
    1166              :   FnType *
    1167              :   handle_substitions (SubstitutionArgumentMappings &mappings) override final;
    1168              : 
    1169        32229 :   ABI get_abi () const { return abi; }
    1170            0 :   uint8_t get_flags () const { return flags; }
    1171              : 
    1172           22 :   WARN_UNUSED_RESULT size_t get_num_params () const override
    1173              :   {
    1174           22 :     return params.size ();
    1175              :   }
    1176              : 
    1177           22 :   WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
    1178              :   {
    1179           22 :     return param_at (index).get_type ();
    1180              :   }
    1181              : 
    1182       118051 :   WARN_UNUSED_RESULT BaseType *get_return_type () const override
    1183              :   {
    1184       118051 :     return type;
    1185              :   }
    1186              : 
    1187              : private:
    1188              :   std::vector<FnParam> params;
    1189              :   BaseType *type;
    1190              :   uint8_t flags;
    1191              :   std::string identifier;
    1192              :   DefId id;
    1193              :   ABI abi;
    1194              : };
    1195              : 
    1196              : class FnPtr : public CallableTypeInterface
    1197              : {
    1198              : public:
    1199              :   static constexpr auto KIND = TypeKind::FNPTR;
    1200              : 
    1201           60 :   FnPtr (HirId ref, location_t locus, std::vector<TyVar> params,
    1202              :          TyVar result_type, ABI abi, Unsafety unsafety,
    1203              :          std::set<HirId> refs = std::set<HirId> ())
    1204           60 :     : CallableTypeInterface (ref, ref, TypeKind::FNPTR,
    1205           60 :                              {Resolver::CanonicalPath::create_empty (), locus},
    1206              :                              refs),
    1207           60 :       params (std::move (params)), result_type (result_type), abi (abi),
    1208          120 :       unsafety (unsafety)
    1209           60 :   {}
    1210              : 
    1211         1384 :   FnPtr (HirId ref, HirId ty_ref, location_t locus, std::vector<TyVar> params,
    1212              :          TyVar result_type, ABI abi, Unsafety unsafety,
    1213              :          std::set<HirId> refs = std::set<HirId> ())
    1214         1384 :     : CallableTypeInterface (ref, ty_ref, TypeKind::FNPTR,
    1215         1384 :                              {Resolver::CanonicalPath::create_empty (), locus},
    1216              :                              refs),
    1217         2768 :       params (params), result_type (result_type), abi (abi), unsafety (unsafety)
    1218         1384 :   {}
    1219              : 
    1220         9247 :   std::string get_name () const override final { return as_string (); }
    1221              : 
    1222            0 :   WARN_UNUSED_RESULT size_t get_num_params () const override
    1223              :   {
    1224            0 :     return params.size ();
    1225              :   }
    1226              : 
    1227          183 :   WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
    1228              :   {
    1229          183 :     return params.at (index).get_tyty ();
    1230              :   }
    1231              : 
    1232        14438 :   WARN_UNUSED_RESULT BaseType *get_return_type () const override
    1233              :   {
    1234        14438 :     return result_type.get_tyty ();
    1235              :   }
    1236              : 
    1237            0 :   const TyVar &get_var_return_type () const { return result_type; }
    1238              : 
    1239          446 :   size_t num_params () const { return params.size (); }
    1240              : 
    1241              :   void accept_vis (TyVisitor &vis) override;
    1242              :   void accept_vis (TyConstVisitor &vis) const override;
    1243              : 
    1244              :   std::string as_string () const override;
    1245              : 
    1246              :   bool is_equal (const BaseType &other) const override;
    1247              : 
    1248              :   BaseType *clone () const final override;
    1249              : 
    1250           20 :   std::vector<TyVar> &get_params () { return params; }
    1251        13726 :   const std::vector<TyVar> &get_params () const { return params; }
    1252              : 
    1253         9618 :   ABI get_abi () const { return abi; }
    1254              : 
    1255        10944 :   Unsafety get_unsafety () const { return unsafety; }
    1256              : 
    1257              :   FnPtr *handle_substitions (SubstitutionArgumentMappings &mappings);
    1258              : 
    1259              : private:
    1260              :   std::vector<TyVar> params;
    1261              :   TyVar result_type;
    1262              :   ABI abi;
    1263              :   Unsafety unsafety;
    1264              : };
    1265              : 
    1266              : class ClosureType : public CallableTypeInterface, public SubstitutionRef
    1267              : {
    1268              : public:
    1269              :   static constexpr auto KIND = TypeKind::CLOSURE;
    1270              : 
    1271           65 :   ClosureType (HirId ref, DefId id, RustIdent ident, TupleType *parameters,
    1272              :                TyVar result_type,
    1273              :                std::vector<SubstitutionParamMapping> subst_refs,
    1274              :                std::set<NodeId> captures,
    1275              :                std::set<HirId> refs = std::set<HirId> (),
    1276              :                std::vector<TypeBoundPredicate> specified_bounds
    1277              :                = std::vector<TypeBoundPredicate> ())
    1278           65 :     : CallableTypeInterface (ref, ref, TypeKind::CLOSURE, ident, refs),
    1279              :       SubstitutionRef (std::move (subst_refs),
    1280          130 :                        SubstitutionArgumentMappings::error (),
    1281              :                        {}), // TODO: check region constraints
    1282           65 :       parameters (parameters), result_type (std::move (result_type)), id (id),
    1283          130 :       captures (captures)
    1284              :   {
    1285           65 :     LocalDefId local_def_id = id.localDefId;
    1286           65 :     rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
    1287           65 :     inherit_bounds (specified_bounds);
    1288           65 :   }
    1289              : 
    1290          319 :   ClosureType (HirId ref, HirId ty_ref, RustIdent ident, DefId id,
    1291              :                TupleType *parameters, TyVar result_type,
    1292              :                std::vector<SubstitutionParamMapping> subst_refs,
    1293              :                std::set<NodeId> captures,
    1294              :                std::set<HirId> refs = std::set<HirId> (),
    1295              :                std::vector<TypeBoundPredicate> specified_bounds
    1296              :                = std::vector<TypeBoundPredicate> ())
    1297          319 :     : CallableTypeInterface (ref, ty_ref, TypeKind::CLOSURE, ident, refs),
    1298              :       SubstitutionRef (std::move (subst_refs),
    1299          638 :                        SubstitutionArgumentMappings::error (), {}), // TODO
    1300          319 :       parameters (parameters), result_type (std::move (result_type)), id (id),
    1301          638 :       captures (captures)
    1302              :   {
    1303          319 :     LocalDefId local_def_id = id.localDefId;
    1304          319 :     rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
    1305          319 :     inherit_bounds (specified_bounds);
    1306          319 :   }
    1307              : 
    1308              :   void accept_vis (TyVisitor &vis) override;
    1309              :   void accept_vis (TyConstVisitor &vis) const override;
    1310              : 
    1311            0 :   WARN_UNUSED_RESULT size_t get_num_params () const override
    1312              :   {
    1313            0 :     return parameters->num_fields ();
    1314              :   }
    1315              : 
    1316            0 :   WARN_UNUSED_RESULT BaseType *get_param_type_at (size_t index) const override
    1317              :   {
    1318            0 :     return parameters->get_field (index);
    1319              :   }
    1320              : 
    1321            0 :   WARN_UNUSED_RESULT BaseType *get_return_type () const override
    1322              :   {
    1323            0 :     return result_type.get_tyty ();
    1324              :   }
    1325              : 
    1326              :   std::string as_string () const override;
    1327         2054 :   std::string get_name () const override final { return as_string (); }
    1328              : 
    1329              :   bool is_equal (const BaseType &other) const override;
    1330              : 
    1331              :   BaseType *clone () const final override;
    1332              : 
    1333              :   ClosureType *
    1334              :   handle_substitions (SubstitutionArgumentMappings &mappings) override final;
    1335              : 
    1336          642 :   TyTy::TupleType &get_parameters () const { return *parameters; }
    1337          644 :   TyTy::BaseType &get_result_type () const { return *result_type.get_tyty (); }
    1338              : 
    1339          390 :   DefId get_def_id () const { return id; }
    1340              : 
    1341              :   void setup_fn_once_output () const;
    1342              : 
    1343          365 :   const std::set<NodeId> &get_captures () const { return captures; }
    1344              : 
    1345              : private:
    1346              :   TyTy::TupleType *parameters;
    1347              :   TyVar result_type;
    1348              :   DefId id;
    1349              :   std::set<NodeId> captures;
    1350              : };
    1351              : 
    1352         4720 : class ArrayType : public BaseType
    1353              : {
    1354              : public:
    1355              :   static constexpr auto KIND = TypeKind::ARRAY;
    1356              : 
    1357         1128 :   ArrayType (HirId ref, location_t locus, TyVar capacity, TyVar base,
    1358              :              std::set<HirId> refs = std::set<HirId> ())
    1359         1128 :     : BaseType (ref, ref, TypeKind::ARRAY,
    1360         1128 :                 {Resolver::CanonicalPath::create_empty (), locus}, refs),
    1361         2256 :       element_type (base), capacity (capacity)
    1362         1128 :   {}
    1363              : 
    1364         2473 :   ArrayType (HirId ref, HirId ty_ref, location_t locus, TyVar capacity,
    1365              :              TyVar base, std::set<HirId> refs = std::set<HirId> ())
    1366         2473 :     : BaseType (ref, ty_ref, TypeKind::ARRAY,
    1367         2473 :                 {Resolver::CanonicalPath::create_empty (), locus}, refs),
    1368         4946 :       element_type (base), capacity (capacity)
    1369         2473 :   {}
    1370              : 
    1371              :   void accept_vis (TyVisitor &vis) override;
    1372              :   void accept_vis (TyConstVisitor &vis) const override;
    1373              : 
    1374              :   std::string as_string () const override;
    1375              : 
    1376        54248 :   std::string get_name () const override final { return as_string (); }
    1377              : 
    1378              :   bool is_equal (const BaseType &other) const override;
    1379              : 
    1380              :   BaseType *get_element_type () const;
    1381              :   const TyVar &get_var_element_type () const;
    1382              : 
    1383              :   BaseType *clone () const final override;
    1384              : 
    1385              :   BaseType *get_capacity () const;
    1386           80 :   const TyVar &get_capacity_var () const { return capacity; }
    1387              : 
    1388              :   ArrayType *handle_substitions (SubstitutionArgumentMappings &mappings);
    1389              : 
    1390              : private:
    1391              :   TyVar element_type;
    1392              :   TyVar capacity;
    1393              : };
    1394              : 
    1395         7336 : class SliceType : public BaseType
    1396              : {
    1397              : public:
    1398              :   static constexpr auto KIND = TypeKind::SLICE;
    1399              : 
    1400          916 :   SliceType (HirId ref, location_t locus, TyVar base,
    1401              :              std::set<HirId> refs = std::set<HirId> ())
    1402          916 :     : BaseType (ref, ref, TypeKind::SLICE,
    1403          916 :                 {Resolver::CanonicalPath::create_empty (), locus}, refs),
    1404         1832 :       element_type (base)
    1405          916 :   {}
    1406              : 
    1407        50062 :   SliceType (HirId ref, HirId ty_ref, location_t locus, TyVar base,
    1408              :              std::set<HirId> refs = std::set<HirId> ())
    1409        50062 :     : BaseType (ref, ty_ref, TypeKind::SLICE,
    1410        50062 :                 {Resolver::CanonicalPath::create_empty (), locus}, refs),
    1411       100124 :       element_type (base)
    1412        50062 :   {}
    1413              : 
    1414              :   void accept_vis (TyVisitor &vis) override;
    1415              :   void accept_vis (TyConstVisitor &vis) const override;
    1416              : 
    1417              :   std::string as_string () const override;
    1418              : 
    1419        43751 :   std::string get_name () const override final { return as_string (); }
    1420              : 
    1421              :   bool is_equal (const BaseType &other) const override;
    1422              : 
    1423              :   BaseType *get_element_type () const;
    1424              :   const TyVar &get_var_element_type () const;
    1425              : 
    1426              :   BaseType *clone () const final override;
    1427              : 
    1428              :   SliceType *handle_substitions (SubstitutionArgumentMappings &mappings);
    1429              : 
    1430              : private:
    1431              :   TyVar element_type;
    1432              : };
    1433              : 
    1434              : class BoolType : public BaseType
    1435              : {
    1436              : public:
    1437              :   static constexpr auto KIND = TypeKind::BOOL;
    1438              : 
    1439              :   BoolType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
    1440              :   BoolType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ());
    1441              : 
    1442              :   void accept_vis (TyVisitor &vis) override;
    1443              :   void accept_vis (TyConstVisitor &vis) const override;
    1444              : 
    1445              :   std::string as_string () const override;
    1446              : 
    1447              :   std::string get_name () const override final;
    1448              : 
    1449              :   BaseType *clone () const final override;
    1450              : };
    1451              : 
    1452              : class IntType : public BaseType
    1453              : {
    1454              : public:
    1455              :   enum IntKind
    1456              :   {
    1457              :     I8,
    1458              :     I16,
    1459              :     I32,
    1460              :     I64,
    1461              :     I128
    1462              :   };
    1463              : 
    1464              :   static constexpr auto KIND = TypeKind::INT;
    1465              : 
    1466              :   IntType (HirId ref, IntKind kind, std::set<HirId> refs = std::set<HirId> ());
    1467              :   IntType (HirId ref, HirId ty_ref, IntKind kind,
    1468              :            std::set<HirId> refs = std::set<HirId> ());
    1469              : 
    1470              :   void accept_vis (TyVisitor &vis) override;
    1471              :   void accept_vis (TyConstVisitor &vis) const override;
    1472              : 
    1473              :   std::string as_string () const override;
    1474              : 
    1475              :   std::string get_name () const override final;
    1476              : 
    1477              :   IntKind get_int_kind () const;
    1478              : 
    1479              :   BaseType *clone () const final override;
    1480              : 
    1481              :   bool is_equal (const BaseType &other) const override;
    1482              : 
    1483              : private:
    1484              :   IntKind int_kind;
    1485              : };
    1486              : 
    1487              : class UintType : public BaseType
    1488              : {
    1489              : public:
    1490              :   static constexpr auto KIND = TypeKind::UINT;
    1491              : 
    1492              :   enum UintKind
    1493              :   {
    1494              :     U8,
    1495              :     U16,
    1496              :     U32,
    1497              :     U64,
    1498              :     U128
    1499              :   };
    1500              : 
    1501              :   UintType (HirId ref, UintKind kind,
    1502              :             std::set<HirId> refs = std::set<HirId> ());
    1503              :   UintType (HirId ref, HirId ty_ref, UintKind kind,
    1504              :             std::set<HirId> refs = std::set<HirId> ());
    1505              : 
    1506              :   void accept_vis (TyVisitor &vis) override;
    1507              :   void accept_vis (TyConstVisitor &vis) const override;
    1508              : 
    1509              :   std::string as_string () const override;
    1510              : 
    1511              :   std::string get_name () const override final;
    1512              : 
    1513              :   UintKind get_uint_kind () const;
    1514              : 
    1515              :   BaseType *clone () const final override;
    1516              : 
    1517              :   bool is_equal (const BaseType &other) const override;
    1518              : 
    1519              : private:
    1520              :   UintKind uint_kind;
    1521              : };
    1522              : 
    1523              : class FloatType : public BaseType
    1524              : {
    1525              : public:
    1526              :   static constexpr auto KIND = TypeKind::FLOAT;
    1527              : 
    1528              :   enum FloatKind
    1529              :   {
    1530              :     F32,
    1531              :     F64
    1532              :   };
    1533              : 
    1534              :   FloatType (HirId ref, FloatKind kind,
    1535              :              std::set<HirId> refs = std::set<HirId> ());
    1536              :   FloatType (HirId ref, HirId ty_ref, FloatKind kind,
    1537              :              std::set<HirId> refs = std::set<HirId> ());
    1538              : 
    1539              :   void accept_vis (TyVisitor &vis) override;
    1540              :   void accept_vis (TyConstVisitor &vis) const override;
    1541              : 
    1542              :   std::string as_string () const override;
    1543              :   std::string get_name () const override final;
    1544              : 
    1545              :   FloatKind get_float_kind () const;
    1546              : 
    1547              :   BaseType *clone () const final override;
    1548              : 
    1549              :   bool is_equal (const BaseType &other) const override;
    1550              : 
    1551              : private:
    1552              :   FloatKind float_kind;
    1553              : };
    1554              : 
    1555              : class USizeType : public BaseType
    1556              : {
    1557              : public:
    1558              :   static constexpr auto KIND = TypeKind::USIZE;
    1559              : 
    1560              :   USizeType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
    1561              :   USizeType (HirId ref, HirId ty_ref,
    1562              :              std::set<HirId> refs = std::set<HirId> ());
    1563              : 
    1564              :   void accept_vis (TyVisitor &vis) override;
    1565              :   void accept_vis (TyConstVisitor &vis) const override;
    1566              : 
    1567              :   std::string as_string () const override;
    1568              :   std::string get_name () const override final;
    1569              : 
    1570              :   BaseType *clone () const final override;
    1571              : };
    1572              : 
    1573              : class ISizeType : public BaseType
    1574              : {
    1575              : public:
    1576              :   static constexpr auto KIND = TypeKind::ISIZE;
    1577              : 
    1578              :   ISizeType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
    1579              :   ISizeType (HirId ref, HirId ty_ref,
    1580              :              std::set<HirId> refs = std::set<HirId> ());
    1581              : 
    1582              :   void accept_vis (TyVisitor &vis) override;
    1583              :   void accept_vis (TyConstVisitor &vis) const override;
    1584              : 
    1585              :   std::string as_string () const override;
    1586              :   std::string get_name () const override final;
    1587              : 
    1588              :   BaseType *clone () const final override;
    1589              : };
    1590              : 
    1591              : class CharType : public BaseType
    1592              : {
    1593              : public:
    1594              :   static constexpr auto KIND = TypeKind::CHAR;
    1595              : 
    1596              :   CharType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
    1597              :   CharType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ());
    1598              : 
    1599              :   void accept_vis (TyVisitor &vis) override;
    1600              :   void accept_vis (TyConstVisitor &vis) const override;
    1601              : 
    1602              :   std::string as_string () const override;
    1603              :   std::string get_name () const override final;
    1604              : 
    1605              :   BaseType *clone () const final override;
    1606              : };
    1607              : 
    1608              : class StrType : public BaseType
    1609              : {
    1610              : public:
    1611              :   static constexpr auto KIND = TypeKind::STR;
    1612              : 
    1613              :   StrType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
    1614              :   StrType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ());
    1615              : 
    1616              :   std::string get_name () const override final;
    1617              : 
    1618              :   void accept_vis (TyVisitor &vis) override;
    1619              :   void accept_vis (TyConstVisitor &vis) const override;
    1620              : 
    1621              :   std::string as_string () const override;
    1622              : 
    1623              :   bool is_equal (const BaseType &other) const override;
    1624              : 
    1625              :   BaseType *clone () const final override;
    1626              : };
    1627              : 
    1628              : class DynamicObjectType : public BaseType
    1629              : {
    1630              : public:
    1631              :   static constexpr auto KIND = TypeKind::DYNAMIC;
    1632              : 
    1633              :   DynamicObjectType (HirId ref, RustIdent ident,
    1634              :                      std::vector<TypeBoundPredicate> specified_bounds,
    1635              :                      std::set<HirId> refs = std::set<HirId> ());
    1636              : 
    1637              :   DynamicObjectType (HirId ref, HirId ty_ref, RustIdent ident,
    1638              :                      std::vector<TypeBoundPredicate> specified_bounds,
    1639              :                      std::set<HirId> refs = std::set<HirId> ());
    1640              : 
    1641              :   void accept_vis (TyVisitor &vis) override;
    1642              :   void accept_vis (TyConstVisitor &vis) const override;
    1643              : 
    1644              :   std::string as_string () const override;
    1645              : 
    1646              :   bool is_equal (const BaseType &other) const override;
    1647              : 
    1648              :   BaseType *clone () const final override;
    1649              : 
    1650              :   std::string get_name () const override final;
    1651              : 
    1652              :   // this returns a flat list of items including super trait bounds
    1653              :   const std::vector<
    1654              :     std::pair<const Resolver::TraitItemReference *, const TypeBoundPredicate *>>
    1655              :   get_object_items () const;
    1656              : };
    1657              : 
    1658        35854 : class ReferenceType : public BaseType
    1659              : {
    1660              : public:
    1661              :   static constexpr auto KIND = REF;
    1662              : 
    1663              :   ReferenceType (HirId ref, TyVar base, Mutability mut,
    1664              :                  Region region = Region::make_anonymous (),
    1665              :                  std::set<HirId> refs = std::set<HirId> ());
    1666              :   ReferenceType (HirId ref, HirId ty_ref, TyVar base, Mutability mut,
    1667              :                  Region region = Region::make_anonymous (),
    1668              :                  std::set<HirId> refs = std::set<HirId> ());
    1669              : 
    1670              :   BaseType *get_base () const;
    1671              :   const TyVar &get_var_element_type () const;
    1672              : 
    1673              :   void accept_vis (TyVisitor &vis) override;
    1674              :   void accept_vis (TyConstVisitor &vis) const override;
    1675              : 
    1676              :   std::string as_string () const override;
    1677              : 
    1678              :   std::string get_name () const override final;
    1679              : 
    1680              :   bool is_equal (const BaseType &other) const override;
    1681              : 
    1682              :   BaseType *clone () const final override;
    1683              : 
    1684              :   ReferenceType *handle_substitions (SubstitutionArgumentMappings &mappings);
    1685              : 
    1686              :   Mutability mutability () const;
    1687              :   bool is_mutable () const;
    1688              : 
    1689              :   WARN_UNUSED_RESULT Region get_region () const;
    1690              :   void set_region (Region region);
    1691              : 
    1692              :   bool is_dyn_object () const;
    1693              :   bool is_dyn_slice_type (const TyTy::SliceType **slice = nullptr) const;
    1694              :   bool is_dyn_str_type (const TyTy::StrType **str = nullptr) const;
    1695              :   bool is_dyn_obj_type (const TyTy::DynamicObjectType **dyn = nullptr) const;
    1696              : 
    1697              : private:
    1698              :   TyVar base;
    1699              :   Mutability mut;
    1700              :   Region region;
    1701              : };
    1702              : 
    1703        31518 : class PointerType : public BaseType
    1704              : {
    1705              : public:
    1706              :   static constexpr auto KIND = TypeKind::POINTER;
    1707              : 
    1708              :   PointerType (HirId ref, TyVar base, Mutability mut,
    1709              :                std::set<HirId> refs = std::set<HirId> ());
    1710              :   PointerType (HirId ref, HirId ty_ref, TyVar base, Mutability mut,
    1711              :                std::set<HirId> refs = std::set<HirId> ());
    1712              : 
    1713              :   BaseType *get_base () const;
    1714              :   const TyVar &get_var_element_type () const;
    1715              : 
    1716              :   void accept_vis (TyVisitor &vis) override;
    1717              :   void accept_vis (TyConstVisitor &vis) const override;
    1718              : 
    1719              :   std::string as_string () const override;
    1720              :   std::string get_name () const override final;
    1721              : 
    1722              :   bool is_equal (const BaseType &other) const override;
    1723              : 
    1724              :   BaseType *clone () const final override;
    1725              : 
    1726              :   PointerType *handle_substitions (SubstitutionArgumentMappings &mappings);
    1727              : 
    1728              :   Mutability mutability () const;
    1729              :   bool is_mutable () const;
    1730              :   bool is_const () const;
    1731              :   bool is_dyn_object () const;
    1732              :   bool is_dyn_slice_type (const TyTy::SliceType **slice = nullptr) const;
    1733              :   bool is_dyn_str_type (const TyTy::StrType **str = nullptr) const;
    1734              :   bool is_dyn_obj_type (const TyTy::DynamicObjectType **dyn = nullptr) const;
    1735              : 
    1736              : private:
    1737              :   TyVar base;
    1738              :   Mutability mut;
    1739              : };
    1740              : 
    1741              : // https://doc.rust-lang.org/std/primitive.never.html
    1742              : //
    1743              : // Since the `!` type is really complicated and it is even still unstable
    1744              : // in rustc, only fairly limited support for this type is introduced here.
    1745              : // Unification between `!` and ANY other type (including `<T?>`) is simply
    1746              : // not allowed. If it is needed, it should be handled manually. For example,
    1747              : // unifying `!` with other types is very necessary when resolving types of
    1748              : // `if/else` expressions.
    1749              : //
    1750              : // See related discussion at https://github.com/Rust-GCC/gccrs/pull/364
    1751              : class NeverType : public BaseType
    1752              : {
    1753              : public:
    1754              :   static constexpr auto KIND = TypeKind::NEVER;
    1755              : 
    1756              :   NeverType (HirId ref, std::set<HirId> refs = std::set<HirId> ());
    1757              : 
    1758              :   NeverType (HirId ref, HirId ty_ref,
    1759              :              std::set<HirId> refs = std::set<HirId> ());
    1760              : 
    1761              :   void accept_vis (TyVisitor &vis) override;
    1762              : 
    1763              :   void accept_vis (TyConstVisitor &vis) const override;
    1764              : 
    1765              :   std::string as_string () const override;
    1766              : 
    1767              :   BaseType *clone () const final override;
    1768              : 
    1769              :   std::string get_name () const override final;
    1770              : };
    1771              : 
    1772              : // used at the type in associated types in traits
    1773              : // see: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
    1774              : class PlaceholderType : public BaseType
    1775              : {
    1776              : public:
    1777              :   static constexpr auto KIND = TypeKind::PLACEHOLDER;
    1778              : 
    1779              :   PlaceholderType (std::string symbol, DefId id, HirId ref,
    1780              :                    std::set<HirId> refs = std::set<HirId> ());
    1781              :   PlaceholderType (std::string symbol, DefId id, HirId ref, HirId ty_ref,
    1782              :                    std::set<HirId> refs = std::set<HirId> ());
    1783              : 
    1784              :   void accept_vis (TyVisitor &vis) override;
    1785              :   void accept_vis (TyConstVisitor &vis) const override;
    1786              : 
    1787              :   std::string as_string () const override;
    1788              : 
    1789              :   BaseType *clone () const final override;
    1790              : 
    1791              :   std::string get_name () const override final;
    1792              : 
    1793              :   std::string get_symbol () const;
    1794              : 
    1795              :   void set_associated_type (HirId ref);
    1796              : 
    1797              :   void clear_associated_type ();
    1798              : 
    1799              :   bool can_resolve () const;
    1800              : 
    1801              :   BaseType *resolve () const;
    1802              : 
    1803              :   bool is_equal (const BaseType &other) const override;
    1804              : 
    1805              :   DefId get_def_id () const;
    1806              : 
    1807              : private:
    1808              :   std::string symbol;
    1809              :   DefId defId;
    1810              : };
    1811              : 
    1812              : class ProjectionType : public BaseType, public SubstitutionRef
    1813              : {
    1814              : public:
    1815              :   static constexpr auto KIND = TypeKind::PROJECTION;
    1816              : 
    1817              :   ProjectionType (HirId ref, BaseType *base,
    1818              :                   const Resolver::TraitReference *trait, DefId item,
    1819              :                   std::vector<SubstitutionParamMapping> subst_refs,
    1820              :                   SubstitutionArgumentMappings generic_arguments
    1821              :                   = SubstitutionArgumentMappings::error (),
    1822              :                   RegionConstraints region_constraints = {},
    1823              :                   std::set<HirId> refs = std::set<HirId> ());
    1824              : 
    1825              :   ProjectionType (HirId ref, HirId ty_ref, BaseType *base,
    1826              :                   const Resolver::TraitReference *trait, DefId item,
    1827              :                   std::vector<SubstitutionParamMapping> subst_refs,
    1828              :                   SubstitutionArgumentMappings generic_arguments
    1829              :                   = SubstitutionArgumentMappings::error (),
    1830              :                   RegionConstraints region_constraints = {},
    1831              :                   std::set<HirId> refs = std::set<HirId> ());
    1832              : 
    1833              :   void accept_vis (TyVisitor &vis) override;
    1834              :   void accept_vis (TyConstVisitor &vis) const override;
    1835              : 
    1836              :   std::string as_string () const override;
    1837              : 
    1838              :   BaseType *clone () const final override;
    1839              : 
    1840              :   std::string get_name () const override final;
    1841              : 
    1842              :   const BaseType *get () const;
    1843              :   BaseType *get ();
    1844              : 
    1845              :   ProjectionType *
    1846              :   handle_substitions (SubstitutionArgumentMappings &mappings) override final;
    1847              : 
    1848              : private:
    1849              :   BaseType *base;
    1850              :   const Resolver::TraitReference *trait;
    1851              :   DefId item;
    1852              : };
    1853              : 
    1854              : template <>
    1855              : WARN_UNUSED_RESULT inline bool
    1856           22 : BaseType::is<CallableTypeInterface> () const
    1857              : {
    1858           22 :   auto kind = this->get_kind ();
    1859           22 :   return kind == FNPTR || kind == FNDEF || kind == CLOSURE;
    1860              : }
    1861              : 
    1862              : template <>
    1863              : WARN_UNUSED_RESULT inline bool
    1864           11 : BaseType::is<const CallableTypeInterface> () const
    1865              : {
    1866           11 :   return this->is<CallableTypeInterface> ();
    1867              : }
    1868              : 
    1869              : template <>
    1870              : WARN_UNUSED_RESULT inline bool
    1871           17 : BaseType::is<SubstitutionRef> () const
    1872              : {
    1873           17 :   auto kind = this->get_kind ();
    1874           34 :   return kind == FNPTR || kind == FNDEF || kind == CLOSURE || kind == ADT
    1875           17 :          || kind == PROJECTION;
    1876              : }
    1877              : 
    1878              : template <>
    1879              : WARN_UNUSED_RESULT inline bool
    1880              : BaseType::is<const SubstitutionRef> () const
    1881              : {
    1882              :   return this->is<SubstitutionRef> ();
    1883              : }
    1884              : 
    1885              : template <>
    1886              : WARN_UNUSED_RESULT inline SubstitutionRef *
    1887           16 : BaseType::as<SubstitutionRef> ()
    1888              : {
    1889           16 :   auto kind = this->get_kind ();
    1890           16 :   switch (kind)
    1891              :     {
    1892            0 :     case FNDEF:
    1893            0 :       return static_cast<FnType *> (this);
    1894            0 :     case CLOSURE:
    1895            0 :       return static_cast<ClosureType *> (this);
    1896           16 :     case ADT:
    1897           16 :       return static_cast<ADTType *> (this);
    1898            0 :     case PROJECTION:
    1899            0 :       return static_cast<ProjectionType *> (this);
    1900            0 :     default:
    1901            0 :       rust_unreachable ();
    1902              :     }
    1903              : }
    1904              : 
    1905              : template <>
    1906              : WARN_UNUSED_RESULT inline const SubstitutionRef *
    1907            5 : BaseType::as<const SubstitutionRef> () const
    1908              : {
    1909            5 :   auto kind = this->get_kind ();
    1910            5 :   switch (kind)
    1911              :     {
    1912            0 :     case FNDEF:
    1913            0 :       return static_cast<const FnType *> (this);
    1914            0 :     case CLOSURE:
    1915            0 :       return static_cast<const ClosureType *> (this);
    1916            5 :     case ADT:
    1917            5 :       return static_cast<const ADTType *> (this);
    1918            0 :     case PROJECTION:
    1919            0 :       return static_cast<const ProjectionType *> (this);
    1920            0 :     default:
    1921            0 :       rust_unreachable ();
    1922              :     }
    1923              : }
    1924              : 
    1925              : template <>
    1926              : WARN_UNUSED_RESULT inline SubstitutionRef *
    1927           17 : BaseType::try_as<SubstitutionRef> ()
    1928              : {
    1929           17 :   if (this->is<SubstitutionRef> ())
    1930              :     {
    1931           16 :       return this->as<SubstitutionRef> ();
    1932              :     }
    1933              :   return nullptr;
    1934              : }
    1935              : 
    1936              : template <>
    1937              : WARN_UNUSED_RESULT inline const SubstitutionRef *
    1938              : BaseType::try_as<const SubstitutionRef> () const
    1939              : {
    1940              :   if (this->is<const SubstitutionRef> ())
    1941              :     {
    1942              :       return this->as<const SubstitutionRef> ();
    1943              :     }
    1944              :   return nullptr;
    1945              : }
    1946              : 
    1947              : } // namespace TyTy
    1948              : } // namespace Rust
    1949              : 
    1950              : #endif // RUST_TYTY
        

Generated by: LCOV version 2.4-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.