LCOV - code coverage report
Current view: top level - gcc/rust/hir/tree - rust-hir-item.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 69.8 % 474 331
Test Date: 2026-10-17 16:30:31 Functions: 63.6 % 140 89
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
       2              : 
       3              : // This file is part of GCC.
       4              : 
       5              : // GCC is free software; you can redistribute it and/or modify it under
       6              : // the terms of the GNU General Public License as published by the Free
       7              : // Software Foundation; either version 3, or (at your option) any later
       8              : // version.
       9              : 
      10              : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11              : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12              : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13              : // for more details.
      14              : 
      15              : // You should have received a copy of the GNU General Public License
      16              : // along with GCC; see the file COPYING3.  If not see
      17              : // <http://www.gnu.org/licenses/>.
      18              : 
      19              : #ifndef RUST_HIR_ITEM_H
      20              : #define RUST_HIR_ITEM_H
      21              : 
      22              : #include "optional.h"
      23              : #include "rust-abi.h"
      24              : #include "rust-hir-stmt.h"
      25              : #include "rust-common.h"
      26              : #include "rust-hir-visibility.h"
      27              : #include "rust-hir-generic-param.h"
      28              : #include "rust-system.h"
      29              : 
      30              : namespace Rust {
      31              : namespace HIR {
      32              : 
      33              : // Rust "item" HIR node (declaration of top-level/module-level allowed stuff)
      34           45 : class Item : public Stmt, public WithOuterAttrs
      35              : {
      36              :   // TODO: should outer attrs be defined here or in each derived class?
      37              : public:
      38              :   enum class ItemKind
      39              :   {
      40              :     Static,
      41              :     Constant,
      42              :     TypeAlias,
      43              :     Function,
      44              :     UseDeclaration,
      45              :     ExternBlock,
      46              :     ExternCrate,
      47              :     Struct,
      48              :     Union,
      49              :     Enum,
      50              :     EnumItem, // FIXME: ARTHUR: Do we need that?
      51              :     Trait,
      52              :     Impl,
      53              :     Module,
      54              :   };
      55              : 
      56              :   static std::string item_kind_string (ItemKind kind);
      57              : 
      58              :   virtual ItemKind get_item_kind () const = 0;
      59              : 
      60              :   // Unique pointer custom clone function
      61            0 :   std::unique_ptr<Item> clone_item () const
      62              :   {
      63            0 :     return std::unique_ptr<Item> (clone_item_impl ());
      64              :   }
      65              : 
      66            0 :   BaseKind get_hir_kind () override { return Node::BaseKind::ITEM; }
      67              : 
      68              :   std::string to_string () const override;
      69              : 
      70              :   /* Adds crate names to the vector passed by reference, if it can
      71              :    * (polymorphism). */
      72              :   virtual void
      73            0 :   add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const
      74            0 :   {}
      75              : 
      76          910 :   bool is_item () const override final { return true; }
      77              : 
      78              : protected:
      79              :   // Constructor
      80        63315 :   Item (Analysis::NodeMapping mappings,
      81              :         AST::AttrVec outer_attribs = AST::AttrVec ())
      82        63315 :     : Stmt (std::move (mappings)), WithOuterAttrs (std::move (outer_attribs))
      83        63315 :   {}
      84              : 
      85              :   // Clone function implementation as pure virtual method
      86              :   virtual Item *clone_item_impl () const = 0;
      87              : 
      88              :   /* Save having to specify two clone methods in derived classes by making
      89              :    * statement clone return item clone. Hopefully won't affect performance too
      90              :    * much. */
      91            3 :   Item *clone_stmt_impl () const override { return clone_item_impl (); }
      92              : };
      93              : 
      94              : // A type generic parameter (as opposed to a lifetime generic parameter)
      95              : class TypeParam : public GenericParam
      96              : {
      97              :   AST::AttrVec outer_attrs;
      98              :   Identifier type_representation;
      99              :   std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
     100              :   tl::optional<std::unique_ptr<Type>> type;
     101              :   location_t locus;
     102              :   bool was_impl_trait;
     103              : 
     104              : public:
     105              :   // Returns whether the type of the type param has been specified.
     106        56925 :   bool has_type () const { return type.has_value (); }
     107              : 
     108              :   // Returns whether the type param has type param bounds.
     109        25964 :   bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
     110              : 
     111              :   // Returns whether the type param has an outer attribute.
     112            0 :   bool has_outer_attribute () const override { return outer_attrs.size () > 0; }
     113         9898 :   AST::AttrVec &get_outer_attrs () override { return outer_attrs; }
     114              : 
     115              :   TypeParam (Analysis::NodeMapping mappings, Identifier type_representation,
     116              :              location_t locus = UNDEF_LOCATION,
     117              :              std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds
     118              :              = {},
     119              :              tl::optional<std::unique_ptr<Type>> type = tl::nullopt,
     120              :              AST::AttrVec outer_attrs = {}, bool was_impl_trait = false);
     121              : 
     122              :   // Copy constructor uses clone
     123              :   TypeParam (TypeParam const &other);
     124              : 
     125              :   // Overloaded assignment operator to clone
     126              :   TypeParam &operator= (TypeParam const &other);
     127              : 
     128              :   // move constructors
     129              :   TypeParam (TypeParam &&other) = default;
     130              : 
     131              :   TypeParam &operator= (TypeParam &&other) = default;
     132              : 
     133              :   std::string to_debug_string () const override;
     134              : 
     135              :   std::string to_string () const override;
     136              : 
     137        26899 :   location_t get_locus () const override final { return locus; }
     138              : 
     139              :   void accept_vis (HIRFullVisitor &vis) override;
     140              : 
     141        19213 :   Identifier get_type_representation () const { return type_representation; }
     142              : 
     143          787 :   Type &get_type ()
     144              :   {
     145          787 :     rust_assert (*type);
     146          787 :     return *type.value ();
     147              :   }
     148              : 
     149              :   Analysis::NodeMapping get_type_mappings () const;
     150              : 
     151              :   std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ();
     152              : 
     153        11749 :   bool from_impl_trait () const { return was_impl_trait; }
     154              : 
     155              : protected:
     156              :   // Clone function implementation as (not pure) virtual method
     157            0 :   TypeParam *clone_generic_param_impl () const override
     158              :   {
     159            0 :     return new TypeParam (*this);
     160              :   }
     161              : };
     162              : 
     163              : /* "where" clause item base. Abstract - use LifetimeWhereClauseItem,
     164              :  * TypeBoundWhereClauseItem */
     165          537 : class WhereClauseItem : public FullVisitable
     166              : {
     167              : public:
     168              :   enum ItemType
     169              :   {
     170              :     LIFETIME,
     171              :     TYPE_BOUND,
     172              :   };
     173              : 
     174              :   virtual ~WhereClauseItem () {}
     175              : 
     176              :   // Unique pointer custom clone function
     177          534 :   std::unique_ptr<WhereClauseItem> clone_where_clause_item () const
     178              :   {
     179          534 :     return std::unique_ptr<WhereClauseItem> (clone_where_clause_item_impl ());
     180              :   }
     181              : 
     182              :   virtual std::string to_string () const = 0;
     183              : 
     184              :   virtual void accept_vis (HIRFullVisitor &vis) = 0;
     185              : 
     186              :   virtual Analysis::NodeMapping get_mappings () const = 0;
     187              : 
     188              :   virtual ItemType get_item_type () const = 0;
     189              : 
     190              : protected:
     191              :   // Clone function implementation as pure virtual method
     192              :   virtual WhereClauseItem *clone_where_clause_item_impl () const = 0;
     193              : };
     194              : 
     195              : // A lifetime where clause item
     196              : class LifetimeWhereClauseItem : public WhereClauseItem
     197              : {
     198              :   Lifetime lifetime;
     199              :   std::vector<Lifetime> lifetime_bounds;
     200              :   location_t locus;
     201              :   Analysis::NodeMapping mappings;
     202              : 
     203              : public:
     204            3 :   LifetimeWhereClauseItem (Analysis::NodeMapping mappings, Lifetime lifetime,
     205              :                            std::vector<Lifetime> lifetime_bounds,
     206              :                            location_t locus)
     207            3 :     : lifetime (std::move (lifetime)),
     208            3 :       lifetime_bounds (std::move (lifetime_bounds)), locus (locus),
     209            3 :       mappings (std::move (mappings))
     210            3 :   {}
     211              : 
     212              :   std::string to_string () const override;
     213              : 
     214              :   location_t get_locus () const { return locus; }
     215              : 
     216              :   void accept_vis (HIRFullVisitor &vis) override;
     217              : 
     218            2 :   Lifetime &get_lifetime () { return lifetime; }
     219              : 
     220            2 :   std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
     221              : 
     222            0 :   Analysis::NodeMapping get_mappings () const override final
     223              :   {
     224            0 :     return mappings;
     225              :   };
     226              : 
     227            6 :   ItemType get_item_type () const override final
     228              :   {
     229            6 :     return WhereClauseItem::ItemType::LIFETIME;
     230              :   }
     231              : 
     232              : protected:
     233              :   // Clone function implementation as (not pure) virtual method
     234            0 :   LifetimeWhereClauseItem *clone_where_clause_item_impl () const override
     235              :   {
     236            0 :     return new LifetimeWhereClauseItem (*this);
     237              :   }
     238              : };
     239              : 
     240              : // A type bound where clause item
     241              : class TypeBoundWhereClauseItem : public WhereClauseItem
     242              : {
     243              :   std::vector<LifetimeParam> for_lifetimes;
     244              :   std::unique_ptr<Type> bound_type;
     245              :   std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
     246              :   Analysis::NodeMapping mappings;
     247              :   location_t locus;
     248              : 
     249              : public:
     250              :   // Returns whether the item has ForLifetimes
     251         1360 :   bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
     252              : 
     253              :   // Returns whether the item has type param bounds
     254              :   bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
     255              : 
     256              :   TypeBoundWhereClauseItem (
     257              :     Analysis::NodeMapping mappings, std::vector<LifetimeParam> for_lifetimes,
     258              :     std::unique_ptr<Type> bound_type,
     259              :     std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
     260              :     location_t locus);
     261              : 
     262              :   // Copy constructor requires clone
     263              :   TypeBoundWhereClauseItem (TypeBoundWhereClauseItem const &other);
     264              : 
     265              :   // Overload assignment operator to clone
     266              :   TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem const &other);
     267              : 
     268              :   // move constructors
     269              :   TypeBoundWhereClauseItem (TypeBoundWhereClauseItem &&other) = default;
     270              :   TypeBoundWhereClauseItem &operator= (TypeBoundWhereClauseItem &&other)
     271              :     = default;
     272              : 
     273              :   location_t get_locus () const { return locus; }
     274              : 
     275              :   std::string to_string () const override;
     276              : 
     277              :   void accept_vis (HIRFullVisitor &vis) override;
     278              : 
     279          380 :   std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
     280              : 
     281         2396 :   Type &get_bound_type () { return *bound_type; }
     282              : 
     283              :   std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ();
     284              : 
     285            0 :   Analysis::NodeMapping get_mappings () const override final
     286              :   {
     287            0 :     return mappings;
     288              :   };
     289              : 
     290         1368 :   ItemType get_item_type () const override final
     291              :   {
     292         1368 :     return WhereClauseItem::ItemType::TYPE_BOUND;
     293              :   }
     294              : 
     295              : protected:
     296              :   // Clone function implementation as (not pure) virtual method
     297          534 :   TypeBoundWhereClauseItem *clone_where_clause_item_impl () const override
     298              :   {
     299          534 :     return new TypeBoundWhereClauseItem (*this);
     300              :   }
     301              : };
     302              : 
     303              : // A where clause
     304       123763 : struct WhereClause
     305              : {
     306              : private:
     307              :   std::vector<std::unique_ptr<WhereClauseItem>> where_clause_items;
     308              : 
     309              :   // should this store location info?
     310              : 
     311              : public:
     312        63895 :   WhereClause (std::vector<std::unique_ptr<WhereClauseItem>> where_clause_items)
     313        63895 :     : where_clause_items (std::move (where_clause_items))
     314              :   {}
     315              : 
     316              :   // copy constructor with vector clone
     317        17821 :   WhereClause (WhereClause const &other)
     318        17821 :   {
     319        17821 :     where_clause_items.reserve (other.where_clause_items.size ());
     320        18355 :     for (const auto &e : other.where_clause_items)
     321          534 :       where_clause_items.push_back (e->clone_where_clause_item ());
     322        17821 :   }
     323              : 
     324              :   // overloaded assignment operator with vector clone
     325            0 :   WhereClause &operator= (WhereClause const &other)
     326              :   {
     327            0 :     where_clause_items.reserve (other.where_clause_items.size ());
     328            0 :     for (const auto &e : other.where_clause_items)
     329            0 :       where_clause_items.push_back (e->clone_where_clause_item ());
     330              : 
     331            0 :     return *this;
     332              :   }
     333              : 
     334              :   // move constructors
     335        79662 :   WhereClause (WhereClause &&other) = default;
     336              :   WhereClause &operator= (WhereClause &&other) = default;
     337              : 
     338              :   // Creates a WhereClause with no items.
     339              :   static WhereClause create_empty ()
     340              :   {
     341              :     return WhereClause (std::vector<std::unique_ptr<WhereClauseItem>> ());
     342              :   }
     343              : 
     344              :   // Returns whether the WhereClause has no items.
     345        34134 :   bool is_empty () const { return where_clause_items.empty (); }
     346              : 
     347              :   std::string to_string () const;
     348              : 
     349              :   std::vector<std::unique_ptr<WhereClauseItem>> &get_items ()
     350              :   {
     351       120623 :     return where_clause_items;
     352              :   }
     353              :   const std::vector<std::unique_ptr<WhereClauseItem>> &get_items () const
     354              :   {
     355            0 :     return where_clause_items;
     356              :   }
     357              : };
     358              : 
     359              : // A self parameter in a method
     360              : struct SelfParam
     361              : {
     362              : public:
     363              :   enum ImplicitSelfKind
     364              :   {
     365              :     IMM,     // self
     366              :     MUT,     // mut self
     367              :     IMM_REF, // &self
     368              :     MUT_REF, // &mut self
     369              :     NONE
     370              :   };
     371              : 
     372              : private:
     373              :   ImplicitSelfKind self_kind;
     374              :   tl::optional<Lifetime> lifetime;
     375              :   std::unique_ptr<Type> type;
     376              :   location_t locus;
     377              :   Analysis::NodeMapping mappings;
     378              : 
     379              :   SelfParam (Analysis::NodeMapping mappings, ImplicitSelfKind self_kind,
     380              :              tl::optional<Lifetime> lifetime, Type *type);
     381              : 
     382              : public:
     383              :   // Type-based self parameter (not ref, no lifetime)
     384              :   SelfParam (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
     385              :              bool is_mut, location_t locus);
     386              : 
     387              :   // Lifetime-based self parameter (is ref, no type)
     388              :   SelfParam (Analysis::NodeMapping mappings, tl::optional<Lifetime> lifetime,
     389              :              bool is_mut, location_t locus);
     390              : 
     391              :   // Copy constructor requires clone
     392              :   SelfParam (SelfParam const &other);
     393              : 
     394              :   // Overload assignment operator to use clone
     395              :   SelfParam &operator= (SelfParam const &other);
     396              : 
     397              :   // move constructors
     398        57145 :   SelfParam (SelfParam &&other) = default;
     399            0 :   SelfParam &operator= (SelfParam &&other) = default;
     400              : 
     401              :   // Returns whether the self-param has a type field.
     402        11400 :   bool has_type () const { return type != nullptr; }
     403              : 
     404              :   // Returns whether the self-param has a valid lifetime.
     405         7733 :   bool has_lifetime () const { return lifetime.has_value (); }
     406              : 
     407            0 :   const Lifetime &get_lifetime () const { return lifetime.value (); }
     408              : 
     409         6873 :   Lifetime &get_lifetime () { return lifetime.value (); }
     410              : 
     411              :   std::string to_string () const;
     412              : 
     413        29802 :   location_t get_locus () const { return locus; }
     414              : 
     415        15267 :   ImplicitSelfKind get_self_kind () const { return self_kind; }
     416              : 
     417            4 :   Type &get_type ()
     418              :   {
     419            4 :     rust_assert (type);
     420            4 :     return *type;
     421              :   }
     422              : 
     423        72374 :   Analysis::NodeMapping get_mappings () { return mappings; }
     424              : 
     425              :   Mutability get_mut () const;
     426              : 
     427              :   bool is_mut () const;
     428              : 
     429              :   bool is_ref () const;
     430              : };
     431              : 
     432              : // Qualifiers for function, i.e. const, unsafe, extern etc.
     433              : struct FunctionQualifiers
     434              : {
     435              : private:
     436              :   Async async_status;
     437              :   Const const_status;
     438              :   Unsafety unsafety;
     439              :   bool has_extern;
     440              :   ABI abi;
     441              : 
     442              : public:
     443        29728 :   FunctionQualifiers (Async async_status, Const const_status, Unsafety unsafety,
     444              :                       bool has_extern, ABI abi)
     445        29728 :     : async_status (async_status), const_status (const_status),
     446        29728 :       unsafety (unsafety), has_extern (has_extern), abi (abi)
     447              :   {}
     448              : 
     449              :   std::string to_string () const;
     450              : 
     451              :   Const get_const_status () const { return const_status; }
     452              : 
     453        73231 :   bool is_const () const { return const_status == Const::Yes; }
     454        20065 :   bool is_unsafe () const { return unsafety == Unsafety::Unsafe; }
     455            2 :   bool is_async () const { return async_status == Async::Yes; }
     456              : 
     457           66 :   Unsafety get_unsafety () const { return unsafety; }
     458        14308 :   ABI get_abi () const { return abi; }
     459              : };
     460              : 
     461              : // A function parameter
     462         1077 : struct FunctionParam
     463              : {
     464              :   std::unique_ptr<Pattern> param_name;
     465              :   std::unique_ptr<Type> type;
     466              :   location_t locus;
     467              :   Analysis::NodeMapping mappings;
     468              : 
     469              : public:
     470              :   FunctionParam (Analysis::NodeMapping mappings,
     471              :                  std::unique_ptr<Pattern> param_name,
     472              :                  std::unique_ptr<Type> param_type, location_t locus);
     473              : 
     474              :   // Copy constructor uses clone
     475              :   FunctionParam (FunctionParam const &other);
     476              : 
     477              :   // Overload assignment operator to use clone
     478              :   FunctionParam &operator= (FunctionParam const &other);
     479              : 
     480              :   // move constructors
     481         1074 :   FunctionParam (FunctionParam &&other) = default;
     482              :   FunctionParam &operator= (FunctionParam &&other) = default;
     483              : 
     484              :   std::string to_string () const;
     485              : 
     486        29194 :   location_t get_locus () const { return locus; }
     487              : 
     488        39443 :   Pattern &get_param_name () { return *param_name; }
     489              : 
     490        32235 :   Type &get_type ()
     491              :   {
     492        32235 :     rust_assert (type);
     493        32235 :     return *type;
     494              :   }
     495              : 
     496        38304 :   const Analysis::NodeMapping &get_mappings () const { return mappings; }
     497              : };
     498              : 
     499              : // Item that supports visibility - abstract base class
     500              : class VisItem : public Item
     501              : {
     502              :   Visibility visibility;
     503              : 
     504              : protected:
     505              :   // Visibility constructor
     506        61908 :   VisItem (Analysis::NodeMapping mappings, Visibility visibility,
     507              :            AST::AttrVec outer_attrs = AST::AttrVec ())
     508              :     : Item (std::move (mappings), std::move (outer_attrs)),
     509        61908 :       visibility (std::move (visibility))
     510        61908 :   {}
     511              : 
     512              :   // Visibility copy constructor
     513              :   VisItem (VisItem const &other);
     514              : 
     515              :   // Overload assignment operator to clone
     516              :   VisItem &operator= (VisItem const &other);
     517              : 
     518              :   // move constructors
     519              :   VisItem (VisItem &&other) = default;
     520              :   VisItem &operator= (VisItem &&other) = default;
     521              : 
     522              : public:
     523              :   using HIR::Stmt::accept_vis;
     524              : 
     525        95644 :   BaseKind get_hir_kind () override final { return VIS_ITEM; }
     526              : 
     527              :   /* Does the item have some kind of public visibility (non-default
     528              :    * visibility)? */
     529            0 :   bool has_visibility () const { return !visibility.is_error (); }
     530              : 
     531              :   virtual void accept_vis (HIRVisItemVisitor &vis) = 0;
     532              : 
     533        39445 :   Visibility &get_visibility () { return visibility; }
     534        18831 :   const Visibility &get_visibility () const { return visibility; }
     535              : 
     536              :   std::string to_string () const override;
     537              : };
     538              : 
     539              : // Rust module item - abstract base class
     540              : class Module : public VisItem, public WithInnerAttrs
     541              : {
     542              :   Identifier module_name;
     543              :   location_t locus;
     544              :   // bool has_items;
     545              :   std::vector<std::unique_ptr<Item>> items;
     546              : 
     547              : public:
     548              :   std::string to_string () const override;
     549              : 
     550              :   // Returns whether the module has items in its body.
     551              :   bool has_items () const { return !items.empty (); }
     552              : 
     553              :   // Full constructor
     554              :   Module (Analysis::NodeMapping mappings, Identifier module_name,
     555              :           location_t locus, std::vector<std::unique_ptr<Item>> items,
     556              :           Visibility visibility = Visibility::create_error (),
     557              :           AST::AttrVec inner_attrs = AST::AttrVec (),
     558              :           AST::AttrVec outer_attrs = AST::AttrVec ());
     559              : 
     560              :   // Copy constructor with vector clone
     561              :   Module (Module const &other);
     562              : 
     563              :   // Overloaded assignment operator with vector clone
     564              :   Module &operator= (Module const &other);
     565              : 
     566              :   // move constructors
     567              :   Module (Module &&other) = default;
     568              :   Module &operator= (Module &&other) = default;
     569              : 
     570              :   void accept_vis (HIRFullVisitor &vis) override;
     571              :   void accept_vis (HIRStmtVisitor &vis) override;
     572              :   void accept_vis (HIRVisItemVisitor &vis) override;
     573              : 
     574            2 :   Identifier get_module_name () const { return module_name; }
     575        14191 :   std::vector<std::unique_ptr<Item>> &get_items () { return items; };
     576              : 
     577              :   /* Override that runs the function recursively on all items contained within
     578              :    * the module. */
     579              :   void add_crate_name (std::vector<std::string> &names) const override;
     580              : 
     581         4232 :   location_t get_locus () const override final { return locus; }
     582              : 
     583            6 :   ItemKind get_item_kind () const override { return ItemKind::Module; }
     584              : 
     585              : protected:
     586              :   /* Use covariance to implement clone function as returning this object
     587              :    * rather than base */
     588            0 :   Module *clone_item_impl () const override { return new Module (*this); }
     589              : 
     590              :   /* Use covariance to implement clone function as returning this object
     591              :    * rather than base */
     592              :   /*virtual Module* clone_statement_impl() const override {
     593              :       return new Module(*this);
     594              :   }*/
     595              : };
     596              : 
     597              : // Rust extern crate declaration HIR node
     598              : class ExternCrate : public VisItem
     599              : {
     600              :   // this is either an identifier or "self", with self parsed to string
     601              :   std::string referenced_crate;
     602              :   // bool has_as_clause;
     603              :   // AsClause as_clause;
     604              :   // this is either an identifier or "_", with _ parsed to string
     605              :   std::string as_clause_name;
     606              : 
     607              :   location_t locus;
     608              : 
     609              :   /* e.g.
     610              :       "extern crate foo as _"
     611              :       "extern crate foo"
     612              :       "extern crate std as cool_std"  */
     613              : public:
     614              :   std::string to_string () const override;
     615              : 
     616              :   // Returns whether extern crate declaration has an as clause.
     617            0 :   bool has_as_clause () const { return !as_clause_name.empty (); }
     618              : 
     619              :   /* Returns whether extern crate declaration references the current crate
     620              :    * (i.e. self). */
     621            0 :   bool references_self () const { return referenced_crate == "self"; }
     622              : 
     623              :   // Constructor
     624              :   ExternCrate (Analysis::NodeMapping mappings, std::string referenced_crate,
     625              :                Visibility visibility, AST::AttrVec outer_attrs,
     626              :                location_t locus, std::string as_clause_name = std::string ())
     627              :     : VisItem (std::move (mappings), std::move (visibility),
     628              :                std::move (outer_attrs)),
     629              :       referenced_crate (std::move (referenced_crate)),
     630              :       as_clause_name (std::move (as_clause_name)), locus (locus)
     631              :   {}
     632              : 
     633            0 :   location_t get_locus () const override final { return locus; }
     634              : 
     635            0 :   ItemKind get_item_kind () const override { return ItemKind::ExternCrate; }
     636            0 :   std::string get_referenced_crate () { return referenced_crate; }
     637            0 :   std::string get_as_clause_name () { return as_clause_name; }
     638              : 
     639              :   void accept_vis (HIRFullVisitor &vis) override;
     640              :   void accept_vis (HIRStmtVisitor &vis) override;
     641              :   void accept_vis (HIRVisItemVisitor &vis) override;
     642              : 
     643              :   // Override that adds extern crate name in decl to passed list of names.
     644            0 :   void add_crate_name (std::vector<std::string> &names) const override
     645              :   {
     646            0 :     names.push_back (referenced_crate);
     647            0 :   }
     648              : 
     649              : protected:
     650              :   /* Use covariance to implement clone function as returning this object
     651              :    * rather than base */
     652            0 :   ExternCrate *clone_item_impl () const override
     653              :   {
     654            0 :     return new ExternCrate (*this);
     655              :   }
     656              : 
     657              :   /* Use covariance to implement clone function as returning this object
     658              :    * rather than base */
     659              :   /*virtual ExternCrate* clone_statement_impl() const override {
     660              :       return new ExternCrate(*this);
     661              :   }*/
     662              : };
     663              : 
     664              : // The path-ish thing referred to in a use declaration - abstract base class
     665            0 : class UseTree : public FullVisitable
     666              : {
     667              :   location_t locus;
     668              : 
     669              : public:
     670              :   virtual ~UseTree () {}
     671              : 
     672              :   // Unique pointer custom clone function
     673            0 :   std::unique_ptr<UseTree> clone_use_tree () const
     674              :   {
     675            0 :     return std::unique_ptr<UseTree> (clone_use_tree_impl ());
     676              :   }
     677              : 
     678              :   virtual std::string to_string () const = 0;
     679              : 
     680              :   location_t get_locus () const { return locus; }
     681              : 
     682              : protected:
     683              :   // Clone function implementation as pure virtual method
     684              :   virtual UseTree *clone_use_tree_impl () const = 0;
     685              : 
     686              :   UseTree (location_t locus) : locus (locus) {}
     687              : };
     688              : 
     689              : // Use tree with a glob (wildcard) operator
     690              : class UseTreeGlob : public UseTree
     691              : {
     692              : public:
     693              :   enum PathType
     694              :   {
     695              :     NO_PATH,
     696              :     GLOBAL,
     697              :     PATH_PREFIXED
     698              :   };
     699              : 
     700              : private:
     701              :   PathType glob_type;
     702              :   AST::SimplePath path;
     703              : 
     704              : public:
     705              :   UseTreeGlob (PathType glob_type, AST::SimplePath path, location_t locus)
     706              :     : UseTree (locus), glob_type (glob_type), path (std::move (path))
     707              :   {
     708              :     if (this->glob_type != PATH_PREFIXED)
     709              :       {
     710              :         // compiler implementation error if there is a path with a
     711              :         // non-path-prefixed use tree glob
     712              :         gcc_assert (!has_path ());
     713              :       }
     714              :     // TODO: do path-prefixed paths also have to have a path? If so, have an
     715              :     // assert for that too.
     716              :   }
     717              : 
     718              :   /* Returns whether has path. Should be made redundant by PathType
     719              :    * PATH_PREFIXED. */
     720              :   bool has_path () const { return !path.is_empty (); }
     721              : 
     722            0 :   PathType get_glob_type () { return glob_type; }
     723            0 :   AST::SimplePath get_path () { return path; };
     724              : 
     725              :   std::string to_string () const override;
     726              : 
     727              :   void accept_vis (HIRFullVisitor &vis) override;
     728              : 
     729              :   /* TODO: find way to ensure only PATH_PREFIXED glob_type has path - factory
     730              :    * methods? */
     731              : protected:
     732              :   /* Use covariance to implement clone function as returning this object
     733              :    * rather than base */
     734            0 :   UseTreeGlob *clone_use_tree_impl () const override
     735              :   {
     736            0 :     return new UseTreeGlob (*this);
     737              :   }
     738              : };
     739              : 
     740              : // Use tree with a list of paths with a common prefix
     741              : class UseTreeList : public UseTree
     742              : {
     743              : public:
     744              :   enum PathType
     745              :   {
     746              :     NO_PATH,
     747              :     GLOBAL,
     748              :     PATH_PREFIXED
     749              :   };
     750              : 
     751              : private:
     752              :   PathType path_type;
     753              :   AST::SimplePath path;
     754              : 
     755              :   std::vector<std::unique_ptr<UseTree>> trees;
     756              : 
     757              : public:
     758              :   UseTreeList (PathType path_type, AST::SimplePath path,
     759              :                std::vector<std::unique_ptr<UseTree>> trees, location_t locus)
     760              :     : UseTree (locus), path_type (path_type), path (std::move (path)),
     761              :       trees (std::move (trees))
     762              :   {
     763              :     if (this->path_type != PATH_PREFIXED)
     764              :       {
     765              :         // compiler implementation error if there is a path with a
     766              :         // non-path-prefixed use tree glob
     767              :         gcc_assert (!has_path ());
     768              :       }
     769              :     // TODO: do path-prefixed paths also have to have a path? If so, have an
     770              :     // assert for that too.
     771              :   }
     772              : 
     773              :   // copy constructor with vector clone
     774            0 :   UseTreeList (UseTreeList const &other)
     775            0 :     : UseTree (other), path_type (other.path_type), path (other.path)
     776              :   {
     777            0 :     trees.reserve (other.trees.size ());
     778            0 :     for (const auto &e : other.trees)
     779            0 :       trees.push_back (e->clone_use_tree ());
     780            0 :   }
     781              : 
     782              :   // overloaded assignment operator with vector clone
     783              :   UseTreeList &operator= (UseTreeList const &other)
     784              :   {
     785              :     UseTree::operator= (other);
     786              :     path_type = other.path_type;
     787              :     path = other.path;
     788              : 
     789              :     trees.reserve (other.trees.size ());
     790              :     for (const auto &e : other.trees)
     791              :       trees.push_back (e->clone_use_tree ());
     792              : 
     793              :     return *this;
     794              :   }
     795              : 
     796              :   // move constructors
     797              :   UseTreeList (UseTreeList &&other) = default;
     798              :   UseTreeList &operator= (UseTreeList &&other) = default;
     799              : 
     800              :   // Returns whether has path. Should be made redundant by path_type.
     801              :   bool has_path () const { return !path.is_empty (); }
     802              : 
     803              :   // Returns whether has inner tree elements.
     804            0 :   bool has_trees () const { return !trees.empty (); }
     805              : 
     806              :   std::string to_string () const override;
     807              : 
     808              :   void accept_vis (HIRFullVisitor &vis) override;
     809              : 
     810            0 :   PathType get_path_type () { return path_type; }
     811            0 :   AST::SimplePath get_path () { return path; }
     812            0 :   std::vector<std::unique_ptr<UseTree>> &get_trees () { return trees; }
     813              : 
     814              :   // TODO: find way to ensure only PATH_PREFIXED path_type has path - factory
     815              :   // methods?
     816              : protected:
     817              :   /* Use covariance to implement clone function as returning this object
     818              :    * rather than base */
     819            0 :   UseTreeList *clone_use_tree_impl () const override
     820              :   {
     821            0 :     return new UseTreeList (*this);
     822              :   }
     823              : };
     824              : 
     825              : // Use tree where it rebinds the module name as something else
     826              : class UseTreeRebind : public UseTree
     827              : {
     828              : public:
     829              :   enum NewBindType
     830              :   {
     831              :     NONE,
     832              :     IDENTIFIER,
     833              :     WILDCARD
     834              :   };
     835              : 
     836              : private:
     837              :   AST::SimplePath path;
     838              : 
     839              :   NewBindType bind_type;
     840              :   Identifier identifier; // only if NewBindType is IDENTIFIER
     841              : 
     842              : public:
     843              :   UseTreeRebind (NewBindType bind_type, AST::SimplePath path, location_t locus,
     844              :                  Identifier identifier = std::string ())
     845              :     : UseTree (locus), path (std::move (path)), bind_type (bind_type),
     846              :       identifier (std::move (identifier))
     847              :   {}
     848              : 
     849              :   // Returns whether has path (this should always be true).
     850              :   bool has_path () const { return !path.is_empty (); }
     851              : 
     852            0 :   AST::SimplePath get_path () { return path; }
     853              : 
     854            0 :   Identifier get_identifier () const { return identifier; }
     855              : 
     856            0 :   NewBindType get_bind_type () const { return bind_type; }
     857              : 
     858              :   // Returns whether has identifier (or, rather, is allowed to).
     859              :   bool has_identifier () const { return bind_type == IDENTIFIER; }
     860              : 
     861              :   std::string to_string () const override;
     862              : 
     863              :   void accept_vis (HIRFullVisitor &vis) override;
     864              : 
     865              :   // TODO: find way to ensure only PATH_PREFIXED path_type has path - factory
     866              :   // methods?
     867              : protected:
     868              :   /* Use covariance to implement clone function as returning this object
     869              :    * rather than base */
     870            0 :   virtual UseTreeRebind *clone_use_tree_impl () const override
     871              :   {
     872            0 :     return new UseTreeRebind (*this);
     873              :   }
     874              : };
     875              : 
     876              : std::string enum_to_str (UseTreeRebind::NewBindType);
     877              : 
     878              : // Rust use declaration (i.e. for modules) HIR node
     879              : class UseDeclaration : public VisItem
     880              : {
     881              :   std::unique_ptr<UseTree> use_tree;
     882              :   location_t locus;
     883              : 
     884              : public:
     885              :   std::string to_string () const override;
     886              : 
     887              :   UseDeclaration (Analysis::NodeMapping mappings,
     888              :                   std::unique_ptr<UseTree> use_tree, Visibility visibility,
     889              :                   AST::AttrVec outer_attrs, location_t locus)
     890              :     : VisItem (std::move (mappings), std::move (visibility),
     891              :                std::move (outer_attrs)),
     892              :       use_tree (std::move (use_tree)), locus (locus)
     893              :   {}
     894              : 
     895              :   // Copy constructor with clone
     896            0 :   UseDeclaration (UseDeclaration const &other)
     897            0 :     : VisItem (other), use_tree (other.use_tree->clone_use_tree ()),
     898            0 :       locus (other.locus)
     899            0 :   {}
     900              : 
     901              :   // Overloaded assignment operator to clone
     902              :   UseDeclaration &operator= (UseDeclaration const &other)
     903              :   {
     904              :     VisItem::operator= (other);
     905              :     use_tree = other.use_tree->clone_use_tree ();
     906              :     // visibility = other.visibility->clone_visibility();
     907              :     // outer_attrs = other.outer_attrs;
     908              :     locus = other.locus;
     909              : 
     910              :     return *this;
     911              :   }
     912              : 
     913              :   // move constructors
     914              :   UseDeclaration (UseDeclaration &&other) = default;
     915              :   UseDeclaration &operator= (UseDeclaration &&other) = default;
     916              : 
     917            0 :   location_t get_locus () const override final { return locus; }
     918            0 :   ItemKind get_item_kind () const override { return ItemKind::UseDeclaration; }
     919              : 
     920            0 :   UseTree &get_use_tree () { return *use_tree; }
     921              :   void accept_vis (HIRFullVisitor &vis) override;
     922              :   void accept_vis (HIRStmtVisitor &vis) override;
     923              :   void accept_vis (HIRVisItemVisitor &vis) override;
     924              : 
     925              : protected:
     926              :   /* Use covariance to implement clone function as returning this object
     927              :    * rather than base */
     928            0 :   UseDeclaration *clone_item_impl () const override
     929              :   {
     930            0 :     return new UseDeclaration (*this);
     931              :   }
     932              : 
     933              :   /* Use covariance to implement clone function as returning this object
     934              :    * rather than base */
     935              :   /*virtual UseDeclaration* clone_statement_impl() const override {
     936              :       return new UseDeclaration(*this);
     937              :   }*/
     938              : };
     939              : 
     940              : class LetStmt;
     941              : 
     942              : enum class Defaultness
     943              : {
     944              :   Default,
     945              :   Final,
     946              : };
     947              : 
     948              : // Rust function declaration HIR node
     949              : class Function : public VisItem, public ImplItem
     950              : {
     951              :   FunctionQualifiers qualifiers;
     952              :   Identifier function_name;
     953              :   std::vector<std::unique_ptr<GenericParam>> generic_params;
     954              :   std::vector<FunctionParam> function_params;
     955              :   std::unique_ptr<Type> return_type;
     956              :   WhereClause where_clause;
     957              :   std::unique_ptr<BlockExpr> function_body;
     958              :   tl::optional<SelfParam> self;
     959              :   location_t locus;
     960              : 
     961              :   // NOTE: This should be moved to the trait item base class once we start
     962              :   // implementing specialization for real, instead of just stubbing out the
     963              :   // feature
     964              :   Defaultness defaultness;
     965              : 
     966              : public:
     967              :   std::string to_string () const override;
     968              : 
     969              :   tl::optional<std::vector<size_t>> get_legacy_const_generic_indexes () const;
     970              : 
     971              :   // Returns whether function has generic parameters.
     972        14901 :   bool has_generics () const { return !generic_params.empty (); }
     973              : 
     974              :   // Returns whether function has regular parameters.
     975            0 :   bool has_function_params () const { return !function_params.empty (); }
     976              : 
     977              :   // Returns whether function has return type - if not, it is void.
     978        29743 :   bool has_function_return_type () const { return return_type != nullptr; }
     979              : 
     980              :   // Returns whether function has a where clause.
     981        14170 :   bool has_where_clause () const { return !where_clause.is_empty (); }
     982              : 
     983              :   // Returns whether function has a default qualifier
     984           43 :   bool is_default () const { return defaultness == Defaultness::Default; }
     985              : 
     986        76354 :   ImplItemType get_impl_item_type () const override final
     987              :   {
     988        76354 :     return ImplItem::ImplItemType::FUNCTION;
     989              :   }
     990              : 
     991        11930 :   ItemKind get_item_kind () const override { return ItemKind::Function; }
     992              : 
     993              :   // Mega-constructor with all possible fields
     994              :   Function (Analysis::NodeMapping mappings, Identifier function_name,
     995              :             FunctionQualifiers qualifiers,
     996              :             std::vector<std::unique_ptr<GenericParam>> generic_params,
     997              :             std::vector<FunctionParam> function_params,
     998              :             std::unique_ptr<Type> return_type, WhereClause where_clause,
     999              :             std::unique_ptr<BlockExpr> function_body, Visibility vis,
    1000              :             AST::AttrVec outer_attrs, tl::optional<SelfParam> self,
    1001              :             Defaultness defaultness, location_t locus);
    1002              : 
    1003              :   // Copy constructor with clone
    1004              :   Function (Function const &other);
    1005              : 
    1006              :   // Overloaded assignment operator to clone
    1007              :   Function &operator= (Function const &other);
    1008              : 
    1009              :   // move constructors
    1010              :   Function (Function &&other) = default;
    1011              :   Function &operator= (Function &&other) = default;
    1012              : 
    1013       104407 :   location_t get_locus () const override final { return locus; }
    1014              : 
    1015              :   void accept_vis (HIRFullVisitor &vis) override;
    1016              :   void accept_vis (HIRImplVisitor &vis) override;
    1017              :   void accept_vis (HIRStmtVisitor &vis) override;
    1018              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1019              : 
    1020       187315 :   Analysis::NodeMapping get_impl_mappings () const override
    1021              :   {
    1022       187315 :     return get_mappings ();
    1023              :   };
    1024              : 
    1025       112712 :   std::vector<FunctionParam> &get_function_params () { return function_params; }
    1026              :   const std::vector<FunctionParam> &get_function_params () const
    1027              :   {
    1028              :     return function_params;
    1029              :   }
    1030              : 
    1031        22015 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    1032              :   {
    1033        36185 :     return generic_params;
    1034              :   }
    1035              :   const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
    1036              :   {
    1037              :     return generic_params;
    1038              :   }
    1039              : 
    1040              :   // TODO: is this better? Or is a "vis_block" better?
    1041       142981 :   BlockExpr &get_definition () { return *function_body; }
    1042              : 
    1043        13983 :   const FunctionQualifiers &get_qualifiers () const { return qualifiers; }
    1044              : 
    1045       123459 :   Identifier get_function_name () const { return function_name; }
    1046              : 
    1047              :   // TODO: is this better? Or is a "vis_block" better?
    1048        14912 :   WhereClause &get_where_clause () { return where_clause; }
    1049              : 
    1050        14173 :   bool has_return_type () const { return return_type != nullptr; }
    1051              : 
    1052              :   // TODO: is this better? Or is a "vis_block" better?
    1053        43261 :   Type &get_return_type () { return *return_type; }
    1054              : 
    1055        60204 :   bool is_method () const { return self.has_value (); }
    1056              : 
    1057        13983 :   tl::optional<SelfParam> &get_self_param () { return self; }
    1058              :   const tl::optional<SelfParam> &get_self_param () const { return self; }
    1059              : 
    1060        35686 :   SelfParam &get_self_param_unchecked () { return self.value (); }
    1061              :   const SelfParam &get_self_param_unchecked () const { return self.value (); }
    1062              : 
    1063        38745 :   std::string get_impl_item_name () const override final
    1064              :   {
    1065        77490 :     return get_function_name ().as_string ();
    1066              :   }
    1067              : 
    1068              : protected:
    1069              :   /* Use covariance to implement clone function as returning this object
    1070              :    * rather than base */
    1071            0 :   Function *clone_item_impl () const override { return new Function (*this); }
    1072              : 
    1073              :   /* Use covariance to implement clone function as returning this object
    1074              :    * rather than base */
    1075            0 :   Function *clone_inherent_impl_item_impl () const override
    1076              :   {
    1077            0 :     return new Function (*this);
    1078              :   }
    1079              : };
    1080              : 
    1081              : // Rust type alias (i.e. typedef) HIR node
    1082              : class TypeAlias : public VisItem, public ImplItem
    1083              : {
    1084              :   Identifier new_type_name;
    1085              : 
    1086              :   // bool has_generics;
    1087              :   // Generics generic_params;
    1088              :   std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
    1089              : 
    1090              :   // bool has_where_clause;
    1091              :   WhereClause where_clause;
    1092              : 
    1093              :   std::unique_ptr<Type> existing_type;
    1094              : 
    1095              :   location_t locus;
    1096              : 
    1097              : public:
    1098              :   std::string to_string () const override;
    1099              : 
    1100              :   // Returns whether type alias has generic parameters.
    1101         3672 :   bool has_generics () const { return !generic_params.empty (); }
    1102              : 
    1103              :   // Returns whether type alias has a where clause.
    1104         1458 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    1105              : 
    1106        19355 :   ImplItemType get_impl_item_type () const override final
    1107              :   {
    1108        19355 :     return ImplItem::ImplItemType::TYPE_ALIAS;
    1109              :   }
    1110              : 
    1111              :   // Mega-constructor with all possible fields
    1112              :   TypeAlias (Analysis::NodeMapping mappings, Identifier new_type_name,
    1113              :              std::vector<std::unique_ptr<GenericParam>> generic_params,
    1114              :              WhereClause where_clause, std::unique_ptr<Type> existing_type,
    1115              :              Visibility vis, AST::AttrVec outer_attrs, location_t locus);
    1116              : 
    1117              :   // Copy constructor
    1118              :   TypeAlias (TypeAlias const &other);
    1119              : 
    1120              :   // Overloaded assignment operator to clone
    1121              :   TypeAlias &operator= (TypeAlias const &other);
    1122              : 
    1123              :   // move constructors
    1124              :   TypeAlias (TypeAlias &&other) = default;
    1125              :   TypeAlias &operator= (TypeAlias &&other) = default;
    1126              : 
    1127        10565 :   location_t get_locus () const override final { return locus; }
    1128              : 
    1129              :   void accept_vis (HIRFullVisitor &vis) override;
    1130              :   void accept_vis (HIRImplVisitor &vis) override;
    1131              :   void accept_vis (HIRStmtVisitor &vis) override;
    1132              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1133              : 
    1134         1577 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    1135              :   {
    1136         3035 :     return generic_params;
    1137              :   }
    1138              :   const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
    1139              :   {
    1140              :     return generic_params;
    1141              :   }
    1142              : 
    1143         1495 :   WhereClause &get_where_clause () { return where_clause; }
    1144              : 
    1145         2967 :   Type &get_type_aliased ()
    1146              :   {
    1147         2967 :     rust_assert (existing_type);
    1148         2967 :     return *existing_type;
    1149              :   }
    1150              : 
    1151        12993 :   Identifier get_new_type_name () const { return new_type_name; }
    1152              : 
    1153            7 :   ItemKind get_item_kind () const override { return ItemKind::TypeAlias; }
    1154              : 
    1155        45463 :   Analysis::NodeMapping get_impl_mappings () const override
    1156              :   {
    1157        45463 :     return get_mappings ();
    1158              :   };
    1159              : 
    1160        10454 :   std::string get_impl_item_name () const override final
    1161              :   {
    1162        20908 :     return get_new_type_name ().as_string ();
    1163              :   }
    1164              : 
    1165              : protected:
    1166              :   /* Use covariance to implement clone function as returning this object
    1167              :    * rather than base */
    1168            0 :   TypeAlias *clone_item_impl () const override { return new TypeAlias (*this); }
    1169              : 
    1170              :   /* Use covariance to implement clone function as returning this object
    1171              :    * rather than base */
    1172            0 :   TypeAlias *clone_inherent_impl_item_impl () const override
    1173              :   {
    1174            0 :     return new TypeAlias (*this);
    1175              :   }
    1176              : };
    1177              : 
    1178              : // Rust base struct declaration HIR node - abstract base class
    1179              : class Struct : public VisItem
    1180              : {
    1181              : protected:
    1182              :   // protected to enable access by derived classes - allows better to_string
    1183              :   Identifier struct_name;
    1184              : 
    1185              :   // bool has_generics;
    1186              :   // Generics generic_params;
    1187              :   std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
    1188              : 
    1189              :   // bool has_where_clause;
    1190              :   WhereClause where_clause;
    1191              : 
    1192              :   location_t locus;
    1193              : 
    1194              : public:
    1195         6018 :   Identifier get_identifier () const { return struct_name; }
    1196              : 
    1197              :   // Returns whether struct has generic parameters.
    1198         2754 :   bool has_generics () const { return !generic_params.empty (); }
    1199              : 
    1200              :   // Returns whether struct has a where clause.
    1201         2564 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    1202              : 
    1203        15728 :   location_t get_locus () const override final { return locus; }
    1204         7149 :   ItemKind get_item_kind () const override { return ItemKind::Struct; }
    1205              : 
    1206         4961 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    1207              :   {
    1208         7525 :     return generic_params;
    1209              :   }
    1210              : 
    1211         2759 :   WhereClause &get_where_clause () { return where_clause; }
    1212              : 
    1213              : protected:
    1214         3449 :   Struct (Analysis::NodeMapping mappings, Identifier struct_name,
    1215              :           std::vector<std::unique_ptr<GenericParam>> generic_params,
    1216              :           WhereClause where_clause, Visibility vis, location_t locus,
    1217              :           AST::AttrVec outer_attrs = AST::AttrVec ())
    1218              :     : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
    1219         6898 :       struct_name (std::move (struct_name)),
    1220         3449 :       generic_params (std::move (generic_params)),
    1221         3449 :       where_clause (std::move (where_clause)), locus (locus)
    1222         3449 :   {}
    1223              : 
    1224              :   // Copy constructor with vector clone
    1225            0 :   Struct (Struct const &other)
    1226            0 :     : VisItem (other), struct_name (other.struct_name),
    1227            0 :       where_clause (other.where_clause), locus (other.locus)
    1228              :   {
    1229            0 :     generic_params.reserve (other.generic_params.size ());
    1230            0 :     for (const auto &e : other.generic_params)
    1231            0 :       generic_params.push_back (e->clone_generic_param ());
    1232            0 :   }
    1233              : 
    1234              :   // Overloaded assignment operator with vector clone
    1235              :   Struct &operator= (Struct const &other)
    1236              :   {
    1237              :     VisItem::operator= (other);
    1238              :     struct_name = other.struct_name;
    1239              :     where_clause = other.where_clause;
    1240              :     locus = other.locus;
    1241              : 
    1242              :     generic_params.reserve (other.generic_params.size ());
    1243              :     for (const auto &e : other.generic_params)
    1244              :       generic_params.push_back (e->clone_generic_param ());
    1245              : 
    1246              :     return *this;
    1247              :   }
    1248              : 
    1249              :   // move constructors
    1250              :   Struct (Struct &&other) = default;
    1251              :   Struct &operator= (Struct &&other) = default;
    1252              : };
    1253              : 
    1254              : // A single field in a struct
    1255              : // FIXME can't this be a TupleStruct + field_name?
    1256              : class StructField
    1257              : {
    1258              : public:
    1259              :   // bool has_outer_attributes;
    1260              :   AST::AttrVec outer_attrs;
    1261              : 
    1262              :   // bool has_visibility;
    1263              :   Visibility visibility;
    1264              : 
    1265              :   Identifier field_name;
    1266              :   std::unique_ptr<Type> field_type;
    1267              : 
    1268              :   Analysis::NodeMapping mappings;
    1269              : 
    1270              :   location_t locus;
    1271              : 
    1272              :   // Returns whether struct field has any outer attributes.
    1273              :   bool has_outer_attributes () const { return !outer_attrs.empty (); }
    1274              : 
    1275              :   // Returns whether struct field has a non-private (non-default) visibility.
    1276            0 :   bool has_visibility () const { return !visibility.is_error (); }
    1277              : 
    1278              :   StructField (Analysis::NodeMapping mappings, Identifier field_name,
    1279              :                std::unique_ptr<Type> field_type, Visibility vis,
    1280              :                location_t locus, AST::AttrVec outer_attrs = AST::AttrVec ());
    1281              : 
    1282              :   // Copy constructor
    1283              :   StructField (StructField const &other);
    1284              : 
    1285         4522 :   ~StructField () = default;
    1286              : 
    1287              :   // Overloaded assignment operator to clone
    1288              :   StructField &operator= (StructField const &other);
    1289              : 
    1290              :   // move constructors
    1291         4492 :   StructField (StructField &&other) = default;
    1292              :   StructField &operator= (StructField &&other) = default;
    1293              : 
    1294              :   std::string to_string () const;
    1295              : 
    1296         7869 :   Identifier get_field_name () const { return field_name; }
    1297              : 
    1298         5059 :   Type &get_field_type () { return *field_type; }
    1299              : 
    1300         6611 :   Analysis::NodeMapping get_mappings () const { return mappings; }
    1301              : 
    1302         2947 :   location_t get_locus () { return locus; }
    1303            0 :   AST::AttrVec &get_outer_attrs () { return outer_attrs; }
    1304            0 :   Visibility &get_visibility () { return visibility; }
    1305              : };
    1306              : 
    1307              : // Rust struct declaration with true struct type HIR node
    1308              : class StructStruct : public Struct
    1309              : {
    1310              : public:
    1311              :   std::vector<StructField> fields;
    1312              :   bool is_unit;
    1313              : 
    1314              :   std::string to_string () const override;
    1315              : 
    1316              :   // Mega-constructor with all possible fields
    1317         2323 :   StructStruct (Analysis::NodeMapping mappings, std::vector<StructField> fields,
    1318              :                 Identifier struct_name,
    1319              :                 std::vector<std::unique_ptr<GenericParam>> generic_params,
    1320              :                 WhereClause where_clause, bool is_unit, Visibility vis,
    1321              :                 AST::AttrVec outer_attrs, location_t locus)
    1322              :     : Struct (std::move (mappings), std::move (struct_name),
    1323              :               std::move (generic_params), std::move (where_clause),
    1324              :               std::move (vis), locus, std::move (outer_attrs)),
    1325         2323 :       fields (std::move (fields)), is_unit (is_unit)
    1326         2323 :   {}
    1327              : 
    1328              :   // Unit struct constructor
    1329              :   StructStruct (Analysis::NodeMapping mappings, Identifier struct_name,
    1330              :                 std::vector<std::unique_ptr<GenericParam>> generic_params,
    1331              :                 WhereClause where_clause, Visibility vis,
    1332              :                 AST::AttrVec outer_attrs, location_t locus)
    1333              :     : Struct (std::move (mappings), std::move (struct_name),
    1334              :               std::move (generic_params), std::move (where_clause),
    1335              :               std::move (vis), locus, std::move (outer_attrs)),
    1336              :       is_unit (true)
    1337              :   {}
    1338              :   // TODO: can a unit struct have generic fields? assuming yes for now.
    1339              : 
    1340              :   /* Returns whether the struct is a unit struct - struct defined without
    1341              :    * fields. This is important because it also means an implicit constant of its
    1342              :    * type is defined. */
    1343         1726 :   bool is_unit_struct () const { return is_unit; }
    1344              : 
    1345              :   void accept_vis (HIRFullVisitor &vis) override;
    1346              :   void accept_vis (HIRStmtVisitor &vis) override;
    1347              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1348              : 
    1349         4925 :   std::vector<StructField> &get_fields () { return fields; }
    1350              : 
    1351              : protected:
    1352              :   /* Use covariance to implement clone function as returning this object
    1353              :    * rather than base */
    1354            0 :   StructStruct *clone_item_impl () const override
    1355              :   {
    1356            0 :     return new StructStruct (*this);
    1357              :   }
    1358              : 
    1359              :   /* Use covariance to implement clone function as returning this object
    1360              :    * rather than base */
    1361              :   /*virtual StructStruct* clone_statement_impl() const override {
    1362              :       return new StructStruct(*this);
    1363              :   }*/
    1364              : };
    1365              : 
    1366              : // A single field in a tuple
    1367              : class TupleField
    1368              : {
    1369              : private:
    1370              :   // bool has_outer_attributes;
    1371              :   AST::AttrVec outer_attrs;
    1372              : 
    1373              :   // bool has_visibility;
    1374              :   Visibility visibility;
    1375              : 
    1376              :   std::unique_ptr<Type> field_type;
    1377              : 
    1378              :   location_t locus;
    1379              : 
    1380              :   Analysis::NodeMapping mappings;
    1381              : 
    1382              : public:
    1383              :   // Returns whether tuple field has outer attributes.
    1384              :   bool has_outer_attributes () const { return !outer_attrs.empty (); }
    1385              : 
    1386              :   /* Returns whether tuple field has a non-default visibility (i.e. a public
    1387              :    * one) */
    1388            0 :   bool has_visibility () const { return !visibility.is_error (); }
    1389              : 
    1390              :   // Complete constructor
    1391              :   TupleField (Analysis::NodeMapping mapping, std::unique_ptr<Type> field_type,
    1392              :               Visibility vis, location_t locus,
    1393              :               AST::AttrVec outer_attrs = AST::AttrVec ());
    1394              : 
    1395              :   // Copy constructor with clone
    1396              :   TupleField (TupleField const &other);
    1397              : 
    1398           10 :   ~TupleField () = default;
    1399              : 
    1400              :   // Overloaded assignment operator to clone
    1401              :   TupleField &operator= (TupleField const &other);
    1402              : 
    1403              :   // move constructors
    1404            0 :   TupleField (TupleField &&other) = default;
    1405              :   TupleField &operator= (TupleField &&other) = default;
    1406              : 
    1407              :   // Returns whether tuple field is in an error state.
    1408              :   bool is_error () const { return field_type == nullptr; }
    1409              : 
    1410              :   std::string to_string () const;
    1411              : 
    1412         4976 :   Analysis::NodeMapping get_mappings () const { return mappings; }
    1413              : 
    1414            0 :   Visibility &get_visibility () { return visibility; }
    1415              : 
    1416         2268 :   location_t get_locus () const { return locus; }
    1417              : 
    1418            0 :   AST::AttrVec &get_outer_attrs () { return outer_attrs; }
    1419         4391 :   HIR::Type &get_field_type () { return *field_type; }
    1420              : };
    1421              : 
    1422              : // Rust tuple declared using struct keyword HIR node
    1423              : class TupleStruct : public Struct
    1424              : {
    1425              :   std::vector<TupleField> fields;
    1426              : 
    1427              : public:
    1428              :   std::string to_string () const override;
    1429              : 
    1430              :   // Mega-constructor with all possible fields
    1431              :   TupleStruct (Analysis::NodeMapping mappings, std::vector<TupleField> fields,
    1432              :                Identifier struct_name,
    1433              :                std::vector<std::unique_ptr<GenericParam>> generic_params,
    1434              :                WhereClause where_clause, Visibility vis,
    1435              :                AST::AttrVec outer_attrs, location_t locus);
    1436              : 
    1437              :   void accept_vis (HIRFullVisitor &vis) override;
    1438              :   void accept_vis (HIRStmtVisitor &vis) override;
    1439              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1440              : 
    1441         1997 :   std::vector<TupleField> &get_fields () { return fields; }
    1442              :   const std::vector<TupleField> &get_fields () const { return fields; }
    1443              : 
    1444              : protected:
    1445              :   /* Use covariance to implement clone function as returning this object
    1446              :    * rather than base */
    1447            0 :   TupleStruct *clone_item_impl () const override
    1448              :   {
    1449            0 :     return new TupleStruct (*this);
    1450              :   }
    1451              : 
    1452              :   /* Use covariance to implement clone function as returning this object
    1453              :    * rather than base */
    1454              :   /*virtual TupleStruct* clone_statement_impl() const override {
    1455              :       return new TupleStruct(*this);
    1456              :   }*/
    1457              : };
    1458              : 
    1459              : /* An item used in an "enum" tagged union - not abstract: base represents a
    1460              :    name-only enum. Syntactically EnumItem's can have a Visibility. But not
    1461              :    Semantically. So check there is no Visibility when lowering and make this
    1462              :    an Item, not an VisItem.  */
    1463              : class EnumItem : public Item
    1464              : {
    1465              :   Identifier variant_name;
    1466              :   location_t locus;
    1467              : 
    1468              : public:
    1469           29 :   virtual ~EnumItem () {}
    1470              : 
    1471              :   enum EnumItemKind
    1472              :   {
    1473              :     Named,
    1474              :     Tuple,
    1475              :     Struct,
    1476              :     Discriminant,
    1477              :   };
    1478              : 
    1479              :   EnumItem (Analysis::NodeMapping mappings, Identifier variant_name,
    1480              :             AST::AttrVec outer_attrs, location_t locus);
    1481              : 
    1482              :   // Unique pointer custom clone function
    1483            3 :   std::unique_ptr<EnumItem> clone_enum_item () const
    1484              :   {
    1485            3 :     return std::unique_ptr<EnumItem> (clone_item_impl ());
    1486              :   }
    1487              : 
    1488              :   virtual std::string to_string () const override;
    1489          921 :   virtual EnumItemKind get_enum_item_kind () const { return Named; };
    1490              : 
    1491              :   // not pure virtual as not abstract
    1492              :   void accept_vis (HIRFullVisitor &vis) override;
    1493              :   void accept_vis (HIRStmtVisitor &vis) override;
    1494              :   // void accept_vis (HIRVisItemVisitor &vis) override;
    1495              : 
    1496         3995 :   location_t get_locus () const override { return locus; }
    1497              : 
    1498         1294 :   Identifier get_identifier () const { return variant_name; }
    1499              : 
    1500            0 :   ItemKind get_item_kind () const override { return ItemKind::EnumItem; }
    1501              : 
    1502              : protected:
    1503            1 :   EnumItem *clone_item_impl () const override { return new EnumItem (*this); }
    1504              : };
    1505              : 
    1506              : // A tuple item used in an "enum" tagged union
    1507              : class EnumItemTuple : public EnumItem
    1508              : {
    1509              :   // bool has_tuple_fields;
    1510              :   std::vector<TupleField> tuple_fields;
    1511              : 
    1512              : public:
    1513              :   // Returns whether tuple enum item has tuple fields.
    1514            0 :   bool has_tuple_fields () const { return !tuple_fields.empty (); }
    1515              : 
    1516          863 :   EnumItemKind get_enum_item_kind () const override
    1517              :   {
    1518          863 :     return EnumItemKind::Tuple;
    1519              :   }
    1520              : 
    1521              :   EnumItemTuple (Analysis::NodeMapping mappings, Identifier variant_name,
    1522              :                  std::vector<TupleField> tuple_fields, AST::AttrVec outer_attrs,
    1523              :                  location_t locus);
    1524              : 
    1525              :   std::string to_string () const override;
    1526              : 
    1527              :   void accept_vis (HIRFullVisitor &vis) override;
    1528              :   void accept_vis (HIRStmtVisitor &vis) override;
    1529              : 
    1530         1278 :   std::vector<TupleField> &get_tuple_fields () { return tuple_fields; }
    1531              : 
    1532              : protected:
    1533              :   // Clone function implementation as (not pure) virtual method
    1534            1 :   EnumItemTuple *clone_item_impl () const override
    1535              :   {
    1536            1 :     return new EnumItemTuple (*this);
    1537              :   }
    1538              : };
    1539              : 
    1540              : // A struct item used in an "enum" tagged union
    1541              : class EnumItemStruct : public EnumItem
    1542              : {
    1543              :   // bool has_struct_fields;
    1544              :   std::vector<StructField> struct_fields;
    1545              : 
    1546              : public:
    1547              :   // Returns whether struct enum item has struct fields.
    1548            0 :   bool has_struct_fields () const { return !struct_fields.empty (); }
    1549              : 
    1550          165 :   EnumItemKind get_enum_item_kind () const override
    1551              :   {
    1552          165 :     return EnumItemKind::Struct;
    1553              :   }
    1554              : 
    1555              :   EnumItemStruct (Analysis::NodeMapping mappings, Identifier variant_name,
    1556              :                   std::vector<StructField> struct_fields,
    1557              :                   AST::AttrVec outer_attrs, location_t locus);
    1558              : 
    1559              :   std::string to_string () const override;
    1560              : 
    1561              :   void accept_vis (HIRFullVisitor &vis) override;
    1562              :   void accept_vis (HIRStmtVisitor &vis) override;
    1563              : 
    1564          244 :   std::vector<StructField> &get_struct_fields () { return struct_fields; }
    1565              : 
    1566              : protected:
    1567              :   // Clone function implementation as (not pure) virtual method
    1568            0 :   EnumItemStruct *clone_item_impl () const override
    1569              :   {
    1570            0 :     return new EnumItemStruct (*this);
    1571              :   }
    1572              : };
    1573              : 
    1574              : // A discriminant (numbered enum) item used in an "enum" tagged union
    1575              : class EnumItemDiscriminant : public EnumItem
    1576              : {
    1577              :   std::unique_ptr<Expr> expression;
    1578              : 
    1579              : public:
    1580              :   EnumItemDiscriminant (Analysis::NodeMapping mappings, Identifier variant_name,
    1581              :                         std::unique_ptr<Expr> expr, AST::AttrVec outer_attrs,
    1582              :                         location_t locus);
    1583              : 
    1584              :   // Copy constructor with clone
    1585              :   EnumItemDiscriminant (EnumItemDiscriminant const &other);
    1586              : 
    1587              :   // Overloaded assignment operator to clone
    1588              :   EnumItemDiscriminant &operator= (EnumItemDiscriminant const &other);
    1589              : 
    1590              :   // move constructors
    1591              :   EnumItemDiscriminant (EnumItemDiscriminant &&other) = default;
    1592              :   EnumItemDiscriminant &operator= (EnumItemDiscriminant &&other) = default;
    1593              : 
    1594          559 :   EnumItemKind get_enum_item_kind () const override
    1595              :   {
    1596          559 :     return EnumItemKind::Discriminant;
    1597              :   }
    1598              : 
    1599              :   std::string to_string () const override;
    1600              : 
    1601              :   void accept_vis (HIRFullVisitor &vis) override;
    1602              :   void accept_vis (HIRStmtVisitor &vis) override;
    1603              : 
    1604         1126 :   Expr &get_discriminant_expression () { return *expression; }
    1605              : 
    1606              :   std::unique_ptr<Expr> take_discriminant_expression ()
    1607              :   {
    1608              :     return std::move (expression);
    1609              :   }
    1610              : 
    1611              : protected:
    1612              :   // Clone function implementation as (not pure) virtual method
    1613            1 :   EnumItemDiscriminant *clone_item_impl () const override
    1614              :   {
    1615            1 :     return new EnumItemDiscriminant (*this);
    1616              :   }
    1617              : };
    1618              : 
    1619              : // HIR node for Rust "enum" - tagged union
    1620              : class Enum : public VisItem
    1621              : {
    1622              :   Identifier enum_name;
    1623              : 
    1624              :   // bool has_generics;
    1625              :   // Generics generic_params;
    1626              :   std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
    1627              : 
    1628              :   // bool has_where_clause;
    1629              :   WhereClause where_clause;
    1630              : 
    1631              :   std::vector<std::unique_ptr<EnumItem>> items;
    1632              : 
    1633              :   location_t locus;
    1634              : 
    1635              : public:
    1636              :   std::string to_string () const override;
    1637              : 
    1638              :   // Returns whether "enum" has generic parameters.
    1639          563 :   bool has_generics () const { return !generic_params.empty (); }
    1640              : 
    1641              :   // Returns whether "enum" has a where clause.
    1642          525 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    1643              : 
    1644              :   /* Returns whether enum is a "zero-variant" (no possible variant) enum,
    1645              :    * which cannot be instantiated. */
    1646          563 :   bool is_zero_variant () const { return items.empty (); }
    1647              : 
    1648              :   // Mega-constructor
    1649              :   Enum (Analysis::NodeMapping mappings, Identifier enum_name, Visibility vis,
    1650              :         std::vector<std::unique_ptr<GenericParam>> generic_params,
    1651              :         WhereClause where_clause, std::vector<std::unique_ptr<EnumItem>> items,
    1652              :         AST::AttrVec outer_attrs, location_t locus);
    1653              : 
    1654              :   // TODO: constructor with less arguments
    1655              : 
    1656              :   // Copy constructor with vector clone
    1657              :   Enum (Enum const &other);
    1658              : 
    1659              :   // Overloaded assignment operator with vector clone
    1660              :   Enum &operator= (Enum const &other);
    1661              : 
    1662              :   // Move constructors
    1663              :   Enum (Enum &&other) = default;
    1664              :   Enum &operator= (Enum &&other) = default;
    1665              : 
    1666         2545 :   location_t get_locus () const override final { return locus; }
    1667              : 
    1668              :   void accept_vis (HIRFullVisitor &vis) override;
    1669              :   void accept_vis (HIRStmtVisitor &vis) override;
    1670              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1671              : 
    1672          563 :   Identifier get_identifier () const { return enum_name; }
    1673          429 :   ItemKind get_item_kind () const override { return ItemKind::Enum; }
    1674              : 
    1675         1288 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    1676              :   {
    1677         1813 :     return generic_params;
    1678              :   }
    1679              : 
    1680              :   const std::vector<std::unique_ptr<EnumItem>> &get_variants () const
    1681              :   {
    1682              :     return items;
    1683              :   }
    1684              : 
    1685         3246 :   std::vector<std::unique_ptr<EnumItem>> &get_variants () { return items; }
    1686          563 :   WhereClause &get_where_clause () { return where_clause; }
    1687              : 
    1688              : protected:
    1689              :   /* Use covariance to implement clone function as returning this object
    1690              :    * rather than base */
    1691            3 :   Enum *clone_item_impl () const override { return new Enum (*this); }
    1692              : 
    1693              :   /* Use covariance to implement clone function as returning this object
    1694              :    * rather than base */
    1695              :   /*virtual Enum* clone_statement_impl() const override {
    1696              :       return new Enum(*this);
    1697              :   }*/
    1698              : };
    1699              : 
    1700              : // Rust untagged union used for C compat HIR node
    1701              : class Union : public VisItem
    1702              : {
    1703              :   Identifier union_name;
    1704              : 
    1705              :   // bool has_generics;
    1706              :   // Generics generic_params;
    1707              :   std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
    1708              : 
    1709              :   // bool has_where_clause;
    1710              :   WhereClause where_clause;
    1711              : 
    1712              :   std::vector<StructField> variants;
    1713              : 
    1714              :   location_t locus;
    1715              : 
    1716              : public:
    1717              :   std::string to_string () const override;
    1718              : 
    1719              :   // Returns whether union has generic params.
    1720          105 :   bool has_generics () const { return !generic_params.empty (); }
    1721              : 
    1722              :   // Returns whether union has where clause.
    1723          101 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    1724              : 
    1725              :   Union (Analysis::NodeMapping mappings, Identifier union_name, Visibility vis,
    1726              :          std::vector<std::unique_ptr<GenericParam>> generic_params,
    1727              :          WhereClause where_clause, std::vector<StructField> variants,
    1728              :          AST::AttrVec outer_attrs, location_t locus);
    1729              : 
    1730              :   // copy constructor with vector clone
    1731              :   Union (Union const &other);
    1732              : 
    1733              :   // overloaded assignment operator with vector clone
    1734              :   Union &operator= (Union const &other);
    1735              : 
    1736              :   // move constructors
    1737              :   Union (Union &&other) = default;
    1738              :   Union &operator= (Union &&other) = default;
    1739              : 
    1740          279 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    1741              :   {
    1742          380 :     return generic_params;
    1743              :   }
    1744              : 
    1745          210 :   Identifier get_identifier () const { return union_name; }
    1746              : 
    1747          501 :   location_t get_locus () const override final { return locus; }
    1748              : 
    1749              :   void accept_vis (HIRFullVisitor &vis) override;
    1750              :   void accept_vis (HIRStmtVisitor &vis) override;
    1751              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1752              : 
    1753          206 :   std::vector<StructField> &get_variants () { return variants; }
    1754              : 
    1755          105 :   WhereClause &get_where_clause () { return where_clause; }
    1756              : 
    1757           11 :   ItemKind get_item_kind () const override { return ItemKind::Union; }
    1758              : 
    1759              : protected:
    1760              :   /* Use covariance to implement clone function as returning this object
    1761              :    * rather than base */
    1762            0 :   Union *clone_item_impl () const override { return new Union (*this); }
    1763              : };
    1764              : 
    1765              : class ConstantItem : public VisItem, public ImplItem
    1766              : {
    1767              :   Identifier identifier;
    1768              :   std::unique_ptr<Type> type;
    1769              :   std::unique_ptr<Expr> const_expr;
    1770              :   location_t locus;
    1771              : 
    1772              : public:
    1773              :   std::string to_string () const override;
    1774              : 
    1775              :   ConstantItem (Analysis::NodeMapping mappings, Identifier ident,
    1776              :                 Visibility vis, std::unique_ptr<Type> type,
    1777              :                 std::unique_ptr<Expr> const_expr, AST::AttrVec outer_attrs,
    1778              :                 location_t locus);
    1779              : 
    1780              :   ConstantItem (ConstantItem const &other);
    1781              : 
    1782              :   // Overload assignment operator to clone
    1783              :   ConstantItem &operator= (ConstantItem const &other);
    1784              : 
    1785              :   // move constructors
    1786              :   ConstantItem (ConstantItem &&other) = default;
    1787              :   ConstantItem &operator= (ConstantItem &&other) = default;
    1788              : 
    1789              :   // Returns whether constant item is an "unnamed" (wildcard underscore used
    1790              :   // as identifier) constant.
    1791              :   bool is_unnamed () const
    1792              :   {
    1793              :     return identifier.as_string () == std::string ("_");
    1794              :   }
    1795              : 
    1796         4210 :   location_t get_locus () const override final { return locus; }
    1797              : 
    1798              :   void accept_vis (HIRFullVisitor &vis) override;
    1799              :   void accept_vis (HIRStmtVisitor &vis) override;
    1800              :   void accept_vis (HIRImplVisitor &vis) override;
    1801              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1802              : 
    1803         1676 :   Type &get_type ()
    1804              :   {
    1805         1676 :     rust_assert (type);
    1806         1676 :     return *type;
    1807              :   }
    1808              : 
    1809           59 :   bool has_expr () const { return const_expr != nullptr; }
    1810              : 
    1811         4423 :   Expr &get_expr () { return *const_expr; }
    1812              : 
    1813          222 :   Identifier get_identifier () const { return identifier; }
    1814              : 
    1815         1459 :   Analysis::NodeMapping get_impl_mappings () const override
    1816              :   {
    1817         1459 :     return get_mappings ();
    1818              :   };
    1819              : 
    1820          335 :   ImplItemType get_impl_item_type () const override final
    1821              :   {
    1822          335 :     return ImplItem::ImplItemType::CONSTANT;
    1823              :   }
    1824              : 
    1825          573 :   ItemKind get_item_kind () const override { return ItemKind::Constant; }
    1826              : 
    1827          154 :   std::string get_impl_item_name () const override final
    1828              :   {
    1829          308 :     return get_identifier ().as_string ();
    1830              :   }
    1831              : 
    1832              : protected:
    1833              :   /* Use covariance to implement clone function as returning this object
    1834              :    * rather than base */
    1835            0 :   ConstantItem *clone_item_impl () const override
    1836              :   {
    1837            0 :     return new ConstantItem (*this);
    1838              :   }
    1839              : 
    1840              :   /* Use covariance to implement clone function as returning this object
    1841              :    * rather than base */
    1842            0 :   ConstantItem *clone_inherent_impl_item_impl () const override
    1843              :   {
    1844            0 :     return new ConstantItem (*this);
    1845              :   }
    1846              : };
    1847              : 
    1848              : /* Static item HIR node - items within module scope with fixed storage
    1849              :  * duration? */
    1850              : class StaticItem : public VisItem
    1851              : {
    1852              :   Mutability mut;
    1853              :   Identifier name;
    1854              :   std::unique_ptr<Type> type;
    1855              :   std::unique_ptr<Expr> expr;
    1856              :   location_t locus;
    1857              : 
    1858              : public:
    1859              :   std::string to_string () const override;
    1860              : 
    1861              :   StaticItem (Analysis::NodeMapping mappings, Identifier name, Mutability mut,
    1862              :               std::unique_ptr<Type> type, std::unique_ptr<Expr> expr,
    1863              :               Visibility vis, AST::AttrVec outer_attrs, location_t locus);
    1864              : 
    1865              :   // Copy constructor with clone
    1866              :   StaticItem (StaticItem const &other);
    1867              : 
    1868              :   // Overloaded assignment operator to clone
    1869              :   StaticItem &operator= (StaticItem const &other);
    1870              : 
    1871              :   // move constructors
    1872              :   StaticItem (StaticItem &&other) = default;
    1873              :   StaticItem &operator= (StaticItem &&other) = default;
    1874              : 
    1875          413 :   location_t get_locus () const override final { return locus; }
    1876              : 
    1877              :   void accept_vis (HIRFullVisitor &vis) override;
    1878              :   void accept_vis (HIRStmtVisitor &vis) override;
    1879              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1880              : 
    1881            7 :   Identifier get_identifier () const { return name; }
    1882              : 
    1883              :   Mutability get_mut () const { return mut; }
    1884              : 
    1885           38 :   bool is_mut () const { return mut == Mutability::Mut; }
    1886              : 
    1887          454 :   Expr &get_expr ()
    1888              :   {
    1889          454 :     rust_assert (expr);
    1890          454 :     return *expr;
    1891              :   }
    1892              : 
    1893          171 :   Type &get_type ()
    1894              :   {
    1895          171 :     rust_assert (type);
    1896          171 :     return *type;
    1897              :   }
    1898              : 
    1899           55 :   ItemKind get_item_kind () const override { return ItemKind::Static; }
    1900              : 
    1901              : protected:
    1902            0 :   StaticItem *clone_item_impl () const override
    1903              :   {
    1904            0 :     return new StaticItem (*this);
    1905              :   }
    1906              : };
    1907              : 
    1908              : // Function declaration in traits
    1909              : class TraitFunctionDecl
    1910              : {
    1911              : private:
    1912              :   FunctionQualifiers qualifiers;
    1913              :   Identifier function_name;
    1914              :   std::vector<std::unique_ptr<GenericParam>> generic_params;
    1915              :   std::vector<FunctionParam> function_params;
    1916              :   std::unique_ptr<Type> return_type;
    1917              :   WhereClause where_clause;
    1918              :   tl::optional<SelfParam> self;
    1919              : 
    1920              : public:
    1921              :   // Mega-constructor
    1922              :   TraitFunctionDecl (Identifier function_name, FunctionQualifiers qualifiers,
    1923              :                      std::vector<std::unique_ptr<GenericParam>> generic_params,
    1924              :                      tl::optional<SelfParam> self,
    1925              :                      std::vector<FunctionParam> function_params,
    1926              :                      std::unique_ptr<Type> return_type,
    1927              :                      WhereClause where_clause);
    1928              : 
    1929              :   // Copy constructor with clone
    1930              :   TraitFunctionDecl (TraitFunctionDecl const &other);
    1931              : 
    1932        11606 :   ~TraitFunctionDecl () = default;
    1933              : 
    1934              :   // Overloaded assignment operator with clone
    1935              :   TraitFunctionDecl &operator= (TraitFunctionDecl const &other);
    1936              : 
    1937              :   // move constructors
    1938         6180 :   TraitFunctionDecl (TraitFunctionDecl &&other) = default;
    1939              :   TraitFunctionDecl &operator= (TraitFunctionDecl &&other) = default;
    1940              : 
    1941              :   std::string to_string () const;
    1942              : 
    1943              :   // Returns whether function decl has generic parameters.
    1944         2764 :   bool has_generics () const { return !generic_params.empty (); }
    1945              : 
    1946              :   // Returns whether function decl has regular parameters.
    1947            0 :   bool has_params () const { return !function_params.empty (); }
    1948              : 
    1949              :   // Returns whether function has return type (otherwise is void).
    1950         6299 :   bool has_return_type () const { return return_type != nullptr; }
    1951              : 
    1952              :   // Returns whether function has a where clause.
    1953         2666 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    1954              : 
    1955         2938 :   WhereClause &get_where_clause () { return where_clause; }
    1956              : 
    1957        11960 :   bool is_method () const { return self.has_value (); }
    1958              : 
    1959         2424 :   SelfParam &get_self_unchecked () { return self.value (); }
    1960            0 :   const SelfParam &get_self_unchecked () const { return self.value (); }
    1961              : 
    1962         2609 :   tl::optional<SelfParam> &get_self () { return self; }
    1963              :   const tl::optional<SelfParam> &get_self () const { return self; }
    1964              : 
    1965         9757 :   Identifier get_function_name () const { return function_name; }
    1966              : 
    1967           29 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    1968              :   {
    1969         2695 :     return generic_params;
    1970              :   }
    1971              : 
    1972         7488 :   Type &get_return_type () { return *return_type; }
    1973              : 
    1974         8777 :   std::vector<FunctionParam> &get_function_params () { return function_params; }
    1975              : 
    1976          259 :   const FunctionQualifiers &get_qualifiers () const { return qualifiers; }
    1977              : };
    1978              : 
    1979              : // Actual trait item function declaration within traits
    1980              : class TraitItemFunc : public TraitItem
    1981              : {
    1982              :   AST::AttrVec outer_attrs;
    1983              :   TraitFunctionDecl decl;
    1984              :   std::unique_ptr<BlockExpr> block_expr;
    1985              :   location_t locus;
    1986              : 
    1987              : public:
    1988              :   // Returns whether function has a definition or is just a declaration.
    1989        13777 :   bool has_definition () const { return block_expr != nullptr; }
    1990              : 
    1991              :   TraitItemFunc (Analysis::NodeMapping mappings, TraitFunctionDecl decl,
    1992              :                  std::unique_ptr<BlockExpr> block_expr,
    1993              :                  AST::AttrVec outer_attrs, location_t locus);
    1994              : 
    1995              :   // Copy constructor with clone
    1996              :   TraitItemFunc (TraitItemFunc const &other);
    1997              : 
    1998              :   // Overloaded assignment operator to clone
    1999              :   TraitItemFunc &operator= (TraitItemFunc const &other);
    2000              : 
    2001              :   // move constructors
    2002              :   TraitItemFunc (TraitItemFunc &&other) = default;
    2003              :   TraitItemFunc &operator= (TraitItemFunc &&other) = default;
    2004              : 
    2005              :   std::string to_string () const override;
    2006              : 
    2007        13088 :   location_t get_locus () const { return locus; }
    2008              : 
    2009              :   void accept_vis (HIRFullVisitor &vis) override;
    2010              :   void accept_vis (HIRTraitItemVisitor &vis) override;
    2011              : 
    2012        11096 :   TraitFunctionDecl &get_decl () { return decl; }
    2013              : 
    2014         1898 :   const TraitFunctionDecl &get_decl () const { return decl; }
    2015              : 
    2016         4563 :   BlockExpr &get_block_expr () { return *block_expr; }
    2017              : 
    2018         1261 :   const std::string trait_identifier () const override final
    2019              :   {
    2020         2522 :     return decl.get_function_name ().as_string ();
    2021              :   }
    2022              : 
    2023         5076 :   TraitItemKind get_item_kind () const override final
    2024              :   {
    2025         5076 :     return TraitItemKind::FUNC;
    2026              :   }
    2027              : 
    2028         2925 :   AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
    2029         7817 :   const AST::AttrVec &get_outer_attrs () const override final
    2030              :   {
    2031         7817 :     return outer_attrs;
    2032              :   }
    2033              : 
    2034         6180 :   location_t get_trait_locus () const override { return get_locus (); }
    2035              : 
    2036              : protected:
    2037              :   // Clone function implementation as (not pure) virtual method
    2038            0 :   TraitItemFunc *clone_trait_item_impl () const override
    2039              :   {
    2040            0 :     return new TraitItemFunc (*this);
    2041              :   }
    2042              : };
    2043              : 
    2044              : // Constant item within traits
    2045              : class TraitItemConst : public TraitItem
    2046              : {
    2047              :   AST::AttrVec outer_attrs;
    2048              :   Identifier name;
    2049              :   std::unique_ptr<Type> type;
    2050              :   std::unique_ptr<Expr> expr;
    2051              :   location_t locus;
    2052              : 
    2053              : public:
    2054              :   // Whether the constant item has an associated expression.
    2055            0 :   bool has_expression () const { return expr != nullptr; }
    2056              : 
    2057              :   TraitItemConst (Analysis::NodeMapping mappings, Identifier name,
    2058              :                   std::unique_ptr<Type> type, std::unique_ptr<Expr> expr,
    2059              :                   AST::AttrVec outer_attrs, location_t locus);
    2060              : 
    2061              :   // Copy constructor with clones
    2062              :   TraitItemConst (TraitItemConst const &other);
    2063              : 
    2064              :   // Overloaded assignment operator to clone
    2065              :   TraitItemConst &operator= (TraitItemConst const &other);
    2066              : 
    2067              :   // move constructors
    2068              :   TraitItemConst (TraitItemConst &&other) = default;
    2069              :   TraitItemConst &operator= (TraitItemConst &&other) = default;
    2070              : 
    2071              :   std::string to_string () const override;
    2072              : 
    2073          177 :   location_t get_locus () const { return locus; }
    2074              : 
    2075              :   void accept_vis (HIRFullVisitor &vis) override;
    2076              :   void accept_vis (HIRTraitItemVisitor &vis) override;
    2077              : 
    2078           40 :   Identifier get_name () const { return name; }
    2079              : 
    2080           40 :   bool has_type () const { return expr != nullptr; }
    2081              : 
    2082          241 :   bool has_expr () const { return expr != nullptr; }
    2083              : 
    2084           84 :   Type &get_type ()
    2085              :   {
    2086           84 :     rust_assert (type);
    2087           84 :     return *type;
    2088              :   }
    2089              : 
    2090           56 :   Expr &get_expr ()
    2091              :   {
    2092           56 :     rust_assert (expr);
    2093           56 :     return *expr;
    2094              :   }
    2095              : 
    2096            0 :   const std::string trait_identifier () const override final
    2097              :   {
    2098            0 :     return name.as_string ();
    2099              :   }
    2100              : 
    2101           61 :   TraitItemKind get_item_kind () const override final
    2102              :   {
    2103           61 :     return TraitItemKind::CONST;
    2104              :   }
    2105              : 
    2106           31 :   AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
    2107           90 :   const AST::AttrVec &get_outer_attrs () const override final
    2108              :   {
    2109           90 :     return outer_attrs;
    2110              :   }
    2111              : 
    2112          118 :   location_t get_trait_locus () const override { return get_locus (); }
    2113              : 
    2114              : protected:
    2115              :   // Clone function implementation as (not pure) virtual method
    2116            0 :   TraitItemConst *clone_trait_item_impl () const override
    2117              :   {
    2118            0 :     return new TraitItemConst (*this);
    2119              :   }
    2120              : };
    2121              : 
    2122              : // Type items within traits
    2123              : class TraitItemType : public TraitItem
    2124              : {
    2125              :   AST::AttrVec outer_attrs;
    2126              : 
    2127              :   Identifier name;
    2128              :   // Generic parameters for GATs (Generic Associated Types)
    2129              :   std::vector<std::unique_ptr<GenericParam>> generic_params;
    2130              :   std::vector<std::unique_ptr<TypeParamBound>>
    2131              :     type_param_bounds; // inlined form
    2132              :   location_t locus;
    2133              : 
    2134              : public:
    2135          828 :   bool has_generics () const { return !generic_params.empty (); }
    2136              : 
    2137              :   // Returns whether trait item type has type param bounds.
    2138          828 :   bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
    2139              : 
    2140              :   TraitItemType (Analysis::NodeMapping mappings, Identifier name,
    2141              :                  std::vector<std::unique_ptr<GenericParam>> generic_params,
    2142              :                  std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
    2143              :                  AST::AttrVec outer_attrs, location_t locus);
    2144              : 
    2145              :   // Copy constructor with vector clone
    2146              :   TraitItemType (TraitItemType const &other);
    2147              : 
    2148              :   // Overloaded assignment operator with vector clone
    2149              :   TraitItemType &operator= (TraitItemType const &other);
    2150              : 
    2151              :   // default move constructors
    2152              :   TraitItemType (TraitItemType &&other) = default;
    2153              :   TraitItemType &operator= (TraitItemType &&other) = default;
    2154              : 
    2155              :   std::string to_string () const override;
    2156              : 
    2157         2579 :   location_t get_locus () const { return locus; }
    2158              : 
    2159              :   void accept_vis (HIRFullVisitor &vis) override;
    2160              :   void accept_vis (HIRTraitItemVisitor &vis) override;
    2161              : 
    2162          828 :   Identifier get_name () const { return name; }
    2163              : 
    2164           17 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    2165              :   {
    2166           17 :     return generic_params;
    2167              :   }
    2168              :   const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
    2169              :   {
    2170              :     return generic_params;
    2171              :   }
    2172              : 
    2173            0 :   std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
    2174              :   {
    2175          843 :     return type_param_bounds;
    2176              :   }
    2177              : 
    2178          886 :   const std::string trait_identifier () const override final
    2179              :   {
    2180          886 :     return name.as_string ();
    2181              :   }
    2182              : 
    2183         1717 :   TraitItemKind get_item_kind () const override final
    2184              :   {
    2185         1717 :     return TraitItemKind::TYPE;
    2186              :   }
    2187              : 
    2188          792 :   AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
    2189         3044 :   const AST::AttrVec &get_outer_attrs () const override final
    2190              :   {
    2191         3044 :     return outer_attrs;
    2192              :   }
    2193              : 
    2194         1734 :   location_t get_trait_locus () const override { return get_locus (); }
    2195              : 
    2196              : protected:
    2197              :   // Clone function implementation as (not pure) virtual method
    2198            0 :   TraitItemType *clone_trait_item_impl () const override
    2199              :   {
    2200            0 :     return new TraitItemType (*this);
    2201              :   }
    2202              : };
    2203              : 
    2204              : // Rust trait item declaration HIR node
    2205              : class Trait : public VisItem
    2206              : {
    2207              :   Unsafety unsafety;
    2208              :   Identifier name;
    2209              :   std::vector<std::unique_ptr<GenericParam>> generic_params;
    2210              :   std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
    2211              :   WhereClause where_clause;
    2212              :   std::vector<std::unique_ptr<TraitItem>> trait_items;
    2213              :   location_t locus;
    2214              : 
    2215              : public:
    2216              :   std::string to_string () const override;
    2217              : 
    2218              :   // Returns whether trait has generic parameters.
    2219              :   bool has_generics () const { return !generic_params.empty (); }
    2220              : 
    2221              :   // Returns whether trait has type parameter bounds.
    2222         8851 :   bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
    2223              : 
    2224              :   // Returns whether trait has where clause.
    2225         3986 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    2226              : 
    2227              :   // Returns whether trait has trait items.
    2228            0 :   bool has_trait_items () const { return !trait_items.empty (); }
    2229              : 
    2230            0 :   std::vector<std::unique_ptr<TraitItem>> &get_trait_items ()
    2231              :   {
    2232        25176 :     return trait_items;
    2233              :   }
    2234              : 
    2235            7 :   WhereClause &get_where_clause () { return where_clause; }
    2236              : 
    2237         8595 :   Identifier get_name () const { return name; }
    2238            0 :   bool is_unsafe () const { return unsafety == Unsafety::Unsafe; }
    2239              : 
    2240              :   // Mega-constructor
    2241              :   Trait (Analysis::NodeMapping mappings, Identifier name, Unsafety unsafety,
    2242              :          std::vector<std::unique_ptr<GenericParam>> generic_params,
    2243              :          std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
    2244              :          WhereClause where_clause,
    2245              :          std::vector<std::unique_ptr<TraitItem>> trait_items, Visibility vis,
    2246              :          AST::AttrVec outer_attrs, location_t locus);
    2247              : 
    2248              :   // Copy constructor with vector clone
    2249              :   Trait (Trait const &other);
    2250              : 
    2251              :   // Overloaded assignment operator with vector clone
    2252              :   Trait &operator= (Trait const &other);
    2253              : 
    2254              :   // default move constructors
    2255              :   Trait (Trait &&other) = default;
    2256              :   Trait &operator= (Trait &&other) = default;
    2257              : 
    2258        27211 :   location_t get_locus () const override final { return locus; }
    2259              : 
    2260              :   void accept_vis (HIRFullVisitor &vis) override;
    2261              :   void accept_vis (HIRStmtVisitor &vis) override;
    2262              :   void accept_vis (HIRVisItemVisitor &vis) override;
    2263              : 
    2264         8083 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    2265              :   {
    2266        19068 :     return generic_params;
    2267              :   }
    2268              : 
    2269              :   const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
    2270              :   {
    2271          828 :     return generic_params;
    2272              :   }
    2273              : 
    2274            0 :   std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
    2275              :   {
    2276         6953 :     return type_param_bounds;
    2277              :   }
    2278              : 
    2279              :   const std::vector<std::unique_ptr<TypeParamBound>> &
    2280              :   get_type_param_bounds () const
    2281              :   {
    2282              :     return type_param_bounds;
    2283              :   }
    2284              : 
    2285       438120 :   ItemKind get_item_kind () const override { return ItemKind::Trait; }
    2286              : 
    2287              : protected:
    2288              :   /* Use covariance to implement clone function as returning this object
    2289              :    * rather than base */
    2290            0 :   Trait *clone_item_impl () const override { return new Trait (*this); }
    2291              : };
    2292              : 
    2293              : class ImplBlock : public VisItem, public WithInnerAttrs
    2294              : {
    2295              :   std::vector<std::unique_ptr<GenericParam>> generic_params;
    2296              :   std::unique_ptr<Type> impl_type;
    2297              :   std::unique_ptr<TypePath> trait_ref;
    2298              :   WhereClause where_clause;
    2299              :   BoundPolarity polarity;
    2300              :   location_t locus;
    2301              :   std::vector<std::unique_ptr<ImplItem>> impl_items;
    2302              :   bool unsafe;
    2303              : 
    2304              : public:
    2305              :   ImplBlock (Analysis::NodeMapping mappings,
    2306              :              std::vector<std::unique_ptr<ImplItem>> impl_items,
    2307              :              std::vector<std::unique_ptr<GenericParam>> generic_params,
    2308              :              std::unique_ptr<Type> impl_type,
    2309              :              std::unique_ptr<TypePath> trait_ref, WhereClause where_clause,
    2310              :              BoundPolarity polarity, Visibility vis, AST::AttrVec inner_attrs,
    2311              :              AST::AttrVec outer_attrs, location_t locus, bool unsafe = false);
    2312              : 
    2313              :   ImplBlock (ImplBlock const &other);
    2314              : 
    2315              :   ImplBlock &operator= (ImplBlock const &other);
    2316              : 
    2317              :   ImplBlock (ImplBlock &&other) = default;
    2318              :   ImplBlock &operator= (ImplBlock &&other) = default;
    2319              : 
    2320              :   std::string to_string () const override;
    2321              : 
    2322              :   // Returns whether inherent impl block has inherent impl items.
    2323         6042 :   bool has_impl_items () const { return !impl_items.empty (); }
    2324              : 
    2325         6336 :   bool is_unsafe () const { return unsafe; }
    2326              : 
    2327              :   void accept_vis (HIRFullVisitor &vis) override;
    2328              :   void accept_vis (HIRStmtVisitor &vis) override;
    2329              :   void accept_vis (HIRVisItemVisitor &vis) override;
    2330              : 
    2331            0 :   std::vector<std::unique_ptr<ImplItem>> &get_impl_items ()
    2332              :   {
    2333        89976 :     return impl_items;
    2334              :   };
    2335              : 
    2336              :   const std::vector<std::unique_ptr<ImplItem>> &get_impl_items () const
    2337              :   {
    2338        43694 :     return impl_items;
    2339              :   };
    2340              : 
    2341              :   // Returns whether impl has generic parameters.
    2342        34907 :   bool has_generics () const { return !generic_params.empty (); }
    2343              : 
    2344              :   // Returns whether impl has where clause.
    2345         6045 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    2346              : 
    2347              :   // Returns the polarity of the impl.
    2348        75534 :   BoundPolarity get_polarity () const { return polarity; }
    2349              : 
    2350       331678 :   location_t get_locus () const override final { return locus; }
    2351              : 
    2352       442121 :   Type &get_type ()
    2353              :   {
    2354       442121 :     rust_assert (impl_type);
    2355       442121 :     return *impl_type;
    2356              :   };
    2357              : 
    2358          776 :   bool has_type () { return impl_type != nullptr; }
    2359              : 
    2360        17533 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    2361              :   {
    2362        33543 :     return generic_params;
    2363              :   }
    2364              : 
    2365       485853 :   bool has_trait_ref () const { return trait_ref != nullptr; }
    2366              : 
    2367       359303 :   TypePath &get_trait_ref () { return *trait_ref; }
    2368              : 
    2369        35010 :   WhereClause &get_where_clause () { return where_clause; }
    2370              : 
    2371            0 :   ItemKind get_item_kind () const override { return ItemKind::Impl; }
    2372              : 
    2373              : protected:
    2374            0 :   ImplBlock *clone_item_impl () const override { return new ImplBlock (*this); }
    2375              : };
    2376              : 
    2377              : // Abstract base class for an item used inside an extern block
    2378              : class ExternalItem : public Node
    2379              : {
    2380              :   Analysis::NodeMapping mappings;
    2381              :   AST::AttrVec outer_attrs;
    2382              :   Visibility visibility;
    2383              :   Identifier item_name;
    2384              :   location_t locus;
    2385              : 
    2386              : public:
    2387              :   enum class ExternKind
    2388              :   {
    2389              :     Static,
    2390              :     Function,
    2391              :     Type,
    2392              :   };
    2393              : 
    2394            1 :   virtual ~ExternalItem () {}
    2395              : 
    2396            0 :   BaseKind get_hir_kind () override final { return EXTERNAL; }
    2397              : 
    2398              :   virtual ExternKind get_extern_kind () = 0;
    2399              : 
    2400              :   // Returns whether item has outer attributes.
    2401              :   bool has_outer_attrs () const { return !outer_attrs.empty (); }
    2402              : 
    2403              :   // Returns whether item has non-default visibility.
    2404            0 :   bool has_visibility () const { return !visibility.is_error (); }
    2405              : 
    2406              :   // Unique pointer custom clone function
    2407            0 :   std::unique_ptr<ExternalItem> clone_external_item () const
    2408              :   {
    2409            0 :     return std::unique_ptr<ExternalItem> (clone_external_item_impl ());
    2410              :   }
    2411              : 
    2412              :   virtual std::string to_string () const;
    2413              : 
    2414              :   std::string to_debug_string () const
    2415              :   {
    2416              :     return to_string () + mappings.as_string ();
    2417              :   }
    2418              : 
    2419         8416 :   location_t get_locus () const { return locus; }
    2420              : 
    2421              :   virtual void accept_vis (HIRFullVisitor &vis) = 0;
    2422              :   virtual void accept_vis (HIRExternalItemVisitor &vis) = 0;
    2423              : 
    2424            0 :   Visibility &get_visibility () { return visibility; }
    2425        23999 :   Analysis::NodeMapping get_mappings () const { return mappings; }
    2426              : 
    2427        11678 :   Identifier get_item_name () const { return item_name; }
    2428              : 
    2429         4445 :   AST::AttrVec &get_outer_attrs () { return outer_attrs; }
    2430              : 
    2431              : protected:
    2432              :   ExternalItem (Analysis::NodeMapping mappings, Identifier item_name,
    2433              :                 Visibility vis, AST::AttrVec outer_attrs, location_t locus);
    2434              : 
    2435              :   // Copy constructor
    2436              :   ExternalItem (ExternalItem const &other);
    2437              : 
    2438              :   // Overloaded assignment operator to clone
    2439              :   ExternalItem &operator= (ExternalItem const &other);
    2440              : 
    2441              :   // move constructors
    2442              :   ExternalItem (ExternalItem &&other) = default;
    2443              :   ExternalItem &operator= (ExternalItem &&other) = default;
    2444              : 
    2445              :   // Clone function implementation as pure virtual method
    2446              :   virtual ExternalItem *clone_external_item_impl () const = 0;
    2447              : };
    2448              : 
    2449              : // A static item used in an extern block
    2450              : class ExternalStaticItem : public ExternalItem
    2451              : {
    2452              :   Mutability mut;
    2453              :   std::unique_ptr<Type> item_type;
    2454              : 
    2455              : public:
    2456              :   ExternalStaticItem (Analysis::NodeMapping mappings, Identifier item_name,
    2457              :                       std::unique_ptr<Type> item_type, Mutability mut,
    2458              :                       Visibility vis, AST::AttrVec outer_attrs,
    2459              :                       location_t locus);
    2460              : 
    2461              :   // Copy constructor
    2462              :   ExternalStaticItem (ExternalStaticItem const &other);
    2463              : 
    2464              :   // Overloaded assignment operator to clone
    2465              :   ExternalStaticItem &operator= (ExternalStaticItem const &other);
    2466              : 
    2467              :   // move constructors
    2468              :   ExternalStaticItem (ExternalStaticItem &&other) = default;
    2469              :   ExternalStaticItem &operator= (ExternalStaticItem &&other) = default;
    2470              : 
    2471              :   std::string to_string () const override;
    2472              : 
    2473              :   void accept_vis (HIRFullVisitor &vis) override;
    2474              :   void accept_vis (HIRExternalItemVisitor &vis) override;
    2475              : 
    2476            0 :   bool is_mut () const { return mut == Mutability::Mut; }
    2477              : 
    2478              :   Mutability get_mut () { return mut; }
    2479              : 
    2480            1 :   Type &get_item_type () { return *item_type; }
    2481              : 
    2482            2 :   ExternKind get_extern_kind () override { return ExternKind::Static; }
    2483              : 
    2484              : protected:
    2485              :   /* Use covariance to implement clone function as returning this object
    2486              :    * rather than base */
    2487            0 :   ExternalStaticItem *clone_external_item_impl () const override
    2488              :   {
    2489            0 :     return new ExternalStaticItem (*this);
    2490              :   }
    2491              : };
    2492              : 
    2493              : // A named function parameter used in external functions
    2494              : struct NamedFunctionParam
    2495              : {
    2496              : private:
    2497              :   Identifier name;
    2498              :   std::unique_ptr<Type> param_type;
    2499              :   Analysis::NodeMapping mappings;
    2500              : 
    2501              : public:
    2502              :   bool has_name () const { return name.as_string () != "_"; }
    2503              : 
    2504              :   NamedFunctionParam (Analysis::NodeMapping mappings, Identifier name,
    2505              :                       std::unique_ptr<Type> param_type);
    2506              : 
    2507              :   // Copy constructor
    2508              :   NamedFunctionParam (NamedFunctionParam const &other);
    2509              : 
    2510         2113 :   ~NamedFunctionParam () = default;
    2511              : 
    2512              :   // Overloaded assignment operator to clone
    2513              :   NamedFunctionParam &operator= (NamedFunctionParam const &other);
    2514              : 
    2515              :   // move constructors
    2516         2112 :   NamedFunctionParam (NamedFunctionParam &&other) = default;
    2517              :   NamedFunctionParam &operator= (NamedFunctionParam &&other) = default;
    2518              : 
    2519              :   std::string to_string () const;
    2520              : 
    2521         3095 :   Identifier get_param_name () const { return name; }
    2522              : 
    2523         6106 :   Type &get_type ()
    2524              :   {
    2525         6106 :     rust_assert (param_type);
    2526         6106 :     return *param_type;
    2527              :   }
    2528              : 
    2529         3095 :   Analysis::NodeMapping get_mappings () const { return mappings; }
    2530              : };
    2531              : 
    2532              : // A function item used in an extern block
    2533              : class ExternalFunctionItem : public ExternalItem
    2534              : {
    2535              :   // bool has_generics;
    2536              :   // Generics generic_params;
    2537              :   std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
    2538              : 
    2539              :   // bool has_return_type;
    2540              :   // FunctionReturnType return_type;
    2541              :   std::unique_ptr<Type> return_type; // inlined
    2542              : 
    2543              :   // bool has_where_clause;
    2544              :   WhereClause where_clause;
    2545              : 
    2546              :   std::vector<NamedFunctionParam> function_params;
    2547              :   bool has_variadics;
    2548              : 
    2549              : public:
    2550              :   // Returns whether item has generic parameters.
    2551         2686 :   bool has_generics () const { return !generic_params.empty (); }
    2552              : 
    2553              :   // Returns whether item has a return type (otherwise void).
    2554         5305 :   bool has_return_type () const { return return_type != nullptr; }
    2555              : 
    2556              :   // Returns whether item has a where clause.
    2557         2619 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    2558              : 
    2559              :   WARN_UNUSED_RESULT const WhereClause &get_where_clause () const
    2560              :   {
    2561              :     return where_clause;
    2562              :   }
    2563              : 
    2564         2686 :   WARN_UNUSED_RESULT WhereClause &get_where_clause () { return where_clause; }
    2565              : 
    2566              :   ExternalFunctionItem (
    2567              :     Analysis::NodeMapping mappings, Identifier item_name,
    2568              :     std::vector<std::unique_ptr<GenericParam>> generic_params,
    2569              :     std::unique_ptr<Type> return_type, WhereClause where_clause,
    2570              :     std::vector<NamedFunctionParam> function_params, bool has_variadics,
    2571              :     Visibility vis, AST::AttrVec outer_attrs, location_t locus);
    2572              : 
    2573              :   // Copy constructor with clone
    2574              :   ExternalFunctionItem (ExternalFunctionItem const &other);
    2575              : 
    2576              :   // Overloaded assignment operator with clone
    2577              :   ExternalFunctionItem &operator= (ExternalFunctionItem const &other);
    2578              : 
    2579              :   // move constructors
    2580              :   ExternalFunctionItem (ExternalFunctionItem &&other) = default;
    2581              :   ExternalFunctionItem &operator= (ExternalFunctionItem &&other) = default;
    2582              : 
    2583              :   std::string to_string () const override;
    2584              : 
    2585              :   void accept_vis (HIRFullVisitor &vis) override;
    2586              :   void accept_vis (HIRExternalItemVisitor &vis) override;
    2587              : 
    2588         1073 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    2589              :   {
    2590         3692 :     return generic_params;
    2591              :   }
    2592              : 
    2593         4179 :   Type &get_return_type () { return *return_type; }
    2594              : 
    2595              :   std::vector<NamedFunctionParam> &get_function_params ()
    2596              :   {
    2597         5305 :     return function_params;
    2598              :   }
    2599              : 
    2600         2686 :   bool is_variadic () const { return has_variadics; }
    2601              : 
    2602         6624 :   ExternKind get_extern_kind () override { return ExternKind::Function; }
    2603              : 
    2604              : protected:
    2605              :   /* Use covariance to implement clone function as returning this object
    2606              :    * rather than base */
    2607            0 :   ExternalFunctionItem *clone_external_item_impl () const override
    2608              :   {
    2609            0 :     return new ExternalFunctionItem (*this);
    2610              :   }
    2611              : };
    2612              : 
    2613              : class ExternalTypeItem : public ExternalItem
    2614              : {
    2615              : public:
    2616              :   ExternalTypeItem (Analysis::NodeMapping mappings, Identifier item_name,
    2617              :                     Visibility vis, location_t locus);
    2618              : 
    2619              :   ExternalTypeItem (ExternalTypeItem const &other);
    2620              : 
    2621              :   ExternalTypeItem (ExternalTypeItem &&other) = default;
    2622              :   ExternalTypeItem &operator= (ExternalTypeItem &&other) = default;
    2623              :   ExternalTypeItem &operator= (ExternalTypeItem const &other) = default;
    2624              : 
    2625              :   std::string to_string () const override;
    2626              : 
    2627              :   void accept_vis (HIRFullVisitor &vis) override;
    2628              :   void accept_vis (HIRExternalItemVisitor &vis) override;
    2629              : 
    2630            0 :   ExternKind get_extern_kind () override { return ExternKind::Type; }
    2631              : 
    2632              : protected:
    2633              :   /* Use covariance to implement clone function as returning this object
    2634              :    * rather than base */
    2635            0 :   ExternalTypeItem *clone_external_item_impl () const override
    2636              :   {
    2637            0 :     return new ExternalTypeItem (*this);
    2638              :   }
    2639              : };
    2640              : 
    2641              : // An extern block HIR node
    2642              : class ExternBlock : public VisItem, public WithInnerAttrs
    2643              : {
    2644              :   ABI abi;
    2645              :   bool explicit_abi;
    2646              :   std::vector<std::unique_ptr<ExternalItem>> extern_items;
    2647              :   location_t locus;
    2648              : 
    2649              : public:
    2650              :   std::string to_string () const override;
    2651              : 
    2652              :   // Returns whether extern block has extern items.
    2653            0 :   bool has_extern_items () const { return !extern_items.empty (); }
    2654              : 
    2655              :   // Returns whether the extern block was given an explicit ABI string.
    2656            2 :   bool has_abi () const { return explicit_abi; }
    2657              : 
    2658        13274 :   ABI get_abi () const { return abi; }
    2659              : 
    2660              :   ExternBlock (Analysis::NodeMapping mappings, ABI abi, bool explicit_abi,
    2661              :                std::vector<std::unique_ptr<ExternalItem>> extern_items,
    2662              :                Visibility vis, AST::AttrVec inner_attrs,
    2663              :                AST::AttrVec outer_attrs, location_t locus);
    2664              : 
    2665              :   // Copy constructor with vector clone
    2666              :   ExternBlock (ExternBlock const &other);
    2667              : 
    2668              :   // Overloaded assignment operator with vector clone
    2669              :   ExternBlock &operator= (ExternBlock const &other);
    2670              : 
    2671              :   // move constructors
    2672              :   ExternBlock (ExternBlock &&other) = default;
    2673              :   ExternBlock &operator= (ExternBlock &&other) = default;
    2674              : 
    2675         5185 :   location_t get_locus () const override final { return locus; }
    2676              : 
    2677              :   void accept_vis (HIRFullVisitor &vis) override;
    2678              :   void accept_vis (HIRStmtVisitor &vis) override;
    2679              :   void accept_vis (HIRVisItemVisitor &vis) override;
    2680              : 
    2681            0 :   std::vector<std::unique_ptr<ExternalItem>> &get_extern_items ()
    2682              :   {
    2683        10173 :     return extern_items;
    2684              :   }
    2685              : 
    2686            0 :   ItemKind get_item_kind () const override { return ItemKind::ExternBlock; }
    2687              : 
    2688              : protected:
    2689              :   /* Use covariance to implement clone function as returning this object
    2690              :    * rather than base */
    2691            0 :   ExternBlock *clone_item_impl () const override
    2692              :   {
    2693            0 :     return new ExternBlock (*this);
    2694              :   }
    2695              : 
    2696              :   /* Use covariance to implement clone function as returning this object
    2697              :    * rather than base */
    2698              :   /*virtual ExternBlock* clone_statement_impl() const override {
    2699              :       return new ExternBlock(*this);
    2700              :   }*/
    2701              : };
    2702              : 
    2703              : } // namespace HIR
    2704              : } // namespace Rust
    2705              : 
    2706              : #endif
        

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.