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