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

Generated by: LCOV version 2.5.0-beta

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