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: 65.8 % 474 312
Test Date: 2026-02-28 14:20:25 Functions: 59.3 % 140 83
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           42 : 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          842 :   bool is_item () const override final { return true; }
      77              : 
      78              : protected:
      79              :   // Constructor
      80        35916 :   Item (Analysis::NodeMapping mappings,
      81              :         AST::AttrVec outer_attribs = AST::AttrVec ())
      82        35916 :     : Stmt (std::move (mappings)), WithOuterAttrs (std::move (outer_attribs))
      83        35916 :   {}
      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            0 :   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        45015 :   bool has_type () const { return type.has_value (); }
     107              : 
     108              :   // Returns whether the type param has type param bounds.
     109        25971 :   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         8625 :   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        18352 :   location_t get_locus () const override final { return locus; }
     138              : 
     139              :   void accept_vis (HIRFullVisitor &vis) override;
     140              : 
     141        18491 :   Identifier get_type_representation () const { return type_representation; }
     142              : 
     143          704 :   Type &get_type ()
     144              :   {
     145          704 :     rust_assert (*type);
     146          704 :     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         9773 :   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           92 : 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           90 :   std::unique_ptr<WhereClauseItem> clone_where_clause_item () const
     178              :   {
     179           90 :     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            2 :   LifetimeWhereClauseItem (Analysis::NodeMapping mappings, Lifetime lifetime,
     205              :                            std::vector<Lifetime> lifetime_bounds,
     206              :                            location_t locus)
     207            2 :     : lifetime (std::move (lifetime)),
     208            2 :       lifetime_bounds (std::move (lifetime_bounds)), locus (locus),
     209            2 :       mappings (std::move (mappings))
     210            2 :   {}
     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            2 :   ItemType get_item_type () const override final
     228              :   {
     229            2 :     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          563 :   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          139 :   std::vector<LifetimeParam> &get_for_lifetimes () { return for_lifetimes; }
     280              : 
     281          702 :   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          563 :   ItemType get_item_type () const override final
     291              :   {
     292          563 :     return WhereClauseItem::ItemType::TYPE_BOUND;
     293              :   }
     294              : 
     295              : protected:
     296              :   // Clone function implementation as (not pure) virtual method
     297           90 :   TypeBoundWhereClauseItem *clone_where_clause_item_impl () const override
     298              :   {
     299           90 :     return new TypeBoundWhereClauseItem (*this);
     300              :   }
     301              : };
     302              : 
     303              : // A where clause
     304        68725 : 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        36199 :   WhereClause (std::vector<std::unique_ptr<WhereClauseItem>> where_clause_items)
     313        36199 :     : where_clause_items (std::move (where_clause_items))
     314              :   {}
     315              : 
     316              :   // copy constructor with vector clone
     317         9298 :   WhereClause (WhereClause const &other)
     318         9298 :   {
     319         9298 :     where_clause_items.reserve (other.where_clause_items.size ());
     320         9388 :     for (const auto &e : other.where_clause_items)
     321           90 :       where_clause_items.push_back (e->clone_where_clause_item ());
     322         9298 :   }
     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        45557 :   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        57118 :   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        58333 :     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        28329 :   SelfParam (SelfParam &&other) = default;
     399            0 :   SelfParam &operator= (SelfParam &&other) = default;
     400              : 
     401              :   // Returns whether the self-param has a type field.
     402        31679 :   bool has_type () const { return type != nullptr; }
     403              : 
     404              :   // Returns whether the self-param has a valid lifetime.
     405        27440 :   bool has_lifetime () const { return lifetime.has_value (); }
     406              : 
     407            0 :   const Lifetime &get_lifetime () const { return lifetime.value (); }
     408              : 
     409        26628 :   Lifetime &get_lifetime () { return lifetime.value (); }
     410              : 
     411              :   std::string to_string () const;
     412              : 
     413        40657 :   location_t get_locus () const { return locus; }
     414              : 
     415        34930 :   ImplicitSelfKind get_self_kind () const { return self_kind; }
     416              : 
     417            1 :   Type &get_type ()
     418              :   {
     419            1 :     rust_assert (type);
     420            1 :     return *type;
     421              :   }
     422              : 
     423        84066 :   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        15799 :   FunctionQualifiers (Async async_status, Const const_status, Unsafety unsafety,
     444              :                       bool has_extern, ABI abi)
     445        15799 :     : async_status (async_status), const_status (const_status),
     446        15799 :       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        63314 :   bool is_const () const { return const_status == Const::Yes; }
     454        17385 :   bool is_unsafe () const { return unsafety == Unsafety::Unsafe; }
     455            2 :   bool is_async () const { return async_status == Async::Yes; }
     456              : 
     457           60 :   Unsafety get_unsafety () const { return unsafety; }
     458        12790 :   ABI get_abi () const { return abi; }
     459              : };
     460              : 
     461              : // A function parameter
     462          336 : 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          333 :   FunctionParam (FunctionParam &&other) = default;
     482              :   FunctionParam &operator= (FunctionParam &&other) = default;
     483              : 
     484              :   std::string to_string () const;
     485              : 
     486        14216 :   location_t get_locus () const { return locus; }
     487              : 
     488        46087 :   Pattern &get_param_name () { return *param_name; }
     489              : 
     490        45908 :   Type &get_type ()
     491              :   {
     492        45908 :     rust_assert (type);
     493        45908 :     return *type;
     494              :   }
     495              : 
     496        33714 :   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        34691 :   VisItem (Analysis::NodeMapping mappings, Visibility visibility,
     507              :            AST::AttrVec outer_attrs = AST::AttrVec ())
     508        34691 :     : Item (std::move (mappings), std::move (outer_attrs)),
     509        34691 :       visibility (std::move (visibility))
     510        34691 :   {}
     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       102484 :   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        35183 :   Visibility &get_visibility () { return visibility; }
     534        33413 :   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        13819 :   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         3594 :   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              :   // Returns whether function has generic parameters.
     970        13873 :   bool has_generics () const { return !generic_params.empty (); }
     971              : 
     972              :   // Returns whether function has regular parameters.
     973            0 :   bool has_function_params () const { return !function_params.empty (); }
     974              : 
     975              :   // Returns whether function has return type - if not, it is void.
     976        26327 :   bool has_function_return_type () const { return return_type != nullptr; }
     977              : 
     978              :   // Returns whether function has a where clause.
     979        12626 :   bool has_where_clause () const { return !where_clause.is_empty (); }
     980              : 
     981              :   // Returns whether function has a default qualifier
     982           43 :   bool is_default () const { return defaultness == Defaultness::Default; }
     983              : 
     984       264654 :   ImplItemType get_impl_item_type () const override final
     985              :   {
     986       264654 :     return ImplItem::ImplItemType::FUNCTION;
     987              :   }
     988              : 
     989         6001 :   ItemKind get_item_kind () const override { return ItemKind::Function; }
     990              : 
     991              :   // Mega-constructor with all possible fields
     992              :   Function (Analysis::NodeMapping mappings, Identifier function_name,
     993              :             FunctionQualifiers qualifiers,
     994              :             std::vector<std::unique_ptr<GenericParam>> generic_params,
     995              :             std::vector<FunctionParam> function_params,
     996              :             std::unique_ptr<Type> return_type, WhereClause where_clause,
     997              :             std::unique_ptr<BlockExpr> function_body, Visibility vis,
     998              :             AST::AttrVec outer_attrs, tl::optional<SelfParam> self,
     999              :             Defaultness defaultness, location_t locus);
    1000              : 
    1001              :   // Copy constructor with clone
    1002              :   Function (Function const &other);
    1003              : 
    1004              :   // Overloaded assignment operator to clone
    1005              :   Function &operator= (Function const &other);
    1006              : 
    1007              :   // move constructors
    1008              :   Function (Function &&other) = default;
    1009              :   Function &operator= (Function &&other) = default;
    1010              : 
    1011        76724 :   location_t get_locus () const override final { return locus; }
    1012              : 
    1013              :   void accept_vis (HIRFullVisitor &vis) override;
    1014              :   void accept_vis (HIRImplVisitor &vis) override;
    1015              :   void accept_vis (HIRStmtVisitor &vis) override;
    1016              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1017              : 
    1018       331002 :   Analysis::NodeMapping get_impl_mappings () const override
    1019              :   {
    1020       331002 :     return get_mappings ();
    1021              :   };
    1022              : 
    1023        77266 :   std::vector<FunctionParam> &get_function_params () { return function_params; }
    1024              :   const std::vector<FunctionParam> &get_function_params () const
    1025              :   {
    1026              :     return function_params;
    1027              :   }
    1028              : 
    1029        19690 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    1030              :   {
    1031        32316 :     return generic_params;
    1032              :   }
    1033              :   const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
    1034              :   {
    1035              :     return generic_params;
    1036              :   }
    1037              : 
    1038              :   // TODO: is this better? Or is a "vis_block" better?
    1039       127544 :   BlockExpr &get_definition () { return *function_body; }
    1040              : 
    1041        12475 :   const FunctionQualifiers &get_qualifiers () const { return qualifiers; }
    1042              : 
    1043       216997 :   Identifier get_function_name () const { return function_name; }
    1044              : 
    1045              :   // TODO: is this better? Or is a "vis_block" better?
    1046           27 :   WhereClause &get_where_clause () { return where_clause; }
    1047              : 
    1048        12629 :   bool has_return_type () const { return return_type != nullptr; }
    1049              : 
    1050              :   // TODO: is this better? Or is a "vis_block" better?
    1051        37871 :   Type &get_return_type () { return *return_type; }
    1052              : 
    1053       213229 :   bool is_method () const { return self.has_value (); }
    1054              : 
    1055        12475 :   tl::optional<SelfParam> &get_self_param () { return self; }
    1056              :   const tl::optional<SelfParam> &get_self_param () const { return self; }
    1057              : 
    1058        17168 :   SelfParam &get_self_param_unchecked () { return self.value (); }
    1059              :   const SelfParam &get_self_param_unchecked () const { return self.value (); }
    1060              : 
    1061         2682 :   std::string get_impl_item_name () const override final
    1062              :   {
    1063         5364 :     return get_function_name ().as_string ();
    1064              :   }
    1065              : 
    1066              : protected:
    1067              :   /* Use covariance to implement clone function as returning this object
    1068              :    * rather than base */
    1069            0 :   Function *clone_item_impl () const override { return new Function (*this); }
    1070              : 
    1071              :   /* Use covariance to implement clone function as returning this object
    1072              :    * rather than base */
    1073            0 :   Function *clone_inherent_impl_item_impl () const override
    1074              :   {
    1075            0 :     return new Function (*this);
    1076              :   }
    1077              : };
    1078              : 
    1079              : // Rust type alias (i.e. typedef) HIR node
    1080              : class TypeAlias : public VisItem, public ImplItem
    1081              : {
    1082              :   Identifier new_type_name;
    1083              : 
    1084              :   // bool has_generics;
    1085              :   // Generics generic_params;
    1086              :   std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
    1087              : 
    1088              :   // bool has_where_clause;
    1089              :   WhereClause where_clause;
    1090              : 
    1091              :   std::unique_ptr<Type> existing_type;
    1092              : 
    1093              :   location_t locus;
    1094              : 
    1095              : public:
    1096              :   std::string to_string () const override;
    1097              : 
    1098              :   // Returns whether type alias has generic parameters.
    1099         2349 :   bool has_generics () const { return !generic_params.empty (); }
    1100              : 
    1101              :   // Returns whether type alias has a where clause.
    1102         1212 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    1103              : 
    1104        52389 :   ImplItemType get_impl_item_type () const override final
    1105              :   {
    1106        52389 :     return ImplItem::ImplItemType::TYPE_ALIAS;
    1107              :   }
    1108              : 
    1109              :   // Mega-constructor with all possible fields
    1110              :   TypeAlias (Analysis::NodeMapping mappings, Identifier new_type_name,
    1111              :              std::vector<std::unique_ptr<GenericParam>> generic_params,
    1112              :              WhereClause where_clause, std::unique_ptr<Type> existing_type,
    1113              :              Visibility vis, AST::AttrVec outer_attrs, location_t locus);
    1114              : 
    1115              :   // Copy constructor
    1116              :   TypeAlias (TypeAlias const &other);
    1117              : 
    1118              :   // Overloaded assignment operator to clone
    1119              :   TypeAlias &operator= (TypeAlias const &other);
    1120              : 
    1121              :   // move constructors
    1122              :   TypeAlias (TypeAlias &&other) = default;
    1123              :   TypeAlias &operator= (TypeAlias &&other) = default;
    1124              : 
    1125        19298 :   location_t get_locus () const override final { return locus; }
    1126              : 
    1127              :   void accept_vis (HIRFullVisitor &vis) override;
    1128              :   void accept_vis (HIRImplVisitor &vis) override;
    1129              :   void accept_vis (HIRStmtVisitor &vis) override;
    1130              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1131              : 
    1132         1268 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    1133              :   {
    1134         2480 :     return generic_params;
    1135              :   }
    1136              :   const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
    1137              :   {
    1138              :     return generic_params;
    1139              :   }
    1140              : 
    1141            0 :   WhereClause &get_where_clause () { return where_clause; }
    1142              : 
    1143         2454 :   Type &get_type_aliased ()
    1144              :   {
    1145         2454 :     rust_assert (existing_type);
    1146         2454 :     return *existing_type;
    1147              :   }
    1148              : 
    1149        19599 :   Identifier get_new_type_name () const { return new_type_name; }
    1150              : 
    1151            3 :   ItemKind get_item_kind () const override { return ItemKind::TypeAlias; }
    1152              : 
    1153        72286 :   Analysis::NodeMapping get_impl_mappings () const override
    1154              :   {
    1155        72286 :     return get_mappings ();
    1156              :   };
    1157              : 
    1158        15575 :   std::string get_impl_item_name () const override final
    1159              :   {
    1160        31150 :     return get_new_type_name ().as_string ();
    1161              :   }
    1162              : 
    1163              : protected:
    1164              :   /* Use covariance to implement clone function as returning this object
    1165              :    * rather than base */
    1166            0 :   TypeAlias *clone_item_impl () const override { return new TypeAlias (*this); }
    1167              : 
    1168              :   /* Use covariance to implement clone function as returning this object
    1169              :    * rather than base */
    1170            0 :   TypeAlias *clone_inherent_impl_item_impl () const override
    1171              :   {
    1172            0 :     return new TypeAlias (*this);
    1173              :   }
    1174              : };
    1175              : 
    1176              : // Rust base struct declaration HIR node - abstract base class
    1177              : class Struct : public VisItem
    1178              : {
    1179              : protected:
    1180              :   // protected to enable access by derived classes - allows better to_string
    1181              :   Identifier struct_name;
    1182              : 
    1183              :   // bool has_generics;
    1184              :   // Generics generic_params;
    1185              :   std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
    1186              : 
    1187              :   // bool has_where_clause;
    1188              :   WhereClause where_clause;
    1189              : 
    1190              :   location_t locus;
    1191              : 
    1192              : public:
    1193         5422 :   Identifier get_identifier () const { return struct_name; }
    1194              : 
    1195              :   // Returns whether struct has generic parameters.
    1196         2456 :   bool has_generics () const { return !generic_params.empty (); }
    1197              : 
    1198              :   // Returns whether struct has a where clause.
    1199         2336 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    1200              : 
    1201        12890 :   location_t get_locus () const override final { return locus; }
    1202         1864 :   ItemKind get_item_kind () const override { return ItemKind::Struct; }
    1203              : 
    1204         4461 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    1205              :   {
    1206         6797 :     return generic_params;
    1207              :   }
    1208              : 
    1209            2 :   WhereClause &get_where_clause () { return where_clause; }
    1210              : 
    1211              : protected:
    1212         2465 :   Struct (Analysis::NodeMapping mappings, Identifier struct_name,
    1213              :           std::vector<std::unique_ptr<GenericParam>> generic_params,
    1214              :           WhereClause where_clause, Visibility vis, location_t locus,
    1215              :           AST::AttrVec outer_attrs = AST::AttrVec ())
    1216         2465 :     : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
    1217         4930 :       struct_name (std::move (struct_name)),
    1218         2465 :       generic_params (std::move (generic_params)),
    1219         2465 :       where_clause (std::move (where_clause)), locus (locus)
    1220         2465 :   {}
    1221              : 
    1222              :   // Copy constructor with vector clone
    1223            0 :   Struct (Struct const &other)
    1224            0 :     : VisItem (other), struct_name (other.struct_name),
    1225            0 :       where_clause (other.where_clause), locus (other.locus)
    1226              :   {
    1227            0 :     generic_params.reserve (other.generic_params.size ());
    1228            0 :     for (const auto &e : other.generic_params)
    1229            0 :       generic_params.push_back (e->clone_generic_param ());
    1230            0 :   }
    1231              : 
    1232              :   // Overloaded assignment operator with vector clone
    1233              :   Struct &operator= (Struct const &other)
    1234              :   {
    1235              :     VisItem::operator= (other);
    1236              :     struct_name = other.struct_name;
    1237              :     where_clause = other.where_clause;
    1238              :     locus = other.locus;
    1239              : 
    1240              :     generic_params.reserve (other.generic_params.size ());
    1241              :     for (const auto &e : other.generic_params)
    1242              :       generic_params.push_back (e->clone_generic_param ());
    1243              : 
    1244              :     return *this;
    1245              :   }
    1246              : 
    1247              :   // move constructors
    1248              :   Struct (Struct &&other) = default;
    1249              :   Struct &operator= (Struct &&other) = default;
    1250              : };
    1251              : 
    1252              : // A single field in a struct
    1253              : // FIXME can't this be a TupleStruct + field_name?
    1254              : class StructField
    1255              : {
    1256              : public:
    1257              :   // bool has_outer_attributes;
    1258              :   AST::AttrVec outer_attrs;
    1259              : 
    1260              :   // bool has_visibility;
    1261              :   Visibility visibility;
    1262              : 
    1263              :   Identifier field_name;
    1264              :   std::unique_ptr<Type> field_type;
    1265              : 
    1266              :   Analysis::NodeMapping mappings;
    1267              : 
    1268              :   location_t locus;
    1269              : 
    1270              :   // Returns whether struct field has any outer attributes.
    1271              :   bool has_outer_attributes () const { return !outer_attrs.empty (); }
    1272              : 
    1273              :   // Returns whether struct field has a non-private (non-default) visibility.
    1274            0 :   bool has_visibility () const { return !visibility.is_error (); }
    1275              : 
    1276              :   StructField (Analysis::NodeMapping mappings, Identifier field_name,
    1277              :                std::unique_ptr<Type> field_type, Visibility vis,
    1278              :                location_t locus, AST::AttrVec outer_attrs = AST::AttrVec ());
    1279              : 
    1280              :   // Copy constructor
    1281              :   StructField (StructField const &other);
    1282              : 
    1283         3624 :   ~StructField () = default;
    1284              : 
    1285              :   // Overloaded assignment operator to clone
    1286              :   StructField &operator= (StructField const &other);
    1287              : 
    1288              :   // move constructors
    1289         3594 :   StructField (StructField &&other) = default;
    1290              :   StructField &operator= (StructField &&other) = default;
    1291              : 
    1292              :   std::string to_string () const;
    1293              : 
    1294         7232 :   Identifier get_field_name () const { return field_name; }
    1295              : 
    1296         4601 :   Type &get_field_type () { return *field_type; }
    1297              : 
    1298         6025 :   Analysis::NodeMapping get_mappings () const { return mappings; }
    1299              : 
    1300         2715 :   location_t get_locus () { return locus; }
    1301            0 :   AST::AttrVec &get_outer_attrs () { return outer_attrs; }
    1302            0 :   Visibility &get_visibility () { return visibility; }
    1303              : };
    1304              : 
    1305              : // Rust struct declaration with true struct type HIR node
    1306              : class StructStruct : public Struct
    1307              : {
    1308              : public:
    1309              :   std::vector<StructField> fields;
    1310              :   bool is_unit;
    1311              : 
    1312              :   std::string to_string () const override;
    1313              : 
    1314              :   // Mega-constructor with all possible fields
    1315         1508 :   StructStruct (Analysis::NodeMapping mappings, std::vector<StructField> fields,
    1316              :                 Identifier struct_name,
    1317              :                 std::vector<std::unique_ptr<GenericParam>> generic_params,
    1318              :                 WhereClause where_clause, bool is_unit, Visibility vis,
    1319              :                 AST::AttrVec outer_attrs, location_t locus)
    1320         1508 :     : Struct (std::move (mappings), std::move (struct_name),
    1321              :               std::move (generic_params), std::move (where_clause),
    1322              :               std::move (vis), locus, std::move (outer_attrs)),
    1323         1508 :       fields (std::move (fields)), is_unit (is_unit)
    1324         1508 :   {}
    1325              : 
    1326              :   // Unit struct constructor
    1327              :   StructStruct (Analysis::NodeMapping mappings, Identifier struct_name,
    1328              :                 std::vector<std::unique_ptr<GenericParam>> generic_params,
    1329              :                 WhereClause where_clause, Visibility vis,
    1330              :                 AST::AttrVec outer_attrs, location_t locus)
    1331              :     : Struct (std::move (mappings), std::move (struct_name),
    1332              :               std::move (generic_params), std::move (where_clause),
    1333              :               std::move (vis), locus, std::move (outer_attrs)),
    1334              :       is_unit (true)
    1335              :   {}
    1336              :   // TODO: can a unit struct have generic fields? assuming yes for now.
    1337              : 
    1338              :   /* Returns whether the struct is a unit struct - struct defined without
    1339              :    * fields. This is important because it also means an implicit constant of its
    1340              :    * type is defined. */
    1341            0 :   bool is_unit_struct () const { return is_unit; }
    1342              : 
    1343              :   void accept_vis (HIRFullVisitor &vis) override;
    1344              :   void accept_vis (HIRStmtVisitor &vis) override;
    1345              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1346              : 
    1347         4265 :   std::vector<StructField> &get_fields () { return fields; }
    1348              : 
    1349              : protected:
    1350              :   /* Use covariance to implement clone function as returning this object
    1351              :    * rather than base */
    1352            0 :   StructStruct *clone_item_impl () const override
    1353              :   {
    1354            0 :     return new StructStruct (*this);
    1355              :   }
    1356              : 
    1357              :   /* Use covariance to implement clone function as returning this object
    1358              :    * rather than base */
    1359              :   /*virtual StructStruct* clone_statement_impl() const override {
    1360              :       return new StructStruct(*this);
    1361              :   }*/
    1362              : };
    1363              : 
    1364              : // A single field in a tuple
    1365              : class TupleField
    1366              : {
    1367              : private:
    1368              :   // bool has_outer_attributes;
    1369              :   AST::AttrVec outer_attrs;
    1370              : 
    1371              :   // bool has_visibility;
    1372              :   Visibility visibility;
    1373              : 
    1374              :   std::unique_ptr<Type> field_type;
    1375              : 
    1376              :   location_t locus;
    1377              : 
    1378              :   Analysis::NodeMapping mappings;
    1379              : 
    1380              : public:
    1381              :   // Returns whether tuple field has outer attributes.
    1382              :   bool has_outer_attributes () const { return !outer_attrs.empty (); }
    1383              : 
    1384              :   /* Returns whether tuple field has a non-default visibility (i.e. a public
    1385              :    * one) */
    1386            0 :   bool has_visibility () const { return !visibility.is_error (); }
    1387              : 
    1388              :   // Complete constructor
    1389              :   TupleField (Analysis::NodeMapping mapping, std::unique_ptr<Type> field_type,
    1390              :               Visibility vis, location_t locus,
    1391              :               AST::AttrVec outer_attrs = AST::AttrVec ());
    1392              : 
    1393              :   // Copy constructor with clone
    1394              :   TupleField (TupleField const &other);
    1395              : 
    1396           10 :   ~TupleField () = default;
    1397              : 
    1398              :   // Overloaded assignment operator to clone
    1399              :   TupleField &operator= (TupleField const &other);
    1400              : 
    1401              :   // move constructors
    1402            0 :   TupleField (TupleField &&other) = default;
    1403              :   TupleField &operator= (TupleField &&other) = default;
    1404              : 
    1405              :   // Returns whether tuple field is in an error state.
    1406              :   bool is_error () const { return field_type == nullptr; }
    1407              : 
    1408              :   std::string to_string () const;
    1409              : 
    1410         4495 :   Analysis::NodeMapping get_mappings () const { return mappings; }
    1411              : 
    1412            0 :   Visibility &get_visibility () { return visibility; }
    1413              : 
    1414         2043 :   location_t get_locus () const { return locus; }
    1415              : 
    1416            0 :   AST::AttrVec &get_outer_attrs () { return outer_attrs; }
    1417         4027 :   HIR::Type &get_field_type () { return *field_type; }
    1418              : };
    1419              : 
    1420              : // Rust tuple declared using struct keyword HIR node
    1421              : class TupleStruct : public Struct
    1422              : {
    1423              :   std::vector<TupleField> fields;
    1424              : 
    1425              : public:
    1426              :   std::string to_string () const override;
    1427              : 
    1428              :   // Mega-constructor with all possible fields
    1429              :   TupleStruct (Analysis::NodeMapping mappings, std::vector<TupleField> fields,
    1430              :                Identifier struct_name,
    1431              :                std::vector<std::unique_ptr<GenericParam>> generic_params,
    1432              :                WhereClause where_clause, Visibility vis,
    1433              :                AST::AttrVec outer_attrs, location_t locus);
    1434              : 
    1435              :   void accept_vis (HIRFullVisitor &vis) override;
    1436              :   void accept_vis (HIRStmtVisitor &vis) override;
    1437              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1438              : 
    1439         1882 :   std::vector<TupleField> &get_fields () { return fields; }
    1440              :   const std::vector<TupleField> &get_fields () const { return fields; }
    1441              : 
    1442              : protected:
    1443              :   /* Use covariance to implement clone function as returning this object
    1444              :    * rather than base */
    1445            0 :   TupleStruct *clone_item_impl () const override
    1446              :   {
    1447            0 :     return new TupleStruct (*this);
    1448              :   }
    1449              : 
    1450              :   /* Use covariance to implement clone function as returning this object
    1451              :    * rather than base */
    1452              :   /*virtual TupleStruct* clone_statement_impl() const override {
    1453              :       return new TupleStruct(*this);
    1454              :   }*/
    1455              : };
    1456              : 
    1457              : /* An item used in an "enum" tagged union - not abstract: base represents a
    1458              :    name-only enum. Syntactically EnumItem's can have a Visibility. But not
    1459              :    Semantically. So check there is no Visibility when lowering and make this
    1460              :    an Item, not an VisItem.  */
    1461              : class EnumItem : public Item
    1462              : {
    1463              :   Identifier variant_name;
    1464              :   location_t locus;
    1465              : 
    1466              : public:
    1467           29 :   virtual ~EnumItem () {}
    1468              : 
    1469              :   enum EnumItemKind
    1470              :   {
    1471              :     Named,
    1472              :     Tuple,
    1473              :     Struct,
    1474              :     Discriminant,
    1475              :   };
    1476              : 
    1477              :   EnumItem (Analysis::NodeMapping mappings, Identifier variant_name,
    1478              :             AST::AttrVec outer_attrs, location_t locus);
    1479              : 
    1480              :   // Unique pointer custom clone function
    1481            0 :   std::unique_ptr<EnumItem> clone_enum_item () const
    1482              :   {
    1483            0 :     return std::unique_ptr<EnumItem> (clone_item_impl ());
    1484              :   }
    1485              : 
    1486              :   virtual std::string to_string () const override;
    1487          837 :   virtual EnumItemKind get_enum_item_kind () const { return Named; };
    1488              : 
    1489              :   // not pure virtual as not abstract
    1490              :   void accept_vis (HIRFullVisitor &vis) override;
    1491              :   void accept_vis (HIRStmtVisitor &vis) override;
    1492              :   // void accept_vis (HIRVisItemVisitor &vis) override;
    1493              : 
    1494         7868 :   location_t get_locus () const override { return locus; }
    1495              : 
    1496         1202 :   Identifier get_identifier () const { return variant_name; }
    1497              : 
    1498            0 :   ItemKind get_item_kind () const override { return ItemKind::EnumItem; }
    1499              : 
    1500              : protected:
    1501            0 :   EnumItem *clone_item_impl () const override { return new EnumItem (*this); }
    1502              : };
    1503              : 
    1504              : // A tuple item used in an "enum" tagged union
    1505              : class EnumItemTuple : public EnumItem
    1506              : {
    1507              :   // bool has_tuple_fields;
    1508              :   std::vector<TupleField> tuple_fields;
    1509              : 
    1510              : public:
    1511              :   // Returns whether tuple enum item has tuple fields.
    1512            0 :   bool has_tuple_fields () const { return !tuple_fields.empty (); }
    1513              : 
    1514          799 :   EnumItemKind get_enum_item_kind () const override
    1515              :   {
    1516          799 :     return EnumItemKind::Tuple;
    1517              :   }
    1518              : 
    1519              :   EnumItemTuple (Analysis::NodeMapping mappings, Identifier variant_name,
    1520              :                  std::vector<TupleField> tuple_fields, AST::AttrVec outer_attrs,
    1521              :                  location_t locus);
    1522              : 
    1523              :   std::string to_string () const override;
    1524              : 
    1525              :   void accept_vis (HIRFullVisitor &vis) override;
    1526              :   void accept_vis (HIRStmtVisitor &vis) override;
    1527              : 
    1528         1187 :   std::vector<TupleField> &get_tuple_fields () { return tuple_fields; }
    1529              : 
    1530              : protected:
    1531              :   // Clone function implementation as (not pure) virtual method
    1532            0 :   EnumItemTuple *clone_item_impl () const override
    1533              :   {
    1534            0 :     return new EnumItemTuple (*this);
    1535              :   }
    1536              : };
    1537              : 
    1538              : // A struct item used in an "enum" tagged union
    1539              : class EnumItemStruct : public EnumItem
    1540              : {
    1541              :   // bool has_struct_fields;
    1542              :   std::vector<StructField> struct_fields;
    1543              : 
    1544              : public:
    1545              :   // Returns whether struct enum item has struct fields.
    1546            0 :   bool has_struct_fields () const { return !struct_fields.empty (); }
    1547              : 
    1548          165 :   EnumItemKind get_enum_item_kind () const override
    1549              :   {
    1550          165 :     return EnumItemKind::Struct;
    1551              :   }
    1552              : 
    1553              :   EnumItemStruct (Analysis::NodeMapping mappings, Identifier variant_name,
    1554              :                   std::vector<StructField> struct_fields,
    1555              :                   AST::AttrVec outer_attrs, location_t locus);
    1556              : 
    1557              :   std::string to_string () const override;
    1558              : 
    1559              :   void accept_vis (HIRFullVisitor &vis) override;
    1560              :   void accept_vis (HIRStmtVisitor &vis) override;
    1561              : 
    1562          244 :   std::vector<StructField> &get_struct_fields () { return struct_fields; }
    1563              : 
    1564              : protected:
    1565              :   // Clone function implementation as (not pure) virtual method
    1566            0 :   EnumItemStruct *clone_item_impl () const override
    1567              :   {
    1568            0 :     return new EnumItemStruct (*this);
    1569              :   }
    1570              : };
    1571              : 
    1572              : // A discriminant (numbered enum) item used in an "enum" tagged union
    1573              : class EnumItemDiscriminant : public EnumItem
    1574              : {
    1575              :   std::unique_ptr<Expr> expression;
    1576              : 
    1577              : public:
    1578              :   EnumItemDiscriminant (Analysis::NodeMapping mappings, Identifier variant_name,
    1579              :                         std::unique_ptr<Expr> expr, AST::AttrVec outer_attrs,
    1580              :                         location_t locus);
    1581              : 
    1582              :   // Copy constructor with clone
    1583              :   EnumItemDiscriminant (EnumItemDiscriminant const &other);
    1584              : 
    1585              :   // Overloaded assignment operator to clone
    1586              :   EnumItemDiscriminant &operator= (EnumItemDiscriminant const &other);
    1587              : 
    1588              :   // move constructors
    1589              :   EnumItemDiscriminant (EnumItemDiscriminant &&other) = default;
    1590              :   EnumItemDiscriminant &operator= (EnumItemDiscriminant &&other) = default;
    1591              : 
    1592          537 :   EnumItemKind get_enum_item_kind () const override
    1593              :   {
    1594          537 :     return EnumItemKind::Discriminant;
    1595              :   }
    1596              : 
    1597              :   std::string to_string () const override;
    1598              : 
    1599              :   void accept_vis (HIRFullVisitor &vis) override;
    1600              :   void accept_vis (HIRStmtVisitor &vis) override;
    1601              : 
    1602         1075 :   Expr &get_discriminant_expression () { return *expression; }
    1603              : 
    1604              :   std::unique_ptr<Expr> take_discriminant_expression ()
    1605              :   {
    1606              :     return std::move (expression);
    1607              :   }
    1608              : 
    1609              : protected:
    1610              :   // Clone function implementation as (not pure) virtual method
    1611            0 :   EnumItemDiscriminant *clone_item_impl () const override
    1612              :   {
    1613            0 :     return new EnumItemDiscriminant (*this);
    1614              :   }
    1615              : };
    1616              : 
    1617              : // HIR node for Rust "enum" - tagged union
    1618              : class Enum : public VisItem
    1619              : {
    1620              :   Identifier enum_name;
    1621              : 
    1622              :   // bool has_generics;
    1623              :   // Generics generic_params;
    1624              :   std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
    1625              : 
    1626              :   // bool has_where_clause;
    1627              :   WhereClause where_clause;
    1628              : 
    1629              :   std::vector<std::unique_ptr<EnumItem>> items;
    1630              : 
    1631              :   location_t locus;
    1632              : 
    1633              : public:
    1634              :   std::string to_string () const override;
    1635              : 
    1636              :   // Returns whether "enum" has generic parameters.
    1637          514 :   bool has_generics () const { return !generic_params.empty (); }
    1638              : 
    1639              :   // Returns whether "enum" has a where clause.
    1640          480 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    1641              : 
    1642              :   /* Returns whether enum is a "zero-variant" (no possible variant) enum,
    1643              :    * which cannot be instantiated. */
    1644          514 :   bool is_zero_variant () const { return items.empty (); }
    1645              : 
    1646              :   // Mega-constructor
    1647              :   Enum (Analysis::NodeMapping mappings, Identifier enum_name, Visibility vis,
    1648              :         std::vector<std::unique_ptr<GenericParam>> generic_params,
    1649              :         WhereClause where_clause, std::vector<std::unique_ptr<EnumItem>> items,
    1650              :         AST::AttrVec outer_attrs, location_t locus);
    1651              : 
    1652              :   // TODO: constructor with less arguments
    1653              : 
    1654              :   // Copy constructor with vector clone
    1655              :   Enum (Enum const &other);
    1656              : 
    1657              :   // Overloaded assignment operator with vector clone
    1658              :   Enum &operator= (Enum const &other);
    1659              : 
    1660              :   // Move constructors
    1661              :   Enum (Enum &&other) = default;
    1662              :   Enum &operator= (Enum &&other) = default;
    1663              : 
    1664         2607 :   location_t get_locus () const override final { return locus; }
    1665              : 
    1666              :   void accept_vis (HIRFullVisitor &vis) override;
    1667              :   void accept_vis (HIRStmtVisitor &vis) override;
    1668              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1669              : 
    1670          512 :   Identifier get_identifier () const { return enum_name; }
    1671            3 :   ItemKind get_item_kind () const override { return ItemKind::Enum; }
    1672              : 
    1673         1186 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    1674              :   {
    1675         1666 :     return generic_params;
    1676              :   }
    1677              : 
    1678              :   const std::vector<std::unique_ptr<EnumItem>> &get_variants () const
    1679              :   {
    1680              :     return items;
    1681              :   }
    1682              : 
    1683         2953 :   std::vector<std::unique_ptr<EnumItem>> &get_variants () { return items; }
    1684            0 :   WhereClause &get_where_clause () { return where_clause; }
    1685              : 
    1686              : protected:
    1687              :   /* Use covariance to implement clone function as returning this object
    1688              :    * rather than base */
    1689            0 :   Enum *clone_item_impl () const override { return new Enum (*this); }
    1690              : 
    1691              :   /* Use covariance to implement clone function as returning this object
    1692              :    * rather than base */
    1693              :   /*virtual Enum* clone_statement_impl() const override {
    1694              :       return new Enum(*this);
    1695              :   }*/
    1696              : };
    1697              : 
    1698              : // Rust untagged union used for C compat HIR node
    1699              : class Union : public VisItem
    1700              : {
    1701              :   Identifier union_name;
    1702              : 
    1703              :   // bool has_generics;
    1704              :   // Generics generic_params;
    1705              :   std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
    1706              : 
    1707              :   // bool has_where_clause;
    1708              :   WhereClause where_clause;
    1709              : 
    1710              :   std::vector<StructField> variants;
    1711              : 
    1712              :   location_t locus;
    1713              : 
    1714              : public:
    1715              :   std::string to_string () const override;
    1716              : 
    1717              :   // Returns whether union has generic params.
    1718          100 :   bool has_generics () const { return !generic_params.empty (); }
    1719              : 
    1720              :   // Returns whether union has where clause.
    1721           96 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    1722              : 
    1723              :   Union (Analysis::NodeMapping mappings, Identifier union_name, Visibility vis,
    1724              :          std::vector<std::unique_ptr<GenericParam>> generic_params,
    1725              :          WhereClause where_clause, std::vector<StructField> variants,
    1726              :          AST::AttrVec outer_attrs, location_t locus);
    1727              : 
    1728              :   // copy constructor with vector clone
    1729              :   Union (Union const &other);
    1730              : 
    1731              :   // overloaded assignment operator with vector clone
    1732              :   Union &operator= (Union const &other);
    1733              : 
    1734              :   // move constructors
    1735              :   Union (Union &&other) = default;
    1736              :   Union &operator= (Union &&other) = default;
    1737              : 
    1738          268 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    1739              :   {
    1740          364 :     return generic_params;
    1741              :   }
    1742              : 
    1743          200 :   Identifier get_identifier () const { return union_name; }
    1744              : 
    1745          479 :   location_t get_locus () const override final { return locus; }
    1746              : 
    1747              :   void accept_vis (HIRFullVisitor &vis) override;
    1748              :   void accept_vis (HIRStmtVisitor &vis) override;
    1749              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1750              : 
    1751          196 :   std::vector<StructField> &get_variants () { return variants; }
    1752              : 
    1753            0 :   WhereClause &get_where_clause () { return where_clause; }
    1754              : 
    1755            0 :   ItemKind get_item_kind () const override { return ItemKind::Union; }
    1756              : 
    1757              : protected:
    1758              :   /* Use covariance to implement clone function as returning this object
    1759              :    * rather than base */
    1760            0 :   Union *clone_item_impl () const override { return new Union (*this); }
    1761              : };
    1762              : 
    1763              : class ConstantItem : public VisItem, public ImplItem
    1764              : {
    1765              :   Identifier identifier;
    1766              :   std::unique_ptr<Type> type;
    1767              :   std::unique_ptr<Expr> const_expr;
    1768              :   location_t locus;
    1769              : 
    1770              : public:
    1771              :   std::string to_string () const override;
    1772              : 
    1773              :   ConstantItem (Analysis::NodeMapping mappings, Identifier ident,
    1774              :                 Visibility vis, std::unique_ptr<Type> type,
    1775              :                 std::unique_ptr<Expr> const_expr, AST::AttrVec outer_attrs,
    1776              :                 location_t locus);
    1777              : 
    1778              :   ConstantItem (ConstantItem const &other);
    1779              : 
    1780              :   // Overload assignment operator to clone
    1781              :   ConstantItem &operator= (ConstantItem const &other);
    1782              : 
    1783              :   // move constructors
    1784              :   ConstantItem (ConstantItem &&other) = default;
    1785              :   ConstantItem &operator= (ConstantItem &&other) = default;
    1786              : 
    1787              :   // Returns whether constant item is an "unnamed" (wildcard underscore used
    1788              :   // as identifier) constant.
    1789              :   bool is_unnamed () const
    1790              :   {
    1791              :     return identifier.as_string () == std::string ("_");
    1792              :   }
    1793              : 
    1794         2583 :   location_t get_locus () const override final { return locus; }
    1795              : 
    1796              :   void accept_vis (HIRFullVisitor &vis) override;
    1797              :   void accept_vis (HIRStmtVisitor &vis) override;
    1798              :   void accept_vis (HIRImplVisitor &vis) override;
    1799              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1800              : 
    1801         1549 :   Type &get_type ()
    1802              :   {
    1803         1549 :     rust_assert (type);
    1804         1549 :     return *type;
    1805              :   }
    1806              : 
    1807           54 :   bool has_expr () const { return const_expr != nullptr; }
    1808              : 
    1809         3629 :   Expr &get_expr () { return *const_expr; }
    1810              : 
    1811          211 :   Identifier get_identifier () const { return identifier; }
    1812              : 
    1813          738 :   Analysis::NodeMapping get_impl_mappings () const override
    1814              :   {
    1815          738 :     return get_mappings ();
    1816              :   };
    1817              : 
    1818          124 :   ImplItemType get_impl_item_type () const override final
    1819              :   {
    1820          124 :     return ImplItem::ImplItemType::CONSTANT;
    1821              :   }
    1822              : 
    1823          535 :   ItemKind get_item_kind () const override { return ItemKind::Constant; }
    1824              : 
    1825           58 :   std::string get_impl_item_name () const override final
    1826              :   {
    1827          116 :     return get_identifier ().as_string ();
    1828              :   }
    1829              : 
    1830              : protected:
    1831              :   /* Use covariance to implement clone function as returning this object
    1832              :    * rather than base */
    1833            0 :   ConstantItem *clone_item_impl () const override
    1834              :   {
    1835            0 :     return new ConstantItem (*this);
    1836              :   }
    1837              : 
    1838              :   /* Use covariance to implement clone function as returning this object
    1839              :    * rather than base */
    1840            0 :   ConstantItem *clone_inherent_impl_item_impl () const override
    1841              :   {
    1842            0 :     return new ConstantItem (*this);
    1843              :   }
    1844              : };
    1845              : 
    1846              : /* Static item HIR node - items within module scope with fixed storage
    1847              :  * duration? */
    1848              : class StaticItem : public VisItem
    1849              : {
    1850              :   Mutability mut;
    1851              :   Identifier name;
    1852              :   std::unique_ptr<Type> type;
    1853              :   std::unique_ptr<Expr> expr;
    1854              :   location_t locus;
    1855              : 
    1856              : public:
    1857              :   std::string to_string () const override;
    1858              : 
    1859              :   StaticItem (Analysis::NodeMapping mappings, Identifier name, Mutability mut,
    1860              :               std::unique_ptr<Type> type, std::unique_ptr<Expr> expr,
    1861              :               Visibility vis, AST::AttrVec outer_attrs, location_t locus);
    1862              : 
    1863              :   // Copy constructor with clone
    1864              :   StaticItem (StaticItem const &other);
    1865              : 
    1866              :   // Overloaded assignment operator to clone
    1867              :   StaticItem &operator= (StaticItem const &other);
    1868              : 
    1869              :   // move constructors
    1870              :   StaticItem (StaticItem &&other) = default;
    1871              :   StaticItem &operator= (StaticItem &&other) = default;
    1872              : 
    1873          322 :   location_t get_locus () const override final { return locus; }
    1874              : 
    1875              :   void accept_vis (HIRFullVisitor &vis) override;
    1876              :   void accept_vis (HIRStmtVisitor &vis) override;
    1877              :   void accept_vis (HIRVisItemVisitor &vis) override;
    1878              : 
    1879            3 :   Identifier get_identifier () const { return name; }
    1880              : 
    1881              :   Mutability get_mut () const { return mut; }
    1882              : 
    1883           22 :   bool is_mut () const { return mut == Mutability::Mut; }
    1884              : 
    1885          414 :   Expr &get_expr ()
    1886              :   {
    1887          414 :     rust_assert (expr);
    1888          414 :     return *expr;
    1889              :   }
    1890              : 
    1891          156 :   Type &get_type ()
    1892              :   {
    1893          156 :     rust_assert (type);
    1894          156 :     return *type;
    1895              :   }
    1896              : 
    1897           25 :   ItemKind get_item_kind () const override { return ItemKind::Static; }
    1898              : 
    1899              : protected:
    1900            0 :   StaticItem *clone_item_impl () const override
    1901              :   {
    1902            0 :     return new StaticItem (*this);
    1903              :   }
    1904              : };
    1905              : 
    1906              : // Function declaration in traits
    1907              : class TraitFunctionDecl
    1908              : {
    1909              : private:
    1910              :   FunctionQualifiers qualifiers;
    1911              :   Identifier function_name;
    1912              :   std::vector<std::unique_ptr<GenericParam>> generic_params;
    1913              :   std::vector<FunctionParam> function_params;
    1914              :   std::unique_ptr<Type> return_type;
    1915              :   WhereClause where_clause;
    1916              :   tl::optional<SelfParam> self;
    1917              : 
    1918              : public:
    1919              :   // Mega-constructor
    1920              :   TraitFunctionDecl (Identifier function_name, FunctionQualifiers qualifiers,
    1921              :                      std::vector<std::unique_ptr<GenericParam>> generic_params,
    1922              :                      tl::optional<SelfParam> self,
    1923              :                      std::vector<FunctionParam> function_params,
    1924              :                      std::unique_ptr<Type> return_type,
    1925              :                      WhereClause where_clause);
    1926              : 
    1927              :   // Copy constructor with clone
    1928              :   TraitFunctionDecl (TraitFunctionDecl const &other);
    1929              : 
    1930         9559 :   ~TraitFunctionDecl () = default;
    1931              : 
    1932              :   // Overloaded assignment operator with clone
    1933              :   TraitFunctionDecl &operator= (TraitFunctionDecl const &other);
    1934              : 
    1935              :   // move constructors
    1936         5090 :   TraitFunctionDecl (TraitFunctionDecl &&other) = default;
    1937              :   TraitFunctionDecl &operator= (TraitFunctionDecl &&other) = default;
    1938              : 
    1939              :   std::string to_string () const;
    1940              : 
    1941              :   // Returns whether function decl has generic parameters.
    1942        24737 :   bool has_generics () const { return !generic_params.empty (); }
    1943              : 
    1944              :   // Returns whether function decl has regular parameters.
    1945            0 :   bool has_params () const { return !function_params.empty (); }
    1946              : 
    1947              :   // Returns whether function has return type (otherwise is void).
    1948        28050 :   bool has_return_type () const { return return_type != nullptr; }
    1949              : 
    1950              :   // Returns whether function has a where clause.
    1951        27195 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    1952              : 
    1953            0 :   WhereClause &get_where_clause () { return where_clause; }
    1954              : 
    1955        66622 :   bool is_method () const { return self.has_value (); }
    1956              : 
    1957        23791 :   SelfParam &get_self_unchecked () { return self.value (); }
    1958            0 :   const SelfParam &get_self_unchecked () const { return self.value (); }
    1959              : 
    1960         2421 :   tl::optional<SelfParam> &get_self () { return self; }
    1961              :   const tl::optional<SelfParam> &get_self () const { return self; }
    1962              : 
    1963        28680 :   Identifier get_function_name () const { return function_name; }
    1964              : 
    1965           43 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    1966              :   {
    1967         2501 :     return generic_params;
    1968              :   }
    1969              : 
    1970        49438 :   Type &get_return_type () { return *return_type; }
    1971              : 
    1972        29993 :   std::vector<FunctionParam> &get_function_params () { return function_params; }
    1973              : 
    1974          255 :   const FunctionQualifiers &get_qualifiers () const { return qualifiers; }
    1975              : };
    1976              : 
    1977              : // Actual trait item function declaration within traits
    1978              : class TraitItemFunc : public TraitItem
    1979              : {
    1980              :   AST::AttrVec outer_attrs;
    1981              :   TraitFunctionDecl decl;
    1982              :   std::unique_ptr<BlockExpr> block_expr;
    1983              :   location_t locus;
    1984              : 
    1985              : public:
    1986              :   // Returns whether function has a definition or is just a declaration.
    1987        12665 :   bool has_definition () const { return block_expr != nullptr; }
    1988              : 
    1989              :   TraitItemFunc (Analysis::NodeMapping mappings, TraitFunctionDecl decl,
    1990              :                  std::unique_ptr<BlockExpr> block_expr,
    1991              :                  AST::AttrVec outer_attrs, location_t locus);
    1992              : 
    1993              :   // Copy constructor with clone
    1994              :   TraitItemFunc (TraitItemFunc const &other);
    1995              : 
    1996              :   // Overloaded assignment operator to clone
    1997              :   TraitItemFunc &operator= (TraitItemFunc const &other);
    1998              : 
    1999              :   // move constructors
    2000              :   TraitItemFunc (TraitItemFunc &&other) = default;
    2001              :   TraitItemFunc &operator= (TraitItemFunc &&other) = default;
    2002              : 
    2003              :   std::string to_string () const override;
    2004              : 
    2005        34047 :   location_t get_locus () const { return locus; }
    2006              : 
    2007              :   void accept_vis (HIRFullVisitor &vis) override;
    2008              :   void accept_vis (HIRTraitItemVisitor &vis) override;
    2009              : 
    2010        43869 :   TraitFunctionDecl &get_decl () { return decl; }
    2011              : 
    2012         1588 :   const TraitFunctionDecl &get_decl () const { return decl; }
    2013              : 
    2014         4491 :   BlockExpr &get_block_expr () { return *block_expr; }
    2015              : 
    2016         1154 :   const std::string trait_identifier () const override final
    2017              :   {
    2018         2308 :     return decl.get_function_name ().as_string ();
    2019              :   }
    2020              : 
    2021        16069 :   TraitItemKind get_item_kind () const override final
    2022              :   {
    2023        16069 :     return TraitItemKind::FUNC;
    2024              :   }
    2025              : 
    2026         2713 :   AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
    2027         6687 :   const AST::AttrVec &get_outer_attrs () const override final
    2028              :   {
    2029         6687 :     return outer_attrs;
    2030              :   }
    2031              : 
    2032         5090 :   location_t get_trait_locus () const override { return get_locus (); }
    2033              : 
    2034              : protected:
    2035              :   // Clone function implementation as (not pure) virtual method
    2036            0 :   TraitItemFunc *clone_trait_item_impl () const override
    2037              :   {
    2038            0 :     return new TraitItemFunc (*this);
    2039              :   }
    2040              : };
    2041              : 
    2042              : // Constant item within traits
    2043              : class TraitItemConst : public TraitItem
    2044              : {
    2045              :   AST::AttrVec outer_attrs;
    2046              :   Identifier name;
    2047              :   std::unique_ptr<Type> type;
    2048              :   std::unique_ptr<Expr> expr;
    2049              :   location_t locus;
    2050              : 
    2051              : public:
    2052              :   // Whether the constant item has an associated expression.
    2053            0 :   bool has_expression () const { return expr != nullptr; }
    2054              : 
    2055              :   TraitItemConst (Analysis::NodeMapping mappings, Identifier name,
    2056              :                   std::unique_ptr<Type> type, std::unique_ptr<Expr> expr,
    2057              :                   AST::AttrVec outer_attrs, location_t locus);
    2058              : 
    2059              :   // Copy constructor with clones
    2060              :   TraitItemConst (TraitItemConst const &other);
    2061              : 
    2062              :   // Overloaded assignment operator to clone
    2063              :   TraitItemConst &operator= (TraitItemConst const &other);
    2064              : 
    2065              :   // move constructors
    2066              :   TraitItemConst (TraitItemConst &&other) = default;
    2067              :   TraitItemConst &operator= (TraitItemConst &&other) = default;
    2068              : 
    2069              :   std::string to_string () const override;
    2070              : 
    2071          132 :   location_t get_locus () const { return locus; }
    2072              : 
    2073              :   void accept_vis (HIRFullVisitor &vis) override;
    2074              :   void accept_vis (HIRTraitItemVisitor &vis) override;
    2075              : 
    2076           38 :   Identifier get_name () const { return name; }
    2077              : 
    2078           38 :   bool has_type () const { return expr != nullptr; }
    2079              : 
    2080          231 :   bool has_expr () const { return expr != nullptr; }
    2081              : 
    2082           82 :   Type &get_type ()
    2083              :   {
    2084           82 :     rust_assert (type);
    2085           82 :     return *type;
    2086              :   }
    2087              : 
    2088           56 :   Expr &get_expr ()
    2089              :   {
    2090           56 :     rust_assert (expr);
    2091           56 :     return *expr;
    2092              :   }
    2093              : 
    2094            0 :   const std::string trait_identifier () const override final
    2095              :   {
    2096            0 :     return name.as_string ();
    2097              :   }
    2098              : 
    2099            1 :   TraitItemKind get_item_kind () const override final
    2100              :   {
    2101            1 :     return TraitItemKind::CONST;
    2102              :   }
    2103              : 
    2104           30 :   AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
    2105           68 :   const AST::AttrVec &get_outer_attrs () const override final
    2106              :   {
    2107           68 :     return outer_attrs;
    2108              :   }
    2109              : 
    2110           76 :   location_t get_trait_locus () const override { return get_locus (); }
    2111              : 
    2112              : protected:
    2113              :   // Clone function implementation as (not pure) virtual method
    2114            0 :   TraitItemConst *clone_trait_item_impl () const override
    2115              :   {
    2116            0 :     return new TraitItemConst (*this);
    2117              :   }
    2118              : };
    2119              : 
    2120              : // Type items within traits
    2121              : class TraitItemType : public TraitItem
    2122              : {
    2123              :   AST::AttrVec outer_attrs;
    2124              : 
    2125              :   Identifier name;
    2126              :   // Generic parameters for GATs (Generic Associated Types)
    2127              :   std::vector<std::unique_ptr<GenericParam>> generic_params;
    2128              :   std::vector<std::unique_ptr<TypeParamBound>>
    2129              :     type_param_bounds; // inlined form
    2130              :   location_t locus;
    2131              : 
    2132              : public:
    2133            0 :   bool has_generics () const { return !generic_params.empty (); }
    2134              : 
    2135              :   // Returns whether trait item type has type param bounds.
    2136            0 :   bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
    2137              : 
    2138              :   TraitItemType (Analysis::NodeMapping mappings, Identifier name,
    2139              :                  std::vector<std::unique_ptr<GenericParam>> generic_params,
    2140              :                  std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
    2141              :                  AST::AttrVec outer_attrs, location_t locus);
    2142              : 
    2143              :   // Copy constructor with vector clone
    2144              :   TraitItemType (TraitItemType const &other);
    2145              : 
    2146              :   // Overloaded assignment operator with vector clone
    2147              :   TraitItemType &operator= (TraitItemType const &other);
    2148              : 
    2149              :   // default move constructors
    2150              :   TraitItemType (TraitItemType &&other) = default;
    2151              :   TraitItemType &operator= (TraitItemType &&other) = default;
    2152              : 
    2153              :   std::string to_string () const override;
    2154              : 
    2155         2212 :   location_t get_locus () const { return locus; }
    2156              : 
    2157              :   void accept_vis (HIRFullVisitor &vis) override;
    2158              :   void accept_vis (HIRTraitItemVisitor &vis) override;
    2159              : 
    2160         1472 :   Identifier get_name () const { return name; }
    2161              : 
    2162              :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    2163              :   {
    2164              :     return generic_params;
    2165              :   }
    2166              :   const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
    2167              :   {
    2168              :     return generic_params;
    2169              :   }
    2170              : 
    2171            0 :   std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
    2172              :   {
    2173          709 :     return type_param_bounds;
    2174              :   }
    2175              : 
    2176          868 :   const std::string trait_identifier () const override final
    2177              :   {
    2178          868 :     return name.as_string ();
    2179              :   }
    2180              : 
    2181          841 :   TraitItemKind get_item_kind () const override final
    2182              :   {
    2183          841 :     return TraitItemKind::TYPE;
    2184              :   }
    2185              : 
    2186          709 :   AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
    2187         1913 :   const AST::AttrVec &get_outer_attrs () const override final
    2188              :   {
    2189         1913 :     return outer_attrs;
    2190              :   }
    2191              : 
    2192         1476 :   location_t get_trait_locus () const override { return get_locus (); }
    2193              : 
    2194              : protected:
    2195              :   // Clone function implementation as (not pure) virtual method
    2196            0 :   TraitItemType *clone_trait_item_impl () const override
    2197              :   {
    2198            0 :     return new TraitItemType (*this);
    2199              :   }
    2200              : };
    2201              : 
    2202              : // Rust trait item declaration HIR node
    2203              : class Trait : public VisItem
    2204              : {
    2205              :   Unsafety unsafety;
    2206              :   Identifier name;
    2207              :   std::vector<std::unique_ptr<GenericParam>> generic_params;
    2208              :   std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
    2209              :   WhereClause where_clause;
    2210              :   std::vector<std::unique_ptr<TraitItem>> trait_items;
    2211              :   location_t locus;
    2212              : 
    2213              : public:
    2214              :   std::string to_string () const override;
    2215              : 
    2216              :   // Returns whether trait has generic parameters.
    2217              :   bool has_generics () const { return !generic_params.empty (); }
    2218              : 
    2219              :   // Returns whether trait has type parameter bounds.
    2220         7733 :   bool has_type_param_bounds () const { return !type_param_bounds.empty (); }
    2221              : 
    2222              :   // Returns whether trait has where clause.
    2223         3494 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    2224              : 
    2225              :   // Returns whether trait has trait items.
    2226            0 :   bool has_trait_items () const { return !trait_items.empty (); }
    2227              : 
    2228            0 :   std::vector<std::unique_ptr<TraitItem>> &get_trait_items ()
    2229              :   {
    2230        22014 :     return trait_items;
    2231              :   }
    2232              : 
    2233            7 :   WhereClause &get_where_clause () { return where_clause; }
    2234              : 
    2235        61433 :   Identifier get_name () const { return name; }
    2236            0 :   bool is_unsafe () const { return unsafety == Unsafety::Unsafe; }
    2237              : 
    2238              :   // Mega-constructor
    2239              :   Trait (Analysis::NodeMapping mappings, Identifier name, Unsafety unsafety,
    2240              :          std::vector<std::unique_ptr<GenericParam>> generic_params,
    2241              :          std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
    2242              :          WhereClause where_clause,
    2243              :          std::vector<std::unique_ptr<TraitItem>> trait_items, Visibility vis,
    2244              :          AST::AttrVec outer_attrs, location_t locus);
    2245              : 
    2246              :   // Copy constructor with vector clone
    2247              :   Trait (Trait const &other);
    2248              : 
    2249              :   // Overloaded assignment operator with vector clone
    2250              :   Trait &operator= (Trait const &other);
    2251              : 
    2252              :   // default move constructors
    2253              :   Trait (Trait &&other) = default;
    2254              :   Trait &operator= (Trait &&other) = default;
    2255              : 
    2256        23101 :   location_t get_locus () const override final { return locus; }
    2257              : 
    2258              :   void accept_vis (HIRFullVisitor &vis) override;
    2259              :   void accept_vis (HIRStmtVisitor &vis) override;
    2260              :   void accept_vis (HIRVisItemVisitor &vis) override;
    2261              : 
    2262         7071 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    2263              :   {
    2264        14253 :     return generic_params;
    2265              :   }
    2266              : 
    2267              :   const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
    2268              :   {
    2269              :     return generic_params;
    2270              :   }
    2271              : 
    2272            0 :   std::vector<std::unique_ptr<TypeParamBound>> &get_type_param_bounds ()
    2273              :   {
    2274         3494 :     return type_param_bounds;
    2275              :   }
    2276              : 
    2277              :   const std::vector<std::unique_ptr<TypeParamBound>> &
    2278              :   get_type_param_bounds () const
    2279              :   {
    2280              :     return type_param_bounds;
    2281              :   }
    2282              : 
    2283      2306214 :   ItemKind get_item_kind () const override { return ItemKind::Trait; }
    2284              : 
    2285              : protected:
    2286              :   /* Use covariance to implement clone function as returning this object
    2287              :    * rather than base */
    2288            0 :   Trait *clone_item_impl () const override { return new Trait (*this); }
    2289              : };
    2290              : 
    2291              : class ImplBlock : public VisItem, public WithInnerAttrs
    2292              : {
    2293              :   std::vector<std::unique_ptr<GenericParam>> generic_params;
    2294              :   std::unique_ptr<Type> impl_type;
    2295              :   std::unique_ptr<TypePath> trait_ref;
    2296              :   WhereClause where_clause;
    2297              :   BoundPolarity polarity;
    2298              :   location_t locus;
    2299              :   std::vector<std::unique_ptr<ImplItem>> impl_items;
    2300              :   bool unsafe;
    2301              : 
    2302              : public:
    2303              :   ImplBlock (Analysis::NodeMapping mappings,
    2304              :              std::vector<std::unique_ptr<ImplItem>> impl_items,
    2305              :              std::vector<std::unique_ptr<GenericParam>> generic_params,
    2306              :              std::unique_ptr<Type> impl_type,
    2307              :              std::unique_ptr<TypePath> trait_ref, WhereClause where_clause,
    2308              :              BoundPolarity polarity, Visibility vis, AST::AttrVec inner_attrs,
    2309              :              AST::AttrVec outer_attrs, location_t locus, bool unsafe = false);
    2310              : 
    2311              :   ImplBlock (ImplBlock const &other);
    2312              : 
    2313              :   ImplBlock &operator= (ImplBlock const &other);
    2314              : 
    2315              :   ImplBlock (ImplBlock &&other) = default;
    2316              :   ImplBlock &operator= (ImplBlock &&other) = default;
    2317              : 
    2318              :   std::string to_string () const override;
    2319              : 
    2320              :   // Returns whether inherent impl block has inherent impl items.
    2321         5307 :   bool has_impl_items () const { return !impl_items.empty (); }
    2322              : 
    2323         5541 :   bool is_unsafe () const { return unsafe; }
    2324              : 
    2325              :   void accept_vis (HIRFullVisitor &vis) override;
    2326              :   void accept_vis (HIRStmtVisitor &vis) override;
    2327              :   void accept_vis (HIRVisItemVisitor &vis) override;
    2328              : 
    2329            0 :   std::vector<std::unique_ptr<ImplItem>> &get_impl_items ()
    2330              :   {
    2331       170521 :     return impl_items;
    2332              :   };
    2333              : 
    2334              :   const std::vector<std::unique_ptr<ImplItem>> &get_impl_items () const
    2335              :   {
    2336        46156 :     return impl_items;
    2337              :   };
    2338              : 
    2339              :   // Returns whether impl has generic parameters.
    2340        41264 :   bool has_generics () const { return !generic_params.empty (); }
    2341              : 
    2342              :   // Returns whether impl has where clause.
    2343         5310 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    2344              : 
    2345              :   // Returns the polarity of the impl.
    2346        36729 :   BoundPolarity get_polarity () const { return polarity; }
    2347              : 
    2348      1861502 :   location_t get_locus () const override final { return locus; }
    2349              : 
    2350      1983671 :   Type &get_type ()
    2351              :   {
    2352      1983671 :     rust_assert (impl_type);
    2353      1983671 :     return *impl_type;
    2354              :   };
    2355              : 
    2356         2860 :   bool has_type () { return impl_type != nullptr; }
    2357              : 
    2358        17012 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    2359              :   {
    2360        30040 :     return generic_params;
    2361              :   }
    2362              : 
    2363      2512352 :   bool has_trait_ref () const { return trait_ref != nullptr; }
    2364              : 
    2365      2229815 :   TypePath &get_trait_ref () { return *trait_ref; }
    2366              : 
    2367           83 :   WhereClause &get_where_clause () { return where_clause; }
    2368              : 
    2369            0 :   ItemKind get_item_kind () const override { return ItemKind::Impl; }
    2370              : 
    2371              : protected:
    2372            0 :   ImplBlock *clone_item_impl () const override { return new ImplBlock (*this); }
    2373              : };
    2374              : 
    2375              : // Abstract base class for an item used inside an extern block
    2376              : class ExternalItem : public Node
    2377              : {
    2378              :   Analysis::NodeMapping mappings;
    2379              :   AST::AttrVec outer_attrs;
    2380              :   Visibility visibility;
    2381              :   Identifier item_name;
    2382              :   location_t locus;
    2383              : 
    2384              : public:
    2385              :   enum class ExternKind
    2386              :   {
    2387              :     Static,
    2388              :     Function,
    2389              :     Type,
    2390              :   };
    2391              : 
    2392            1 :   virtual ~ExternalItem () {}
    2393              : 
    2394            0 :   BaseKind get_hir_kind () override final { return EXTERNAL; }
    2395              : 
    2396              :   virtual ExternKind get_extern_kind () = 0;
    2397              : 
    2398              :   // Returns whether item has outer attributes.
    2399              :   bool has_outer_attrs () const { return !outer_attrs.empty (); }
    2400              : 
    2401              :   // Returns whether item has non-default visibility.
    2402            0 :   bool has_visibility () const { return !visibility.is_error (); }
    2403              : 
    2404              :   // Unique pointer custom clone function
    2405            0 :   std::unique_ptr<ExternalItem> clone_external_item () const
    2406              :   {
    2407            0 :     return std::unique_ptr<ExternalItem> (clone_external_item_impl ());
    2408              :   }
    2409              : 
    2410              :   virtual std::string to_string () const;
    2411              : 
    2412              :   std::string to_debug_string () const
    2413              :   {
    2414              :     return to_string () + mappings.as_string ();
    2415              :   }
    2416              : 
    2417         6309 :   location_t get_locus () const { return locus; }
    2418              : 
    2419              :   virtual void accept_vis (HIRFullVisitor &vis) = 0;
    2420              :   virtual void accept_vis (HIRExternalItemVisitor &vis) = 0;
    2421              : 
    2422            0 :   Visibility &get_visibility () { return visibility; }
    2423        17741 :   Analysis::NodeMapping get_mappings () const { return mappings; }
    2424              : 
    2425         6751 :   Identifier get_item_name () const { return item_name; }
    2426              : 
    2427         3769 :   AST::AttrVec &get_outer_attrs () { return outer_attrs; }
    2428              : 
    2429              : protected:
    2430              :   ExternalItem (Analysis::NodeMapping mappings, Identifier item_name,
    2431              :                 Visibility vis, AST::AttrVec outer_attrs, location_t locus);
    2432              : 
    2433              :   // Copy constructor
    2434              :   ExternalItem (ExternalItem const &other);
    2435              : 
    2436              :   // Overloaded assignment operator to clone
    2437              :   ExternalItem &operator= (ExternalItem const &other);
    2438              : 
    2439              :   // move constructors
    2440              :   ExternalItem (ExternalItem &&other) = default;
    2441              :   ExternalItem &operator= (ExternalItem &&other) = default;
    2442              : 
    2443              :   // Clone function implementation as pure virtual method
    2444              :   virtual ExternalItem *clone_external_item_impl () const = 0;
    2445              : };
    2446              : 
    2447              : // A static item used in an extern block
    2448              : class ExternalStaticItem : public ExternalItem
    2449              : {
    2450              :   Mutability mut;
    2451              :   std::unique_ptr<Type> item_type;
    2452              : 
    2453              : public:
    2454              :   ExternalStaticItem (Analysis::NodeMapping mappings, Identifier item_name,
    2455              :                       std::unique_ptr<Type> item_type, Mutability mut,
    2456              :                       Visibility vis, AST::AttrVec outer_attrs,
    2457              :                       location_t locus);
    2458              : 
    2459              :   // Copy constructor
    2460              :   ExternalStaticItem (ExternalStaticItem const &other);
    2461              : 
    2462              :   // Overloaded assignment operator to clone
    2463              :   ExternalStaticItem &operator= (ExternalStaticItem const &other);
    2464              : 
    2465              :   // move constructors
    2466              :   ExternalStaticItem (ExternalStaticItem &&other) = default;
    2467              :   ExternalStaticItem &operator= (ExternalStaticItem &&other) = default;
    2468              : 
    2469              :   std::string to_string () const override;
    2470              : 
    2471              :   void accept_vis (HIRFullVisitor &vis) override;
    2472              :   void accept_vis (HIRExternalItemVisitor &vis) override;
    2473              : 
    2474            0 :   bool is_mut () const { return mut == Mutability::Mut; }
    2475              : 
    2476              :   Mutability get_mut () { return mut; }
    2477              : 
    2478            1 :   Type &get_item_type () { return *item_type; }
    2479              : 
    2480            1 :   ExternKind get_extern_kind () override { return ExternKind::Static; }
    2481              : 
    2482              : protected:
    2483              :   /* Use covariance to implement clone function as returning this object
    2484              :    * rather than base */
    2485            0 :   ExternalStaticItem *clone_external_item_impl () const override
    2486              :   {
    2487            0 :     return new ExternalStaticItem (*this);
    2488              :   }
    2489              : };
    2490              : 
    2491              : // A named function parameter used in external functions
    2492              : struct NamedFunctionParam
    2493              : {
    2494              : private:
    2495              :   Identifier name;
    2496              :   std::unique_ptr<Type> param_type;
    2497              :   Analysis::NodeMapping mappings;
    2498              : 
    2499              : public:
    2500              :   bool has_name () const { return name.as_string () != "_"; }
    2501              : 
    2502              :   NamedFunctionParam (Analysis::NodeMapping mappings, Identifier name,
    2503              :                       std::unique_ptr<Type> param_type);
    2504              : 
    2505              :   // Copy constructor
    2506              :   NamedFunctionParam (NamedFunctionParam const &other);
    2507              : 
    2508          733 :   ~NamedFunctionParam () = default;
    2509              : 
    2510              :   // Overloaded assignment operator to clone
    2511              :   NamedFunctionParam &operator= (NamedFunctionParam const &other);
    2512              : 
    2513              :   // move constructors
    2514          732 :   NamedFunctionParam (NamedFunctionParam &&other) = default;
    2515              :   NamedFunctionParam &operator= (NamedFunctionParam &&other) = default;
    2516              : 
    2517              :   std::string to_string () const;
    2518              : 
    2519         2688 :   Identifier get_param_name () const { return name; }
    2520              : 
    2521         5320 :   Type &get_type ()
    2522              :   {
    2523         5320 :     rust_assert (param_type);
    2524         5320 :     return *param_type;
    2525              :   }
    2526              : 
    2527         2688 :   Analysis::NodeMapping get_mappings () const { return mappings; }
    2528              : };
    2529              : 
    2530              : // A function item used in an extern block
    2531              : class ExternalFunctionItem : public ExternalItem
    2532              : {
    2533              :   // bool has_generics;
    2534              :   // Generics generic_params;
    2535              :   std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
    2536              : 
    2537              :   // bool has_return_type;
    2538              :   // FunctionReturnType return_type;
    2539              :   std::unique_ptr<Type> return_type; // inlined
    2540              : 
    2541              :   // bool has_where_clause;
    2542              :   WhereClause where_clause;
    2543              : 
    2544              :   std::vector<NamedFunctionParam> function_params;
    2545              :   bool has_variadics;
    2546              : 
    2547              : public:
    2548              :   // Returns whether item has generic parameters.
    2549         2212 :   bool has_generics () const { return !generic_params.empty (); }
    2550              : 
    2551              :   // Returns whether item has a return type (otherwise void).
    2552         4369 :   bool has_return_type () const { return return_type != nullptr; }
    2553              : 
    2554              :   // Returns whether item has a where clause.
    2555         4369 :   bool has_where_clause () const { return !where_clause.is_empty (); }
    2556              : 
    2557            0 :   WARN_UNUSED_RESULT const WhereClause &get_where_clause () const
    2558              :   {
    2559            0 :     return where_clause;
    2560              :   }
    2561              : 
    2562              :   ExternalFunctionItem (
    2563              :     Analysis::NodeMapping mappings, Identifier item_name,
    2564              :     std::vector<std::unique_ptr<GenericParam>> generic_params,
    2565              :     std::unique_ptr<Type> return_type, WhereClause where_clause,
    2566              :     std::vector<NamedFunctionParam> function_params, bool has_variadics,
    2567              :     Visibility vis, AST::AttrVec outer_attrs, location_t locus);
    2568              : 
    2569              :   // Copy constructor with clone
    2570              :   ExternalFunctionItem (ExternalFunctionItem const &other);
    2571              : 
    2572              :   // Overloaded assignment operator with clone
    2573              :   ExternalFunctionItem &operator= (ExternalFunctionItem const &other);
    2574              : 
    2575              :   // move constructors
    2576              :   ExternalFunctionItem (ExternalFunctionItem &&other) = default;
    2577              :   ExternalFunctionItem &operator= (ExternalFunctionItem &&other) = default;
    2578              : 
    2579              :   std::string to_string () const override;
    2580              : 
    2581              :   void accept_vis (HIRFullVisitor &vis) override;
    2582              :   void accept_vis (HIRExternalItemVisitor &vis) override;
    2583              : 
    2584          816 :   std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
    2585              :   {
    2586         2974 :     return generic_params;
    2587              :   }
    2588              : 
    2589         3040 :   Type &get_return_type () { return *return_type; }
    2590              : 
    2591              :   std::vector<NamedFunctionParam> &get_function_params ()
    2592              :   {
    2593         4369 :     return function_params;
    2594              :   }
    2595              : 
    2596         2211 :   bool is_variadic () const { return has_variadics; }
    2597              : 
    2598          755 :   ExternKind get_extern_kind () override { return ExternKind::Function; }
    2599              : 
    2600              : protected:
    2601              :   /* Use covariance to implement clone function as returning this object
    2602              :    * rather than base */
    2603            0 :   ExternalFunctionItem *clone_external_item_impl () const override
    2604              :   {
    2605            0 :     return new ExternalFunctionItem (*this);
    2606              :   }
    2607              : };
    2608              : 
    2609              : class ExternalTypeItem : public ExternalItem
    2610              : {
    2611              : public:
    2612              :   ExternalTypeItem (Analysis::NodeMapping mappings, Identifier item_name,
    2613              :                     Visibility vis, location_t locus);
    2614              : 
    2615              :   ExternalTypeItem (ExternalTypeItem const &other);
    2616              : 
    2617              :   ExternalTypeItem (ExternalTypeItem &&other) = default;
    2618              :   ExternalTypeItem &operator= (ExternalTypeItem &&other) = default;
    2619              :   ExternalTypeItem &operator= (ExternalTypeItem const &other) = default;
    2620              : 
    2621              :   std::string to_string () const override;
    2622              : 
    2623              :   void accept_vis (HIRFullVisitor &vis) override;
    2624              :   void accept_vis (HIRExternalItemVisitor &vis) override;
    2625              : 
    2626            0 :   ExternKind get_extern_kind () override { return ExternKind::Type; }
    2627              : 
    2628              : protected:
    2629              :   /* Use covariance to implement clone function as returning this object
    2630              :    * rather than base */
    2631            0 :   ExternalTypeItem *clone_external_item_impl () const override
    2632              :   {
    2633            0 :     return new ExternalTypeItem (*this);
    2634              :   }
    2635              : };
    2636              : 
    2637              : // An extern block HIR node
    2638              : class ExternBlock : public VisItem, public WithInnerAttrs
    2639              : {
    2640              :   ABI abi;
    2641              :   std::vector<std::unique_ptr<ExternalItem>> extern_items;
    2642              :   location_t locus;
    2643              : 
    2644              : public:
    2645              :   std::string to_string () const override;
    2646              : 
    2647              :   // Returns whether extern block has extern items.
    2648            0 :   bool has_extern_items () const { return !extern_items.empty (); }
    2649              : 
    2650         4065 :   ABI get_abi () const { return abi; }
    2651              : 
    2652              :   ExternBlock (Analysis::NodeMapping mappings, ABI abi,
    2653              :                std::vector<std::unique_ptr<ExternalItem>> extern_items,
    2654              :                Visibility vis, AST::AttrVec inner_attrs,
    2655              :                AST::AttrVec outer_attrs, location_t locus);
    2656              : 
    2657              :   // Copy constructor with vector clone
    2658              :   ExternBlock (ExternBlock const &other);
    2659              : 
    2660              :   // Overloaded assignment operator with vector clone
    2661              :   ExternBlock &operator= (ExternBlock const &other);
    2662              : 
    2663              :   // move constructors
    2664              :   ExternBlock (ExternBlock &&other) = default;
    2665              :   ExternBlock &operator= (ExternBlock &&other) = default;
    2666              : 
    2667         4364 :   location_t get_locus () const override final { return locus; }
    2668              : 
    2669              :   void accept_vis (HIRFullVisitor &vis) override;
    2670              :   void accept_vis (HIRStmtVisitor &vis) override;
    2671              :   void accept_vis (HIRVisItemVisitor &vis) override;
    2672              : 
    2673            0 :   std::vector<std::unique_ptr<ExternalItem>> &get_extern_items ()
    2674              :   {
    2675         8690 :     return extern_items;
    2676              :   }
    2677              : 
    2678            0 :   ItemKind get_item_kind () const override { return ItemKind::ExternBlock; }
    2679              : 
    2680              : protected:
    2681              :   /* Use covariance to implement clone function as returning this object
    2682              :    * rather than base */
    2683            0 :   ExternBlock *clone_item_impl () const override
    2684              :   {
    2685            0 :     return new ExternBlock (*this);
    2686              :   }
    2687              : 
    2688              :   /* Use covariance to implement clone function as returning this object
    2689              :    * rather than base */
    2690              :   /*virtual ExternBlock* clone_statement_impl() const override {
    2691              :       return new ExternBlock(*this);
    2692              :   }*/
    2693              : };
    2694              : 
    2695              : } // namespace HIR
    2696              : } // namespace Rust
    2697              : 
    2698              : #endif
        

Generated by: LCOV version 2.4-beta

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