LCOV - code coverage report
Current view: top level - gcc/rust/hir/tree - rust-hir-pattern.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.7 % 357 338
Test Date: 2026-02-28 14:20:25 Functions: 95.7 % 92 88
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_PATTERN_H
      20              : #define RUST_HIR_PATTERN_H
      21              : 
      22              : #include "rust-hir-pattern-abstract.h"
      23              : #include "rust-common.h"
      24              : #include "rust-hir-literal.h"
      25              : #include "rust-hir-path.h"
      26              : 
      27              : namespace Rust {
      28              : namespace HIR {
      29              : // Literal pattern HIR node (comparing to a literal)
      30              : class LiteralPattern : public Pattern
      31              : {
      32              :   Literal lit;
      33              :   location_t locus;
      34              :   Analysis::NodeMapping mappings;
      35              :   bool has_minus;
      36              : 
      37              : public:
      38              :   std::string to_string () const override;
      39              : 
      40              :   // Constructor for a literal pattern
      41              :   LiteralPattern (Analysis::NodeMapping mappings, Literal lit, location_t locus)
      42              :     : lit (std::move (lit)), locus (locus), mappings (mappings),
      43              :       has_minus (false)
      44              :   {}
      45              : 
      46          436 :   LiteralPattern (Analysis::NodeMapping mappings, Literal lit, location_t locus,
      47              :                   bool has_minus)
      48          872 :     : lit (std::move (lit)), locus (locus), mappings (mappings),
      49          436 :       has_minus (has_minus)
      50          436 :   {}
      51              : 
      52              :   LiteralPattern (Analysis::NodeMapping mappings, std::string val,
      53              :                   Literal::LitType type, location_t locus)
      54              :     : lit (Literal (std::move (val), type, PrimitiveCoreType::CORETYPE_STR)),
      55              :       locus (locus), mappings (mappings), has_minus (false)
      56              :   {}
      57              : 
      58         2596 :   location_t get_locus () const override { return locus; }
      59              : 
      60              :   void accept_vis (HIRFullVisitor &vis) override;
      61              :   void accept_vis (HIRPatternVisitor &vis) override;
      62              : 
      63         2701 :   const Analysis::NodeMapping &get_mappings () const override final
      64              :   {
      65         2701 :     return mappings;
      66              :   }
      67              : 
      68          207 :   PatternType get_pattern_type () const override final
      69              :   {
      70          207 :     return PatternType::LITERAL;
      71              :   }
      72              : 
      73          831 :   Literal &get_literal () { return lit; }
      74              :   const Literal &get_literal () const { return lit; }
      75              : 
      76          406 :   bool get_has_minus () const { return has_minus; }
      77              : 
      78              : protected:
      79              :   /* Use covariance to implement clone function as returning this object rather
      80              :    * than base */
      81         1427 :   virtual LiteralPattern *clone_pattern_impl () const override
      82              :   {
      83         1427 :     return new LiteralPattern (*this);
      84              :   }
      85              : };
      86              : 
      87              : // Identifier pattern HIR node (bind value matched to a variable)
      88              : class IdentifierPattern : public Pattern
      89              : {
      90              :   Identifier variable_ident;
      91              :   bool is_ref;
      92              :   Mutability mut;
      93              :   std::unique_ptr<Pattern> subpattern;
      94              :   location_t locus;
      95              :   Analysis::NodeMapping mappings;
      96              : 
      97              : public:
      98              :   std::string to_string () const override;
      99              : 
     100              :   // Returns whether the IdentifierPattern has a pattern to bind.
     101       210758 :   bool has_subpattern () const { return subpattern != nullptr; }
     102              : 
     103              :   // Constructor
     104        53518 :   IdentifierPattern (Analysis::NodeMapping mappings, Identifier ident,
     105              :                      location_t locus, bool is_ref = false,
     106              :                      Mutability mut = Mutability::Imm,
     107              :                      std::unique_ptr<Pattern> subpattern = nullptr)
     108       107036 :     : variable_ident (std::move (ident)), is_ref (is_ref), mut (mut),
     109        53518 :       subpattern (std::move (subpattern)), locus (locus), mappings (mappings)
     110        53518 :   {}
     111              : 
     112              :   // Copy constructor with clone
     113        46361 :   IdentifierPattern (IdentifierPattern const &other)
     114        92722 :     : variable_ident (other.variable_ident), is_ref (other.is_ref),
     115        46361 :       mut (other.mut), locus (other.locus), mappings (other.mappings)
     116              :   {
     117              :     // fix to get prevent null pointer dereference
     118        46361 :     if (other.subpattern != nullptr)
     119           18 :       subpattern = other.subpattern->clone_pattern ();
     120        46361 :   }
     121              : 
     122              :   // Overload assignment operator to use clone
     123              :   IdentifierPattern &operator= (IdentifierPattern const &other)
     124              :   {
     125              :     variable_ident = other.variable_ident;
     126              :     is_ref = other.is_ref;
     127              :     mut = other.mut;
     128              :     locus = other.locus;
     129              :     mappings = other.mappings;
     130              : 
     131              :     // fix to get prevent null pointer dereference
     132              :     if (other.subpattern != nullptr)
     133              :       subpattern = other.subpattern->clone_pattern ();
     134              : 
     135              :     return *this;
     136              :   }
     137              : 
     138              :   // default move semantics
     139        32201 :   IdentifierPattern (IdentifierPattern &&other) = default;
     140              :   IdentifierPattern &operator= (IdentifierPattern &&other) = default;
     141              : 
     142        41827 :   location_t get_locus () const override { return locus; }
     143              : 
     144       162079 :   bool is_mut () const { return mut == Mutability::Mut; }
     145        51449 :   bool get_is_ref () const { return is_ref; }
     146           58 :   Pattern &get_subpattern () { return *subpattern; }
     147              : 
     148              :   void accept_vis (HIRFullVisitor &vis) override;
     149              :   void accept_vis (HIRPatternVisitor &vis) override;
     150              : 
     151       171249 :   const Analysis::NodeMapping &get_mappings () const override final
     152              :   {
     153       171249 :     return mappings;
     154              :   }
     155              : 
     156        21551 :   Identifier get_identifier () const { return variable_ident; }
     157              : 
     158        15564 :   PatternType get_pattern_type () const override final
     159              :   {
     160        15564 :     return PatternType::IDENTIFIER;
     161              :   }
     162              : 
     163              : protected:
     164              :   /* Use covariance to implement clone function as returning this object rather
     165              :    * than base */
     166        46361 :   IdentifierPattern *clone_pattern_impl () const override
     167              :   {
     168        46361 :     return new IdentifierPattern (*this);
     169              :   }
     170              : };
     171              : 
     172              : // HIR node for using the '_' wildcard "match any value" pattern
     173         1876 : class WildcardPattern : public Pattern
     174              : {
     175              :   location_t locus;
     176              :   Analysis::NodeMapping mappings;
     177              : 
     178              : public:
     179          479 :   std::string to_string () const override { return "_"; }
     180              : 
     181         1085 :   WildcardPattern (Analysis::NodeMapping mappings, location_t locus)
     182         1085 :     : locus (locus), mappings (mappings)
     183              :   {}
     184              : 
     185         2432 :   location_t get_locus () const override { return locus; }
     186              : 
     187              :   void accept_vis (HIRFullVisitor &vis) override;
     188              :   void accept_vis (HIRPatternVisitor &vis) override;
     189              : 
     190         6207 :   const Analysis::NodeMapping &get_mappings () const override final
     191              :   {
     192         6207 :     return mappings;
     193              :   }
     194              : 
     195          960 :   PatternType get_pattern_type () const override final
     196              :   {
     197          960 :     return PatternType::WILDCARD;
     198              :   }
     199              : 
     200              : protected:
     201              :   /* Use covariance to implement clone function as returning this object rather
     202              :    * than base */
     203         1876 :   WildcardPattern *clone_pattern_impl () const override
     204              :   {
     205         1876 :     return new WildcardPattern (*this);
     206              :   }
     207              : };
     208              : 
     209              : // Base range pattern bound (lower or upper limit) - abstract
     210          444 : class RangePatternBound
     211              : {
     212              : public:
     213              :   enum RangePatternBoundType
     214              :   {
     215              :     LITERAL,
     216              :     PATH,
     217              :     QUALPATH
     218              :   };
     219              : 
     220              :   virtual ~RangePatternBound () {}
     221              : 
     222              :   // Unique pointer custom clone function
     223          364 :   std::unique_ptr<RangePatternBound> clone_range_pattern_bound () const
     224              :   {
     225          182 :     return std::unique_ptr<RangePatternBound> (
     226          182 :       clone_range_pattern_bound_impl ());
     227              :   }
     228              : 
     229              :   virtual std::string to_string () const = 0;
     230              : 
     231              :   virtual void accept_vis (HIRFullVisitor &vis) = 0;
     232              : 
     233              :   virtual RangePatternBoundType get_bound_type () const = 0;
     234              : 
     235              : protected:
     236              :   // pure virtual as RangePatternBound is abstract
     237              :   virtual RangePatternBound *clone_range_pattern_bound_impl () const = 0;
     238              : };
     239              : 
     240              : // Literal-based pattern bound
     241          434 : class RangePatternBoundLiteral : public RangePatternBound
     242              : {
     243              :   Literal literal;
     244              :   /* Can only be a char, byte, int, or float literal - same impl here as
     245              :    * previously */
     246              : 
     247              :   // Minus prefixed to literal (if integer or floating-point)
     248              :   bool has_minus;
     249              : 
     250              :   location_t locus;
     251              : 
     252              : public:
     253              :   // Constructor
     254           59 :   RangePatternBoundLiteral (Literal literal, location_t locus,
     255              :                             bool has_minus = false)
     256           59 :     : literal (literal), has_minus (has_minus), locus (locus)
     257              :   {}
     258              : 
     259              :   std::string to_string () const override;
     260              : 
     261              :   location_t get_locus () const { return locus; }
     262              : 
     263          118 :   Literal get_literal () const { return literal; }
     264           59 :   bool get_has_minus () const { return has_minus; }
     265              : 
     266              :   void accept_vis (HIRFullVisitor &vis) override;
     267              : 
     268          118 :   RangePatternBoundType get_bound_type () const override
     269              :   {
     270          118 :     return RangePatternBoundType::LITERAL;
     271              :   }
     272              : 
     273              : protected:
     274              :   /* Use covariance to implement clone function as returning this object rather
     275              :    * than base */
     276          217 :   RangePatternBoundLiteral *clone_range_pattern_bound_impl () const override
     277              :   {
     278          217 :     return new RangePatternBoundLiteral (*this);
     279              :   }
     280              : };
     281              : 
     282              : // Path-based pattern bound
     283          147 : class RangePatternBoundPath : public RangePatternBound
     284              : {
     285              :   PathInExpression path;
     286              : 
     287              :   /* TODO: should this be refactored so that PathInExpression is a subclass of
     288              :    * RangePatternBound? */
     289              : 
     290              : public:
     291           21 :   RangePatternBoundPath (PathInExpression path) : path (std::move (path)) {}
     292              : 
     293            0 :   std::string to_string () const override { return path.to_string (); }
     294              : 
     295              :   location_t get_locus () const { return path.get_locus (); }
     296              : 
     297           42 :   PathInExpression &get_path () { return path; }
     298              :   const PathInExpression &get_path () const { return path; }
     299              : 
     300              :   void accept_vis (HIRFullVisitor &vis) override;
     301              : 
     302           42 :   RangePatternBoundType get_bound_type () const override
     303              :   {
     304           42 :     return RangePatternBoundType::PATH;
     305              :   }
     306              : 
     307              : protected:
     308              :   /* Use covariance to implement clone function as returning this object rather
     309              :    * than base */
     310          147 :   RangePatternBoundPath *clone_range_pattern_bound_impl () const override
     311              :   {
     312          147 :     return new RangePatternBoundPath (*this);
     313              :   }
     314              : };
     315              : 
     316              : // Qualified path-based pattern bound
     317            0 : class RangePatternBoundQualPath : public RangePatternBound
     318              : {
     319              :   QualifiedPathInExpression path;
     320              : 
     321              :   /* TODO: should this be refactored so that QualifiedPathInExpression is a
     322              :    * subclass of RangePatternBound? */
     323              : 
     324              : public:
     325            0 :   RangePatternBoundQualPath (QualifiedPathInExpression path)
     326            0 :     : path (std::move (path))
     327              :   {}
     328              : 
     329            0 :   std::string to_string () const override { return path.to_string (); }
     330              : 
     331              :   location_t get_locus () const { return path.get_locus (); }
     332              : 
     333              :   void accept_vis (HIRFullVisitor &vis) override;
     334              : 
     335            0 :   QualifiedPathInExpression &get_qualified_path () { return path; }
     336              :   const QualifiedPathInExpression &get_qualified_path () const { return path; }
     337              : 
     338            0 :   RangePatternBoundType get_bound_type () const override
     339              :   {
     340            0 :     return RangePatternBoundType::QUALPATH;
     341              :   }
     342              : 
     343              : protected:
     344              :   /* Use covariance to implement clone function as returning this object rather
     345              :    * than base */
     346            0 :   RangePatternBoundQualPath *clone_range_pattern_bound_impl () const override
     347              :   {
     348            0 :     return new RangePatternBoundQualPath (*this);
     349              :   }
     350              : };
     351              : 
     352              : // HIR node for matching within a certain range (range pattern)
     353              : class RangePattern : public Pattern
     354              : {
     355              :   std::unique_ptr<RangePatternBound> lower;
     356              :   std::unique_ptr<RangePatternBound> upper;
     357              : 
     358              :   bool has_ellipsis_syntax;
     359              : 
     360              :   /* location only stored to avoid a dereference - lower pattern should give
     361              :    * correct location so maybe change in future */
     362              :   location_t locus;
     363              :   bool is_inclusive;
     364              :   Analysis::NodeMapping mappings;
     365              : 
     366              : public:
     367              :   std::string to_string () const override;
     368              : 
     369              :   // Constructor
     370           40 :   RangePattern (Analysis::NodeMapping mappings,
     371              :                 std::unique_ptr<RangePatternBound> lower,
     372              :                 std::unique_ptr<RangePatternBound> upper, location_t locus,
     373              :                 bool is_inclusive, bool has_ellipsis_syntax = false)
     374           40 :     : lower (std::move (lower)), upper (std::move (upper)),
     375           40 :       has_ellipsis_syntax (has_ellipsis_syntax), locus (locus),
     376           40 :       is_inclusive (is_inclusive), mappings (mappings)
     377              :   {}
     378              : 
     379              :   // Copy constructor with clone
     380          182 :   RangePattern (RangePattern const &other)
     381          364 :     : lower (other.lower->clone_range_pattern_bound ()),
     382          182 :       upper (other.upper->clone_range_pattern_bound ()),
     383          182 :       has_ellipsis_syntax (other.has_ellipsis_syntax), locus (other.locus),
     384          182 :       is_inclusive (other.is_inclusive), mappings (other.mappings)
     385          182 :   {}
     386              : 
     387              :   // Overloaded assignment operator to clone
     388              :   RangePattern &operator= (RangePattern const &other)
     389              :   {
     390              :     lower = other.lower->clone_range_pattern_bound ();
     391              :     upper = other.upper->clone_range_pattern_bound ();
     392              :     has_ellipsis_syntax = other.has_ellipsis_syntax;
     393              :     locus = other.locus;
     394              :     is_inclusive = other.is_inclusive;
     395              :     mappings = other.mappings;
     396              : 
     397              :     return *this;
     398              :   }
     399              : 
     400              :   // default move semantics
     401              :   RangePattern (RangePattern &&other) = default;
     402              :   RangePattern &operator= (RangePattern &&other) = default;
     403              : 
     404          442 :   location_t get_locus () const override { return locus; }
     405              : 
     406              :   void accept_vis (HIRFullVisitor &vis) override;
     407              :   void accept_vis (HIRPatternVisitor &vis) override;
     408              : 
     409            0 :   bool get_has_ellipsis_syntax () { return has_ellipsis_syntax; };
     410           40 :   bool is_inclusive_range () const { return is_inclusive; }
     411              : 
     412          240 :   const Analysis::NodeMapping &get_mappings () const override final
     413              :   {
     414          240 :     return mappings;
     415              :   }
     416              : 
     417           40 :   PatternType get_pattern_type () const override final
     418              :   {
     419           40 :     return PatternType::RANGE;
     420              :   }
     421              : 
     422          117 :   RangePatternBound &get_lower_bound () { return *lower; }
     423              : 
     424          117 :   RangePatternBound &get_upper_bound () { return *upper; }
     425              : 
     426              : protected:
     427              :   /* Use covariance to implement clone function as returning this object rather
     428              :    * than base */
     429          182 :   RangePattern *clone_pattern_impl () const override
     430              :   {
     431          182 :     return new RangePattern (*this);
     432              :   }
     433              : };
     434              : 
     435              : // HIR node for pattern based on dereferencing the pointers given
     436              : class ReferencePattern : public Pattern
     437              : {
     438              :   Mutability mut;
     439              :   std::unique_ptr<Pattern> pattern;
     440              :   location_t locus;
     441              :   Analysis::NodeMapping mappings;
     442              : 
     443              : public:
     444              :   std::string to_string () const override;
     445              : 
     446          199 :   ReferencePattern (Analysis::NodeMapping mappings,
     447              :                     std::unique_ptr<Pattern> pattern, Mutability reference_mut,
     448              :                     location_t locus)
     449          199 :     : mut (reference_mut), pattern (std::move (pattern)), locus (locus),
     450          199 :       mappings (mappings)
     451              :   {}
     452              : 
     453              :   // Copy constructor requires clone
     454          327 :   ReferencePattern (ReferencePattern const &other)
     455          654 :     : mut (other.mut), pattern (other.pattern->clone_pattern ()),
     456          327 :       locus (other.locus), mappings (other.mappings)
     457          327 :   {}
     458              : 
     459              :   // Overload assignment operator to clone
     460              :   ReferencePattern &operator= (ReferencePattern const &other)
     461              :   {
     462              :     pattern = other.pattern->clone_pattern ();
     463              :     mut = other.mut;
     464              :     locus = other.locus;
     465              :     mappings = other.mappings;
     466              : 
     467              :     return *this;
     468              :   }
     469              : 
     470              :   // default move semantics
     471              :   ReferencePattern (ReferencePattern &&other) = default;
     472              :   ReferencePattern &operator= (ReferencePattern &&other) = default;
     473              : 
     474          238 :   bool is_mut () const { return mut == Mutability::Mut; }
     475              : 
     476            1 :   Mutability get_mutability () const { return mut; }
     477              : 
     478              :   void accept_vis (HIRFullVisitor &vis) override;
     479              :   void accept_vis (HIRPatternVisitor &vis) override;
     480              : 
     481         1113 :   const Analysis::NodeMapping &get_mappings () const override final
     482              :   {
     483         1113 :     return mappings;
     484              :   }
     485              : 
     486          859 :   location_t get_locus () const override final { return locus; }
     487              : 
     488           32 :   PatternType get_pattern_type () const override final
     489              :   {
     490           32 :     return PatternType::REFERENCE;
     491              :   }
     492              : 
     493          728 :   Pattern &get_referenced_pattern () { return *pattern; }
     494              : 
     495              : protected:
     496              :   /* Use covariance to implement clone function as returning this object rather
     497              :    * than base */
     498          327 :   ReferencePattern *clone_pattern_impl () const override
     499              :   {
     500          327 :     return new ReferencePattern (*this);
     501              :   }
     502              : };
     503              : 
     504              : // Base class for a single field in a struct pattern - abstract
     505          772 : class StructPatternField
     506              : {
     507              :   AST::AttrVec outer_attrs;
     508              :   location_t locus;
     509              :   Analysis::NodeMapping mappings;
     510              : 
     511              : public:
     512              :   enum ItemType
     513              :   {
     514              :     TUPLE_PAT,
     515              :     IDENT_PAT,
     516              :     IDENT
     517              :   };
     518              : 
     519              :   virtual ~StructPatternField () {}
     520              : 
     521              :   // Unique pointer custom clone function
     522          931 :   std::unique_ptr<StructPatternField> clone_struct_pattern_field () const
     523              :   {
     524          931 :     return std::unique_ptr<StructPatternField> (
     525          931 :       clone_struct_pattern_field_impl ());
     526              :   }
     527              : 
     528              :   virtual std::string to_string () const;
     529              :   virtual void accept_vis (HIRFullVisitor &vis) = 0;
     530              :   virtual ItemType get_item_type () const = 0;
     531              : 
     532          462 :   location_t get_locus () const { return locus; }
     533          466 :   Analysis::NodeMapping get_mappings () const { return mappings; };
     534          225 :   AST::AttrVec get_outer_attrs () { return outer_attrs; }
     535              : 
     536              : protected:
     537          275 :   StructPatternField (Analysis::NodeMapping mappings,
     538              :                       AST::AttrVec outer_attribs, location_t locus)
     539          275 :     : outer_attrs (std::move (outer_attribs)), locus (locus),
     540          275 :       mappings (mappings)
     541              :   {}
     542              : 
     543              :   // Clone function implementation as pure virtual method
     544              :   virtual StructPatternField *clone_struct_pattern_field_impl () const = 0;
     545              : };
     546              : 
     547              : // Tuple pattern single field in a struct pattern
     548              : class StructPatternFieldTuplePat : public StructPatternField
     549              : {
     550              :   TupleIndex index;
     551              :   std::unique_ptr<Pattern> tuple_pattern;
     552              : 
     553              : public:
     554           24 :   StructPatternFieldTuplePat (Analysis::NodeMapping mappings, TupleIndex index,
     555              :                               std::unique_ptr<Pattern> tuple_pattern,
     556              :                               AST::AttrVec outer_attribs, location_t locus)
     557           24 :     : StructPatternField (mappings, std::move (outer_attribs), locus),
     558           24 :       index (index), tuple_pattern (std::move (tuple_pattern))
     559           24 :   {}
     560              : 
     561              :   // Copy constructor requires clone
     562           59 :   StructPatternFieldTuplePat (StructPatternFieldTuplePat const &other)
     563          118 :     : StructPatternField (other), index (other.index),
     564           59 :       tuple_pattern (other.tuple_pattern->clone_pattern ())
     565           59 :   {}
     566              : 
     567              :   // Overload assignment operator to perform clone
     568              :   StructPatternFieldTuplePat &
     569              :   operator= (StructPatternFieldTuplePat const &other)
     570              :   {
     571              :     StructPatternField::operator= (other);
     572              :     tuple_pattern = other.tuple_pattern->clone_pattern ();
     573              :     index = other.index;
     574              :     // outer_attrs = other.outer_attrs;
     575              : 
     576              :     return *this;
     577              :   }
     578              : 
     579              :   // default move semantics
     580              :   StructPatternFieldTuplePat (StructPatternFieldTuplePat &&other) = default;
     581              :   StructPatternFieldTuplePat &operator= (StructPatternFieldTuplePat &&other)
     582              :     = default;
     583              : 
     584              :   std::string to_string () const override;
     585              : 
     586              :   void accept_vis (HIRFullVisitor &vis) override;
     587              : 
     588          121 :   TupleIndex get_index () { return index; }
     589           93 :   Pattern &get_tuple_pattern () { return *tuple_pattern; }
     590              : 
     591          100 :   ItemType get_item_type () const override final { return ItemType::TUPLE_PAT; }
     592              : 
     593              : protected:
     594              :   /* Use covariance to implement clone function as returning this object rather
     595              :    * than base */
     596           59 :   StructPatternFieldTuplePat *clone_struct_pattern_field_impl () const override
     597              :   {
     598           59 :     return new StructPatternFieldTuplePat (*this);
     599              :   }
     600              : };
     601              : 
     602              : // Identifier pattern single field in a struct pattern
     603              : class StructPatternFieldIdentPat : public StructPatternField
     604              : {
     605              :   Identifier ident;
     606              :   std::unique_ptr<Pattern> ident_pattern;
     607              : 
     608              : public:
     609          151 :   StructPatternFieldIdentPat (Analysis::NodeMapping mappings, Identifier ident,
     610              :                               std::unique_ptr<Pattern> ident_pattern,
     611              :                               AST::AttrVec outer_attrs, location_t locus)
     612          151 :     : StructPatternField (mappings, std::move (outer_attrs), locus),
     613          151 :       ident (std::move (ident)), ident_pattern (std::move (ident_pattern))
     614          151 :   {}
     615              : 
     616              :   // Copy constructor requires clone
     617          327 :   StructPatternFieldIdentPat (StructPatternFieldIdentPat const &other)
     618          654 :     : StructPatternField (other), ident (other.ident),
     619          327 :       ident_pattern (other.ident_pattern->clone_pattern ())
     620          327 :   {}
     621              : 
     622              :   // Overload assignment operator to clone
     623              :   StructPatternFieldIdentPat &
     624              :   operator= (StructPatternFieldIdentPat const &other)
     625              :   {
     626              :     StructPatternField::operator= (other);
     627              :     ident = other.ident;
     628              :     ident_pattern = other.ident_pattern->clone_pattern ();
     629              :     // outer_attrs = other.outer_attrs;
     630              : 
     631              :     return *this;
     632              :   }
     633              : 
     634              :   // default move semantics
     635              :   StructPatternFieldIdentPat (StructPatternFieldIdentPat &&other) = default;
     636              :   StructPatternFieldIdentPat &operator= (StructPatternFieldIdentPat &&other)
     637              :     = default;
     638              : 
     639              :   std::string to_string () const override;
     640              : 
     641              :   void accept_vis (HIRFullVisitor &vis) override;
     642              : 
     643          462 :   ItemType get_item_type () const override final { return ItemType::IDENT_PAT; }
     644              : 
     645          609 :   Identifier get_identifier () const { return ident; }
     646              : 
     647          573 :   Pattern &get_pattern () { return *ident_pattern; }
     648              : 
     649              : protected:
     650              :   /* Use covariance to implement clone function as returning this object rather
     651              :    * than base */
     652          327 :   StructPatternFieldIdentPat *clone_struct_pattern_field_impl () const override
     653              :   {
     654          327 :     return new StructPatternFieldIdentPat (*this);
     655              :   }
     656              : };
     657              : 
     658              : // Identifier only (with no pattern) single field in a struct pattern
     659              : class StructPatternFieldIdent : public StructPatternField
     660              : {
     661              :   bool has_ref;
     662              :   Mutability mut;
     663              :   Identifier ident;
     664              : 
     665              : public:
     666          100 :   StructPatternFieldIdent (Analysis::NodeMapping mappings, Identifier ident,
     667              :                            bool is_ref, Mutability mut,
     668              :                            AST::AttrVec outer_attrs, location_t locus)
     669          100 :     : StructPatternField (mappings, std::move (outer_attrs), locus),
     670          100 :       has_ref (is_ref), mut (mut), ident (std::move (ident))
     671          100 :   {}
     672              : 
     673              :   std::string to_string () const override;
     674              : 
     675            4 :   bool is_mut () const { return mut == Mutability::Mut; }
     676              : 
     677              :   void accept_vis (HIRFullVisitor &vis) override;
     678              : 
     679          359 :   ItemType get_item_type () const override final { return ItemType::IDENT; }
     680            0 :   bool get_has_ref () const { return has_ref; }
     681          369 :   Identifier get_identifier () const { return ident; };
     682              : 
     683              : protected:
     684              :   /* Use covariance to implement clone function as returning this object rather
     685              :    * than base */
     686          545 :   StructPatternFieldIdent *clone_struct_pattern_field_impl () const override
     687              :   {
     688          545 :     return new StructPatternFieldIdent (*this);
     689              :   }
     690              : };
     691              : 
     692              : // Elements of a struct pattern
     693          257 : class StructPatternElements
     694              : {
     695              :   std::vector<std::unique_ptr<StructPatternField>> fields;
     696              :   bool has_rest_pattern;
     697              : 
     698              : public:
     699              :   // Returns whether there are any struct pattern fields
     700            0 :   bool has_struct_pattern_fields () const { return !fields.empty (); }
     701              : 
     702              :   /* Returns whether the struct pattern elements is entirely empty (no fields,
     703              :    * no etc). */
     704            0 :   bool is_empty () const { return !has_struct_pattern_fields (); }
     705              : 
     706          156 :   bool has_rest () const { return has_rest_pattern; }
     707              : 
     708              :   // Constructor for StructPatternElements with both (potentially)
     709              :   StructPatternElements (
     710              :     std::vector<std::unique_ptr<StructPatternField>> fields)
     711              :     : fields (std::move (fields)), has_rest_pattern (false)
     712              :   {}
     713              : 
     714          165 :   StructPatternElements (
     715              :     std::vector<std::unique_ptr<StructPatternField>> fields,
     716              :     bool has_rest_pattern)
     717          165 :     : fields (std::move (fields)), has_rest_pattern (has_rest_pattern)
     718              :   {}
     719              : 
     720              :   // Copy constructor with vector clone
     721          536 :   StructPatternElements (StructPatternElements const &other)
     722          536 :   {
     723          536 :     fields.reserve (other.fields.size ());
     724         1467 :     for (const auto &e : other.fields)
     725          931 :       fields.emplace_back (e->clone_struct_pattern_field ());
     726          536 :     has_rest_pattern = other.has_rest_pattern;
     727          536 :   }
     728              : 
     729              :   // Overloaded assignment operator with vector clone
     730              :   StructPatternElements &operator= (StructPatternElements const &other)
     731              :   {
     732              :     fields.clear ();
     733              :     fields.reserve (other.fields.size ());
     734              :     for (const auto &e : other.fields)
     735              :       fields.emplace_back (e->clone_struct_pattern_field ());
     736              :     has_rest_pattern = other.has_rest_pattern;
     737              :     return *this;
     738              :   }
     739              : 
     740              :   // move constructors
     741          165 :   StructPatternElements (StructPatternElements &&other) = default;
     742              :   StructPatternElements &operator= (StructPatternElements &&other) = default;
     743              : 
     744              :   // Creates an empty StructPatternElements
     745              :   static StructPatternElements create_empty ()
     746              :   {
     747              :     return StructPatternElements (
     748              :       std::vector<std::unique_ptr<StructPatternField>> ());
     749              :   }
     750              : 
     751              :   std::string to_string () const;
     752              : 
     753            3 :   std::vector<std::unique_ptr<StructPatternField>> &get_struct_pattern_fields ()
     754              :   {
     755          590 :     return fields;
     756              :   }
     757              : };
     758              : 
     759              : // Struct pattern HIR node representation
     760              : class StructPattern : public Pattern
     761              : {
     762              :   PathInExpression path;
     763              :   StructPatternElements elems;
     764              :   Analysis::NodeMapping mappings;
     765              : 
     766              : public:
     767              :   std::string to_string () const override;
     768              : 
     769          165 :   StructPattern (Analysis::NodeMapping mappings, PathInExpression struct_path,
     770              :                  StructPatternElements elems)
     771          330 :     : path (std::move (struct_path)), elems (std::move (elems)),
     772          165 :       mappings (mappings)
     773          165 :   {}
     774              : 
     775            0 :   bool has_struct_pattern_elems () const { return !elems.is_empty (); }
     776              : 
     777          461 :   location_t get_locus () const override { return path.get_locus (); }
     778              : 
     779              :   void accept_vis (HIRFullVisitor &vis) override;
     780              :   void accept_vis (HIRPatternVisitor &vis) override;
     781              : 
     782          135 :   PathInExpression &get_path () { return path; }
     783          684 :   StructPatternElements &get_struct_pattern_elems () { return elems; }
     784              : 
     785          659 :   const Analysis::NodeMapping &get_mappings () const override final
     786              :   {
     787          659 :     return mappings;
     788              :   }
     789              : 
     790           92 :   PatternType get_pattern_type () const override final
     791              :   {
     792           92 :     return PatternType::STRUCT;
     793              :   }
     794              : 
     795              : protected:
     796              :   /* Use covariance to implement clone function as returning this object rather
     797              :    * than base */
     798          444 :   StructPattern *clone_pattern_impl () const override
     799              :   {
     800          444 :     return new StructPattern (*this);
     801              :   }
     802              : };
     803              : 
     804              : // Base abstract class for TupleStructItems, TuplePatternItems &
     805              : // SlicePatternItems
     806         3659 : class PatternItems : public FullVisitable
     807              : {
     808              : public:
     809              :   enum ItemType
     810              :   {
     811              :     NO_REST,
     812              :     HAS_REST,
     813              :   };
     814              : 
     815              :   virtual ~PatternItems () {}
     816              : 
     817              :   // TODO: should this store location data?
     818              : 
     819              :   // Unique pointer custom clone function
     820              :   std::unique_ptr<PatternItems> clone_pattern_items () const
     821              :   {
     822              :     return std::unique_ptr<PatternItems> (clone_pattern_items_impl ());
     823              :   }
     824              : 
     825              :   virtual ItemType get_item_type () const = 0;
     826              : 
     827              :   virtual std::string to_string () const = 0;
     828              : 
     829              : protected:
     830              :   // pure virtual clone implementation
     831              :   virtual PatternItems *clone_pattern_items_impl () const = 0;
     832              : };
     833              : 
     834              : // Base abstract class for patterns used in TupleStructPattern
     835         2724 : class TupleStructItems : public PatternItems
     836              : {
     837              : public:
     838              :   // Unique pointer custom clone function
     839         1718 :   std::unique_ptr<TupleStructItems> clone_tuple_struct_items () const
     840              :   {
     841         1718 :     return std::unique_ptr<TupleStructItems> (clone_pattern_items_impl ());
     842              :   }
     843              : 
     844              : protected:
     845              :   // pure virtual clone implementation
     846              :   virtual TupleStructItems *clone_pattern_items_impl () const override = 0;
     847              : };
     848              : 
     849              : // Class for patterns within a tuple struct pattern, without a rest pattern
     850              : class TupleStructItemsNoRest : public TupleStructItems
     851              : {
     852              :   std::vector<std::unique_ptr<Pattern>> patterns;
     853              : 
     854              : public:
     855          967 :   TupleStructItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
     856          967 :     : patterns (std::move (patterns))
     857              :   {}
     858              : 
     859              :   // Copy constructor with vector clone
     860         1643 :   TupleStructItemsNoRest (TupleStructItemsNoRest const &other)
     861         1643 :   {
     862         1643 :     patterns.reserve (other.patterns.size ());
     863         3439 :     for (const auto &e : other.patterns)
     864         1796 :       patterns.push_back (e->clone_pattern ());
     865         1643 :   }
     866              : 
     867              :   // Overloaded assignment operator with vector clone
     868              :   TupleStructItemsNoRest &operator= (TupleStructItemsNoRest const &other)
     869              :   {
     870              :     patterns.clear ();
     871              :     patterns.reserve (other.patterns.size ());
     872              :     for (const auto &e : other.patterns)
     873              :       patterns.push_back (e->clone_pattern ());
     874              : 
     875              :     return *this;
     876              :   }
     877              : 
     878              :   // move constructors
     879              :   TupleStructItemsNoRest (TupleStructItemsNoRest &&other) = default;
     880              :   TupleStructItemsNoRest &operator= (TupleStructItemsNoRest &&other) = default;
     881              : 
     882              :   std::string to_string () const override;
     883              : 
     884              :   void accept_vis (HIRFullVisitor &vis) override;
     885              : 
     886         4966 :   std::vector<std::unique_ptr<Pattern>> &get_patterns () { return patterns; }
     887              :   const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
     888              :   {
     889              :     return patterns;
     890              :   }
     891              : 
     892         3140 :   ItemType get_item_type () const override final { return ItemType::NO_REST; }
     893              : 
     894              : protected:
     895              :   /* Use covariance to implement clone function as returning this object rather
     896              :    * than base */
     897         1643 :   TupleStructItemsNoRest *clone_pattern_items_impl () const override
     898              :   {
     899         1643 :     return new TupleStructItemsNoRest (*this);
     900              :   }
     901              : };
     902              : 
     903              : // Class for patterns within a tuple struct pattern, with a rest pattern
     904              : // included
     905              : class TupleStructItemsHasRest : public TupleStructItems
     906              : {
     907              :   std::vector<std::unique_ptr<Pattern>> lower_patterns;
     908              :   std::vector<std::unique_ptr<Pattern>> upper_patterns;
     909              : 
     910              : public:
     911           39 :   TupleStructItemsHasRest (std::vector<std::unique_ptr<Pattern>> lower_patterns,
     912              :                            std::vector<std::unique_ptr<Pattern>> upper_patterns)
     913           39 :     : lower_patterns (std::move (lower_patterns)),
     914           39 :       upper_patterns (std::move (upper_patterns))
     915              :   {}
     916              : 
     917              :   // Copy constructor with vector clone
     918           75 :   TupleStructItemsHasRest (TupleStructItemsHasRest const &other)
     919           75 :   {
     920           75 :     lower_patterns.reserve (other.lower_patterns.size ());
     921          135 :     for (const auto &e : other.lower_patterns)
     922           60 :       lower_patterns.push_back (e->clone_pattern ());
     923              : 
     924           75 :     upper_patterns.reserve (other.upper_patterns.size ());
     925          108 :     for (const auto &e : other.upper_patterns)
     926           33 :       upper_patterns.push_back (e->clone_pattern ());
     927           75 :   }
     928              : 
     929              :   // Overloaded assignment operator to clone
     930              :   TupleStructItemsHasRest &operator= (TupleStructItemsHasRest const &other)
     931              :   {
     932              :     lower_patterns.clear ();
     933              :     lower_patterns.reserve (other.lower_patterns.size ());
     934              :     for (const auto &e : other.lower_patterns)
     935              :       lower_patterns.push_back (e->clone_pattern ());
     936              : 
     937              :     upper_patterns.clear ();
     938              :     upper_patterns.reserve (other.upper_patterns.size ());
     939              :     for (const auto &e : other.upper_patterns)
     940              :       upper_patterns.push_back (e->clone_pattern ());
     941              : 
     942              :     return *this;
     943              :   }
     944              : 
     945              :   // move constructors
     946              :   TupleStructItemsHasRest (TupleStructItemsHasRest &&other) = default;
     947              :   TupleStructItemsHasRest &operator= (TupleStructItemsHasRest &&other)
     948              :     = default;
     949              : 
     950              :   std::string to_string () const override;
     951              : 
     952              :   void accept_vis (HIRFullVisitor &vis) override;
     953              : 
     954            0 :   std::vector<std::unique_ptr<Pattern>> &get_lower_patterns ()
     955              :   {
     956          182 :     return lower_patterns;
     957              :   }
     958              :   const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const
     959              :   {
     960              :     return lower_patterns;
     961              :   }
     962              : 
     963              :   // TODO: seems kinda dodgy. Think of better way.
     964            0 :   std::vector<std::unique_ptr<Pattern>> &get_upper_patterns ()
     965              :   {
     966          146 :     return upper_patterns;
     967              :   }
     968              :   const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const
     969              :   {
     970              :     return upper_patterns;
     971              :   }
     972              : 
     973          146 :   ItemType get_item_type () const override final { return ItemType::HAS_REST; }
     974              : 
     975              : protected:
     976              :   /* Use covariance to implement clone function as returning this object rather
     977              :    * than base */
     978           75 :   TupleStructItemsHasRest *clone_pattern_items_impl () const override
     979              :   {
     980           75 :     return new TupleStructItemsHasRest (*this);
     981              :   }
     982              : };
     983              : 
     984              : // HIR node representing a tuple struct pattern
     985              : class TupleStructPattern : public Pattern
     986              : {
     987              :   PathInExpression path;
     988              :   std::unique_ptr<TupleStructItems> items;
     989              :   Analysis::NodeMapping mappings;
     990              : 
     991              :   /* TOOD: should this store location data? current accessor uses path location
     992              :    * data */
     993              : 
     994              : public:
     995              :   std::string to_string () const override;
     996              : 
     997         1006 :   TupleStructPattern (Analysis::NodeMapping mappings,
     998              :                       PathInExpression tuple_struct_path,
     999              :                       std::unique_ptr<TupleStructItems> items)
    1000         2012 :     : path (std::move (tuple_struct_path)), items (std::move (items)),
    1001         1006 :       mappings (mappings)
    1002         1006 :   {}
    1003              : 
    1004              :   // Copy constructor required to clone
    1005         1718 :   TupleStructPattern (TupleStructPattern const &other)
    1006         1718 :     : path (other.path), items (other.items->clone_tuple_struct_items ()),
    1007         1718 :       mappings (other.mappings)
    1008         1718 :   {}
    1009              : 
    1010              :   // Operator overload assignment operator to clone
    1011              :   TupleStructPattern &operator= (TupleStructPattern const &other)
    1012              :   {
    1013              :     path = other.path;
    1014              :     items = other.items->clone_tuple_struct_items ();
    1015              :     mappings = other.mappings;
    1016              : 
    1017              :     return *this;
    1018              :   }
    1019              : 
    1020              :   // move constructors
    1021              :   TupleStructPattern (TupleStructPattern &&other) = default;
    1022              :   TupleStructPattern &operator= (TupleStructPattern &&other) = default;
    1023              : 
    1024         2344 :   location_t get_locus () const override { return path.get_locus (); }
    1025              : 
    1026              :   void accept_vis (HIRFullVisitor &vis) override;
    1027              :   void accept_vis (HIRPatternVisitor &vis) override;
    1028              : 
    1029          914 :   PathInExpression &get_path () { return path; }
    1030              : 
    1031         4200 :   TupleStructItems &get_items () { return *items; }
    1032              : 
    1033         4029 :   const Analysis::NodeMapping &get_mappings () const override final
    1034              :   {
    1035         4029 :     return mappings;
    1036              :   }
    1037              : 
    1038          821 :   PatternType get_pattern_type () const override final
    1039              :   {
    1040          821 :     return PatternType::TUPLE_STRUCT;
    1041              :   }
    1042              : 
    1043              : protected:
    1044              :   /* Use covariance to implement clone function as returning this object rather
    1045              :    * than base */
    1046         1718 :   TupleStructPattern *clone_pattern_impl () const override
    1047              :   {
    1048         1718 :     return new TupleStructPattern (*this);
    1049              :   }
    1050              : };
    1051              : 
    1052              : // Base abstract class representing TuplePattern patterns
    1053          710 : class TuplePatternItems : public PatternItems
    1054              : {
    1055              : public:
    1056              :   // Unique pointer custom clone function
    1057          286 :   std::unique_ptr<TuplePatternItems> clone_tuple_pattern_items () const
    1058              :   {
    1059          286 :     return std::unique_ptr<TuplePatternItems> (clone_pattern_items_impl ());
    1060              :   }
    1061              : 
    1062              : protected:
    1063              :   // pure virtual clone implementation
    1064              :   virtual TuplePatternItems *clone_pattern_items_impl () const override = 0;
    1065              : };
    1066              : 
    1067              : // Class representing patterns within a TuplePattern, without a rest pattern
    1068              : class TuplePatternItemsNoRest : public TuplePatternItems
    1069              : {
    1070              :   std::vector<std::unique_ptr<Pattern>> patterns;
    1071              : 
    1072              : public:
    1073          397 :   TuplePatternItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
    1074          397 :     : patterns (std::move (patterns))
    1075              :   {}
    1076              : 
    1077              :   // Copy constructor with vector clone
    1078          240 :   TuplePatternItemsNoRest (TuplePatternItemsNoRest const &other)
    1079          240 :   {
    1080          240 :     patterns.reserve (other.patterns.size ());
    1081          732 :     for (const auto &e : other.patterns)
    1082          492 :       patterns.push_back (e->clone_pattern ());
    1083          240 :   }
    1084              : 
    1085              :   // Overloaded assignment operator to vector clone
    1086              :   TuplePatternItemsNoRest &operator= (TuplePatternItemsNoRest const &other)
    1087              :   {
    1088              :     patterns.clear ();
    1089              :     patterns.reserve (other.patterns.size ());
    1090              :     for (const auto &e : other.patterns)
    1091              :       patterns.push_back (e->clone_pattern ());
    1092              : 
    1093              :     return *this;
    1094              :   }
    1095              : 
    1096              :   // move constructors
    1097              :   TuplePatternItemsNoRest (TuplePatternItemsNoRest &&other) = default;
    1098              :   TuplePatternItemsNoRest &operator= (TuplePatternItemsNoRest &&other)
    1099              :     = default;
    1100              : 
    1101              :   std::string to_string () const override;
    1102              : 
    1103              :   void accept_vis (HIRFullVisitor &vis) override;
    1104              : 
    1105         1736 :   ItemType get_item_type () const override { return ItemType::NO_REST; }
    1106              : 
    1107         1836 :   std::vector<std::unique_ptr<Pattern>> &get_patterns () { return patterns; }
    1108              :   const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
    1109              :   {
    1110              :     return patterns;
    1111              :   }
    1112              : 
    1113              : protected:
    1114              :   /* Use covariance to implement clone function as returning this object rather
    1115              :    * than base */
    1116          240 :   TuplePatternItemsNoRest *clone_pattern_items_impl () const override
    1117              :   {
    1118          240 :     return new TuplePatternItemsNoRest (*this);
    1119              :   }
    1120              : };
    1121              : 
    1122              : // Class representing patterns within a TuplePattern, with a rest pattern
    1123              : // included
    1124              : class TuplePatternItemsHasRest : public TuplePatternItems
    1125              : {
    1126              :   std::vector<std::unique_ptr<Pattern>> lower_patterns;
    1127              :   std::vector<std::unique_ptr<Pattern>> upper_patterns;
    1128              : 
    1129              : public:
    1130           27 :   TuplePatternItemsHasRest (
    1131              :     std::vector<std::unique_ptr<Pattern>> lower_patterns,
    1132              :     std::vector<std::unique_ptr<Pattern>> upper_patterns)
    1133           27 :     : lower_patterns (std::move (lower_patterns)),
    1134           27 :       upper_patterns (std::move (upper_patterns))
    1135              :   {}
    1136              : 
    1137              :   // Copy constructor with vector clone
    1138           46 :   TuplePatternItemsHasRest (TuplePatternItemsHasRest const &other)
    1139           46 :   {
    1140           46 :     lower_patterns.reserve (other.lower_patterns.size ());
    1141           93 :     for (const auto &e : other.lower_patterns)
    1142           47 :       lower_patterns.push_back (e->clone_pattern ());
    1143              : 
    1144           46 :     upper_patterns.reserve (other.upper_patterns.size ());
    1145           97 :     for (const auto &e : other.upper_patterns)
    1146           51 :       upper_patterns.push_back (e->clone_pattern ());
    1147           46 :   }
    1148              : 
    1149              :   // Overloaded assignment operator to clone
    1150              :   TuplePatternItemsHasRest &operator= (TuplePatternItemsHasRest const &other)
    1151              :   {
    1152              :     lower_patterns.clear ();
    1153              :     lower_patterns.reserve (other.lower_patterns.size ());
    1154              :     for (const auto &e : other.lower_patterns)
    1155              :       lower_patterns.push_back (e->clone_pattern ());
    1156              : 
    1157              :     lower_patterns.clear ();
    1158              :     upper_patterns.reserve (other.upper_patterns.size ());
    1159              :     for (const auto &e : other.upper_patterns)
    1160              :       upper_patterns.push_back (e->clone_pattern ());
    1161              : 
    1162              :     return *this;
    1163              :   }
    1164              : 
    1165              :   // move constructors
    1166              :   TuplePatternItemsHasRest (TuplePatternItemsHasRest &&other) = default;
    1167              :   TuplePatternItemsHasRest &operator= (TuplePatternItemsHasRest &&other)
    1168              :     = default;
    1169              : 
    1170              :   std::string to_string () const override;
    1171              : 
    1172              :   void accept_vis (HIRFullVisitor &vis) override;
    1173              : 
    1174           79 :   ItemType get_item_type () const override { return ItemType::HAS_REST; }
    1175              : 
    1176            2 :   std::vector<std::unique_ptr<Pattern>> &get_lower_patterns ()
    1177              :   {
    1178          101 :     return lower_patterns;
    1179              :   }
    1180              :   const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const
    1181              :   {
    1182              :     return lower_patterns;
    1183              :   }
    1184              : 
    1185            2 :   std::vector<std::unique_ptr<Pattern>> &get_upper_patterns ()
    1186              :   {
    1187          101 :     return upper_patterns;
    1188              :   }
    1189              :   const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const
    1190              :   {
    1191              :     return upper_patterns;
    1192              :   }
    1193              : 
    1194              : protected:
    1195              :   /* Use covariance to implement clone function as returning this object rather
    1196              :    * than base */
    1197           46 :   TuplePatternItemsHasRest *clone_pattern_items_impl () const override
    1198              :   {
    1199           46 :     return new TuplePatternItemsHasRest (*this);
    1200              :   }
    1201              : };
    1202              : 
    1203              : // HIR node representing a tuple pattern
    1204              : class TuplePattern : public Pattern
    1205              : {
    1206              :   std::unique_ptr<TuplePatternItems> items;
    1207              :   location_t locus;
    1208              :   Analysis::NodeMapping mappings;
    1209              : 
    1210              : public:
    1211              :   std::string to_string () const override;
    1212              : 
    1213              :   // Returns true if the tuple pattern has items
    1214          411 :   bool has_tuple_pattern_items () const { return items != nullptr; }
    1215              : 
    1216          424 :   TuplePattern (Analysis::NodeMapping mappings,
    1217              :                 std::unique_ptr<TuplePatternItems> items, location_t locus)
    1218          424 :     : items (std::move (items)), locus (locus), mappings (mappings)
    1219              :   {}
    1220              : 
    1221              :   // Copy constructor requires clone
    1222          286 :   TuplePattern (TuplePattern const &other)
    1223          572 :     : items (other.items->clone_tuple_pattern_items ()), locus (other.locus),
    1224          286 :       mappings (other.mappings)
    1225          286 :   {}
    1226              : 
    1227              :   // Overload assignment operator to clone
    1228              :   TuplePattern &operator= (TuplePattern const &other)
    1229              :   {
    1230              :     items = other.items->clone_tuple_pattern_items ();
    1231              :     locus = other.locus;
    1232              :     mappings = other.mappings;
    1233              : 
    1234              :     return *this;
    1235              :   }
    1236              : 
    1237         1656 :   location_t get_locus () const override { return locus; }
    1238              : 
    1239              :   void accept_vis (HIRFullVisitor &vis) override;
    1240              :   void accept_vis (HIRPatternVisitor &vis) override;
    1241              : 
    1242         2834 :   const Analysis::NodeMapping &get_mappings () const override final
    1243              :   {
    1244         2834 :     return mappings;
    1245              :   }
    1246              : 
    1247          404 :   PatternType get_pattern_type () const override final
    1248              :   {
    1249          404 :     return PatternType::TUPLE;
    1250              :   }
    1251              : 
    1252         3752 :   TuplePatternItems &get_items () { return *items; }
    1253              :   const TuplePatternItems &get_items () const { return *items; }
    1254              : 
    1255              : protected:
    1256              :   /* Use covariance to implement clone function as returning this object rather
    1257              :    * than base */
    1258          286 :   TuplePattern *clone_pattern_impl () const override
    1259              :   {
    1260          286 :     return new TuplePattern (*this);
    1261              :   }
    1262              : };
    1263              : 
    1264              : // Base abstract class representing SlicePattern patterns
    1265          225 : class SlicePatternItems : public PatternItems
    1266              : {
    1267              : public:
    1268              :   // Unique pointer custom clone function
    1269          149 :   std::unique_ptr<SlicePatternItems> clone_slice_pattern_items () const
    1270              :   {
    1271          149 :     return std::unique_ptr<SlicePatternItems> (clone_pattern_items_impl ());
    1272              :   }
    1273              : 
    1274              : protected:
    1275              :   // pure virtual clone implementation
    1276              :   virtual SlicePatternItems *clone_pattern_items_impl () const override = 0;
    1277              : };
    1278              : 
    1279              : // Class representing patterns within a SlicePattern, without a rest pattern
    1280              : class SlicePatternItemsNoRest : public SlicePatternItems
    1281              : {
    1282              :   std::vector<std::unique_ptr<Pattern>> patterns;
    1283              : 
    1284              : public:
    1285           32 :   SlicePatternItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
    1286           32 :     : patterns (std::move (patterns))
    1287              :   {}
    1288              : 
    1289              :   // Copy constructor with vector clone
    1290           63 :   SlicePatternItemsNoRest (SlicePatternItemsNoRest const &other)
    1291           63 :   {
    1292           63 :     patterns.reserve (other.patterns.size ());
    1293          188 :     for (const auto &e : other.patterns)
    1294          125 :       patterns.push_back (e->clone_pattern ());
    1295           63 :   }
    1296              : 
    1297              :   // Overloaded assignment operator to vector clone
    1298              :   SlicePatternItemsNoRest &operator= (SlicePatternItemsNoRest const &other)
    1299              :   {
    1300              :     patterns.clear ();
    1301              :     patterns.reserve (other.patterns.size ());
    1302              :     for (const auto &e : other.patterns)
    1303              :       patterns.push_back (e->clone_pattern ());
    1304              : 
    1305              :     return *this;
    1306              :   }
    1307              : 
    1308              :   // move constructors
    1309              :   SlicePatternItemsNoRest (SlicePatternItemsNoRest &&other) = default;
    1310              :   SlicePatternItemsNoRest &operator= (SlicePatternItemsNoRest &&other)
    1311              :     = default;
    1312              : 
    1313              :   std::string to_string () const override;
    1314              : 
    1315              :   void accept_vis (HIRFullVisitor &vis) override;
    1316              : 
    1317          126 :   ItemType get_item_type () const override { return ItemType::NO_REST; }
    1318              : 
    1319          125 :   std::vector<std::unique_ptr<Pattern>> &get_patterns () { return patterns; }
    1320              :   const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
    1321              :   {
    1322              :     return patterns;
    1323              :   }
    1324              : 
    1325              : protected:
    1326              :   /* Use covariance to implement clone function as returning this object rather
    1327              :    * than base */
    1328           63 :   SlicePatternItemsNoRest *clone_pattern_items_impl () const override
    1329              :   {
    1330           63 :     return new SlicePatternItemsNoRest (*this);
    1331              :   }
    1332              : };
    1333              : 
    1334              : // Class representing patterns within a SlicePattern, with a rest pattern
    1335              : // included
    1336              : class SlicePatternItemsHasRest : public SlicePatternItems
    1337              : {
    1338              :   std::vector<std::unique_ptr<Pattern>> lower_patterns;
    1339              :   std::vector<std::unique_ptr<Pattern>> upper_patterns;
    1340              : 
    1341              : public:
    1342           44 :   SlicePatternItemsHasRest (
    1343              :     std::vector<std::unique_ptr<Pattern>> lower_patterns,
    1344              :     std::vector<std::unique_ptr<Pattern>> upper_patterns)
    1345           44 :     : lower_patterns (std::move (lower_patterns)),
    1346           44 :       upper_patterns (std::move (upper_patterns))
    1347              :   {}
    1348              : 
    1349              :   // Copy constructor with vector clone
    1350           86 :   SlicePatternItemsHasRest (SlicePatternItemsHasRest const &other)
    1351           86 :   {
    1352           86 :     lower_patterns.reserve (other.lower_patterns.size ());
    1353          171 :     for (const auto &e : other.lower_patterns)
    1354           85 :       lower_patterns.push_back (e->clone_pattern ());
    1355              : 
    1356           86 :     upper_patterns.reserve (other.upper_patterns.size ());
    1357          171 :     for (const auto &e : other.upper_patterns)
    1358           85 :       upper_patterns.push_back (e->clone_pattern ());
    1359           86 :   }
    1360              : 
    1361              :   // Overloaded assignment operator to clone
    1362              :   SlicePatternItemsHasRest &operator= (SlicePatternItemsHasRest const &other)
    1363              :   {
    1364              :     lower_patterns.clear ();
    1365              :     lower_patterns.reserve (other.lower_patterns.size ());
    1366              :     for (const auto &e : other.lower_patterns)
    1367              :       lower_patterns.push_back (e->clone_pattern ());
    1368              : 
    1369              :     lower_patterns.clear ();
    1370              :     upper_patterns.reserve (other.upper_patterns.size ());
    1371              :     for (const auto &e : other.upper_patterns)
    1372              :       upper_patterns.push_back (e->clone_pattern ());
    1373              : 
    1374              :     return *this;
    1375              :   }
    1376              : 
    1377              :   // move constructors
    1378              :   SlicePatternItemsHasRest (SlicePatternItemsHasRest &&other) = default;
    1379              :   SlicePatternItemsHasRest &operator= (SlicePatternItemsHasRest &&other)
    1380              :     = default;
    1381              : 
    1382              :   std::string to_string () const override;
    1383              : 
    1384              :   void accept_vis (HIRFullVisitor &vis) override;
    1385              : 
    1386          176 :   ItemType get_item_type () const override { return ItemType::HAS_REST; }
    1387              : 
    1388            0 :   std::vector<std::unique_ptr<Pattern>> &get_lower_patterns ()
    1389              :   {
    1390          176 :     return lower_patterns;
    1391              :   }
    1392              :   const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const
    1393              :   {
    1394              :     return lower_patterns;
    1395              :   }
    1396              : 
    1397            0 :   std::vector<std::unique_ptr<Pattern>> &get_upper_patterns ()
    1398              :   {
    1399          176 :     return upper_patterns;
    1400              :   }
    1401              :   const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const
    1402              :   {
    1403              :     return upper_patterns;
    1404              :   }
    1405              : 
    1406              : protected:
    1407              :   /* Use covariance to implement clone function as returning this object rather
    1408              :    * than base */
    1409           86 :   SlicePatternItemsHasRest *clone_pattern_items_impl () const override
    1410              :   {
    1411           86 :     return new SlicePatternItemsHasRest (*this);
    1412              :   }
    1413              : };
    1414              : 
    1415              : // HIR node representing patterns that can match slices and arrays
    1416              : class SlicePattern : public Pattern
    1417              : {
    1418              :   std::unique_ptr<SlicePatternItems> items;
    1419              :   location_t locus;
    1420              :   Analysis::NodeMapping mappings;
    1421              : 
    1422              : public:
    1423              :   std::string to_string () const override;
    1424              : 
    1425           76 :   SlicePattern (Analysis::NodeMapping mappings,
    1426              :                 std::unique_ptr<SlicePatternItems> items, location_t locus)
    1427           76 :     : items (std::move (items)), locus (locus), mappings (mappings)
    1428              :   {}
    1429              : 
    1430              :   // Copy constructor requires clone
    1431          149 :   SlicePattern (SlicePattern const &other)
    1432          298 :     : items (other.items->clone_slice_pattern_items ()), locus (other.locus),
    1433          149 :       mappings (other.mappings)
    1434          149 :   {}
    1435              : 
    1436              :   // Overloaded assignment operator to vector clone
    1437              :   SlicePattern &operator= (SlicePattern const &other)
    1438              :   {
    1439              :     items = other.items->clone_slice_pattern_items ();
    1440              :     locus = other.locus;
    1441              :     mappings = other.mappings;
    1442              : 
    1443              :     return *this;
    1444              :   }
    1445              : 
    1446              :   // move constructors
    1447              :   SlicePattern (SlicePattern &&other) = default;
    1448              :   SlicePattern &operator= (SlicePattern &&other) = default;
    1449              : 
    1450          679 :   SlicePatternItems &get_items () { return *items; }
    1451              :   const SlicePatternItems &get_items () const { return *items; }
    1452              : 
    1453          882 :   location_t get_locus () const override { return locus; }
    1454              : 
    1455              :   void accept_vis (HIRFullVisitor &vis) override;
    1456              :   void accept_vis (HIRPatternVisitor &vis) override;
    1457              : 
    1458          530 :   const Analysis::NodeMapping &get_mappings () const override final
    1459              :   {
    1460          530 :     return mappings;
    1461              :   }
    1462              : 
    1463           75 :   PatternType get_pattern_type () const override final
    1464              :   {
    1465           75 :     return PatternType::SLICE;
    1466              :   }
    1467              : 
    1468              : protected:
    1469              :   /* Use covariance to implement clone function as returning this object rather
    1470              :    * than base */
    1471          149 :   SlicePattern *clone_pattern_impl () const override
    1472              :   {
    1473          149 :     return new SlicePattern (*this);
    1474              :   }
    1475              : };
    1476              : 
    1477              : // HIR node for alternative patterns
    1478              : class AltPattern : public Pattern
    1479              : {
    1480              :   std::vector<std::unique_ptr<Pattern>> alts;
    1481              :   location_t locus;
    1482              :   Analysis::NodeMapping mappings;
    1483              : 
    1484              : public:
    1485              :   std::string to_string () const override;
    1486              : 
    1487          147 :   AltPattern (Analysis::NodeMapping mappings,
    1488              :               std::vector<std::unique_ptr<Pattern>> alts, location_t locus)
    1489          147 :     : alts (std::move (alts)), locus (locus), mappings (mappings)
    1490          147 :   {}
    1491              : 
    1492              :   // Copy constructor with vector clone
    1493          146 :   AltPattern (AltPattern const &other)
    1494          146 :     : locus (other.locus), mappings (other.mappings)
    1495              :   {
    1496          146 :     alts.reserve (other.alts.size ());
    1497          440 :     for (const auto &e : other.alts)
    1498          294 :       alts.push_back (e->clone_pattern ());
    1499          146 :   }
    1500              : 
    1501              :   // Overloaded assignment operator to vector clone
    1502              :   AltPattern &operator= (AltPattern const &other)
    1503              :   {
    1504              :     locus = other.locus;
    1505              :     mappings = other.mappings;
    1506              : 
    1507              :     alts.clear ();
    1508              :     alts.reserve (other.alts.size ());
    1509              :     for (const auto &e : other.alts)
    1510              :       alts.push_back (e->clone_pattern ());
    1511              : 
    1512              :     return *this;
    1513              :   }
    1514              : 
    1515              :   // move constructors
    1516              :   AltPattern (AltPattern &&other) = default;
    1517              :   AltPattern &operator= (AltPattern &&other) = default;
    1518              : 
    1519          333 :   std::vector<std::unique_ptr<Pattern>> &get_alts () { return alts; }
    1520              :   const std::vector<std::unique_ptr<Pattern>> &get_alts () const
    1521              :   {
    1522              :     return alts;
    1523              :   }
    1524              : 
    1525          823 :   location_t get_locus () const override { return locus; }
    1526              : 
    1527              :   void accept_vis (HIRFullVisitor &vis) override;
    1528              :   void accept_vis (HIRPatternVisitor &vis) override;
    1529              : 
    1530          991 :   const Analysis::NodeMapping &get_mappings () const override final
    1531              :   {
    1532          991 :     return mappings;
    1533              :   }
    1534              : 
    1535          145 :   PatternType get_pattern_type () const override final
    1536              :   {
    1537          145 :     return PatternType::ALT;
    1538              :   }
    1539              : 
    1540              : protected:
    1541              :   /* Use covariance to implement clone function as returning this object rather
    1542              :    * than base */
    1543          146 :   AltPattern *clone_pattern_impl () const override
    1544              :   {
    1545          146 :     return new AltPattern (*this);
    1546              :   }
    1547              : };
    1548              : 
    1549              : // Moved definition to rust-path.h
    1550              : class PathPattern;
    1551              : 
    1552              : // Forward decls for paths (defined in rust-path.h)
    1553              : class PathInExpression;
    1554              : class QualifiedPathInExpression;
    1555              : 
    1556              : } // namespace HIR
    1557              : } // namespace Rust
    1558              : 
    1559              : #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.