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 % 403 351
Test Date: 2026-08-22 16:33:35 Functions: 90.2 % 102 92
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          457 :   LiteralPattern (Analysis::NodeMapping mappings, Literal lit, location_t locus,
      50              :                   bool has_minus)
      51          457 :     : lit (std::move (lit)), locus (locus), mappings (mappings),
      52          457 :       has_minus (has_minus)
      53          457 :   {}
      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         2635 :   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         2813 :   const Analysis::NodeMapping &get_mappings () const override final
      67              :   {
      68         2813 :     return mappings;
      69              :   }
      70              : 
      71          207 :   PatternType get_pattern_type () const override final
      72              :   {
      73          207 :     return PatternType::LITERAL;
      74              :   }
      75              : 
      76          850 :   Literal &get_literal () { return lit; }
      77              :   const Literal &get_literal () const { return lit; }
      78              : 
      79          406 :   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         1436 :   virtual LiteralPattern *clone_pattern_impl () const override
      85              :   {
      86         1436 :     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       235145 :   bool has_subpattern () const { return subpattern != nullptr; }
     113              : 
     114              :   // Constructor
     115        54541 :   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        54541 :     : variable_ident (std::move (ident)), is_ref (is_ref), mut (mut),
     120        54541 :       subpattern (std::move (subpattern)), locus (locus), mappings (mappings)
     121        54541 :   {}
     122              : 
     123              :   // Copy constructor with clone
     124        47472 :   IdentifierPattern (IdentifierPattern const &other)
     125        47472 :     : variable_ident (other.variable_ident), is_ref (other.is_ref),
     126        47472 :       mut (other.mut), locus (other.locus), mappings (other.mappings)
     127              :   {
     128              :     // fix to get prevent null pointer dereference
     129        47472 :     if (other.subpattern != nullptr)
     130           21 :       subpattern = other.subpattern->clone_pattern ();
     131        47472 :   }
     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        32750 :   IdentifierPattern (IdentifierPattern &&other) = default;
     151              :   IdentifierPattern &operator= (IdentifierPattern &&other) = default;
     152              : 
     153        44160 :   location_t get_locus () const override { return locus; }
     154              : 
     155       167286 :   bool is_mut () const { return mut == Mutability::Mut; }
     156        63777 :   bool get_is_ref () const { return is_ref; }
     157           70 :   Pattern &get_subpattern () { return *subpattern; }
     158              : 
     159              :   void accept_vis (HIRFullVisitor &vis) override;
     160              :   void accept_vis (HIRPatternVisitor &vis) override;
     161              : 
     162       187213 :   const Analysis::NodeMapping &get_mappings () const override final
     163              :   {
     164       187213 :     return mappings;
     165              :   }
     166              : 
     167        22745 :   Identifier get_identifier () const { return variable_ident; }
     168              : 
     169        15906 :   PatternType get_pattern_type () const override final
     170              :   {
     171        15906 :     return PatternType::IDENTIFIER;
     172              :   }
     173              : 
     174              : protected:
     175              :   /* Use covariance to implement clone function as returning this object rather
     176              :    * than base */
     177        47472 :   IdentifierPattern *clone_pattern_impl () const override
     178              :   {
     179        47472 :     return new IdentifierPattern (*this);
     180              :   }
     181              : };
     182              : 
     183              : // HIR node for using the '_' wildcard "match any value" pattern
     184         1898 : class WildcardPattern : public Pattern
     185              : {
     186              :   location_t locus;
     187              :   Analysis::NodeMapping mappings;
     188              : 
     189              : public:
     190              :   using Pattern::is_refutable;
     191          351 :   bool is_refutable () const override { return false; }
     192              : 
     193          500 :   std::string to_string () const override { return "_"; }
     194              : 
     195         1133 :   WildcardPattern (Analysis::NodeMapping mappings, location_t locus)
     196         1133 :     : locus (locus), mappings (mappings)
     197              :   {}
     198              : 
     199         2508 :   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         6798 :   const Analysis::NodeMapping &get_mappings () const override final
     205              :   {
     206         6798 :     return mappings;
     207              :   }
     208              : 
     209          987 :   PatternType get_pattern_type () const override final
     210              :   {
     211          987 :     return PatternType::WILDCARD;
     212              :   }
     213              : 
     214              : protected:
     215              :   /* Use covariance to implement clone function as returning this object rather
     216              :    * than base */
     217         1898 :   WildcardPattern *clone_pattern_impl () const override
     218              :   {
     219         1898 :     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          258 :   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           33 :   PatternType get_pattern_type () const override final
     520              :   {
     521           33 :     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          487 :   location_t get_locus () const { return locus; }
     564          496 :   Analysis::NodeMapping get_mappings () const { return mappings; };
     565          231 :   AST::AttrVec get_outer_attrs () { return outer_attrs; }
     566              : 
     567              : protected:
     568          297 :   StructPatternField (Analysis::NodeMapping mappings,
     569              :                       AST::AttrVec outer_attribs, location_t locus)
     570          297 :     : outer_attrs (std::move (outer_attribs)), locus (locus),
     571          297 :       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           24 :   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           24 :       index (index), tuple_pattern (std::move (tuple_pattern))
     590           24 :   {}
     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          121 :   TupleIndex get_index () { return index; }
     620              : 
     621            0 :   TupleIndex get_index () const { return index; }
     622              : 
     623           93 :   Pattern &get_tuple_pattern () { return *tuple_pattern; }
     624              : 
     625            0 :   const Pattern &get_tuple_pattern () const { return *tuple_pattern; }
     626              : 
     627          100 :   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          167 :   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          167 :       ident (std::move (ident)), ident_pattern (std::move (ident_pattern))
     650          167 :   {}
     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          517 :   ItemType get_item_type () const override final { return ItemType::IDENT_PAT; }
     680              : 
     681          667 :   Identifier get_identifier () const { return ident; }
     682              : 
     683          607 :   Pattern &get_pattern () { return *ident_pattern; }
     684           13 :   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          106 :   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          106 :       has_ref (is_ref), mut (mut), ident (std::move (ident))
     708          106 :   {}
     709              : 
     710              :   std::string to_string () const override;
     711              : 
     712           12 :   bool is_mut () const { return mut == Mutability::Mut; }
     713              : 
     714              :   void accept_vis (HIRFullVisitor &vis) override;
     715              : 
     716          381 :   ItemType get_item_type () const override final { return ItemType::IDENT; }
     717            0 :   bool get_has_ref () const { return has_ref; }
     718          383 :   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          269 : 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           12 :   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           12 :   bool is_empty () const { return !has_struct_pattern_fields (); }
     742              : 
     743          167 :   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          176 :   StructPatternElements (
     752              :     std::vector<std::unique_ptr<StructPatternField>> fields,
     753              :     bool has_rest_pattern)
     754          176 :     : 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          176 :   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          609 :     return fields;
     793              :   }
     794              : 
     795              :   const std::vector<std::unique_ptr<StructPatternField>> &
     796              :   get_struct_pattern_fields () const
     797              :   {
     798           11 :     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          176 :   StructPattern (Analysis::NodeMapping mappings, PathInExpression struct_path,
     839              :                  StructPatternElements elems)
     840          176 :     : path (std::move (struct_path)), elems (std::move (elems)),
     841          176 :       mappings (mappings)
     842          176 :   {}
     843              : 
     844           12 :   bool has_struct_pattern_elems () const { return !elems.is_empty (); }
     845              : 
     846          467 :   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          704 :   StructPatternElements &get_struct_pattern_elems () { return elems; }
     853              : 
     854          711 :   const Analysis::NodeMapping &get_mappings () const override final
     855              :   {
     856          711 :     return mappings;
     857              :   }
     858              : 
     859           97 :   PatternType get_pattern_type () const override final
     860              :   {
     861           97 :     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         3770 : 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         2756 : class TupleStructItems : public PatternItems
     905              : {
     906              : public:
     907              :   // Unique pointer custom clone function
     908         1731 :   std::unique_ptr<TupleStructItems> clone_tuple_struct_items () const
     909              :   {
     910         1731 :     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          980 :   TupleStructItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
     925          980 :     : patterns (std::move (patterns))
     926              :   {}
     927              : 
     928              :   // Copy constructor with vector clone
     929         1653 :   TupleStructItemsNoRest (TupleStructItemsNoRest const &other)
     930         1653 :   {
     931         1653 :     patterns.reserve (other.patterns.size ());
     932         3464 :     for (const auto &e : other.patterns)
     933         1811 :       patterns.push_back (e->clone_pattern ());
     934         1653 :   }
     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         5022 :   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         3179 :   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         1653 :   TupleStructItemsNoRest *clone_pattern_items_impl () const override
     967              :   {
     968         1653 :     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          171 :     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         1025 :   TupleStructPattern (Analysis::NodeMapping mappings,
    1073              :                       PathInExpression tuple_struct_path,
    1074              :                       std::unique_ptr<TupleStructItems> items)
    1075         1025 :     : path (std::move (tuple_struct_path)), items (std::move (items)),
    1076         1025 :       mappings (mappings)
    1077         1025 :   {}
    1078              : 
    1079              :   // Copy constructor required to clone
    1080         1731 :   TupleStructPattern (TupleStructPattern const &other)
    1081         1731 :     : path (other.path), items (other.items->clone_tuple_struct_items ()),
    1082         1731 :       mappings (other.mappings)
    1083         1731 :   {}
    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         2357 :   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          917 :   PathInExpression &get_path () { return path; }
    1105              : 
    1106         4235 :   TupleStructItems &get_items () { return *items; }
    1107              : 
    1108         4115 :   const Analysis::NodeMapping &get_mappings () const override final
    1109              :   {
    1110         4115 :     return mappings;
    1111              :   }
    1112              : 
    1113          825 :   PatternType get_pattern_type () const override final
    1114              :   {
    1115          825 :     return PatternType::TUPLE_STRUCT;
    1116              :   }
    1117              : 
    1118              : protected:
    1119              :   /* Use covariance to implement clone function as returning this object rather
    1120              :    * than base */
    1121         1731 :   TupleStructPattern *clone_pattern_impl () const override
    1122              :   {
    1123         1731 :     return new TupleStructPattern (*this);
    1124              :   }
    1125              : };
    1126              : 
    1127              : // Base abstract class representing TuplePattern patterns
    1128          779 : class TuplePatternItems : public PatternItems
    1129              : {
    1130              : public:
    1131              :   // Unique pointer custom clone function
    1132          317 :   std::unique_ptr<TuplePatternItems> clone_tuple_pattern_items () const
    1133              :   {
    1134          317 :     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          424 :   TuplePatternItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
    1149          424 :     : patterns (std::move (patterns))
    1150              :   {}
    1151              : 
    1152              :   // Copy constructor with vector clone
    1153          264 :   TuplePatternItemsNoRest (TuplePatternItemsNoRest const &other)
    1154          264 :   {
    1155          264 :     patterns.reserve (other.patterns.size ());
    1156          792 :     for (const auto &e : other.patterns)
    1157          528 :       patterns.push_back (e->clone_pattern ());
    1158          264 :   }
    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         2122 :   ItemType get_item_type () const override { return ItemType::NO_REST; }
    1181              : 
    1182         2231 :   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          264 :   TuplePatternItemsNoRest *clone_pattern_items_impl () const override
    1192              :   {
    1193          264 :     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          439 :   bool has_tuple_pattern_items () const { return items != nullptr; }
    1314              : 
    1315          462 :   TuplePattern (Analysis::NodeMapping mappings,
    1316              :                 std::unique_ptr<TuplePatternItems> items, location_t locus)
    1317          462 :     : items (std::move (items)), locus (locus), mappings (mappings)
    1318              :   {}
    1319              : 
    1320              :   // Copy constructor requires clone
    1321          317 :   TuplePattern (TuplePattern const &other)
    1322          317 :     : items (other.items->clone_tuple_pattern_items ()), locus (other.locus),
    1323          317 :       mappings (other.mappings)
    1324          317 :   {}
    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         1753 :   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         3371 :   const Analysis::NodeMapping &get_mappings () const override final
    1342              :   {
    1343         3371 :     return mappings;
    1344              :   }
    1345              : 
    1346          425 :   PatternType get_pattern_type () const override final
    1347              :   {
    1348          425 :     return PatternType::TUPLE;
    1349              :   }
    1350              : 
    1351         3975 :   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          317 :   TuplePattern *clone_pattern_impl () const override
    1358              :   {
    1359          317 :     return new TuplePattern (*this);
    1360              :   }
    1361              : };
    1362              : 
    1363              : // Base abstract class representing SlicePattern patterns
    1364          235 : class SlicePatternItems : public PatternItems
    1365              : {
    1366              : public:
    1367              :   // Unique pointer custom clone function
    1368          152 :   std::unique_ptr<SlicePatternItems> clone_slice_pattern_items () const
    1369              :   {
    1370          152 :     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           34 :   SlicePatternItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
    1385           34 :     : patterns (std::move (patterns))
    1386              :   {}
    1387              : 
    1388              :   // Copy constructor with vector clone
    1389           64 :   SlicePatternItemsNoRest (SlicePatternItemsNoRest const &other)
    1390           64 :   {
    1391           64 :     patterns.reserve (other.patterns.size ());
    1392          192 :     for (const auto &e : other.patterns)
    1393          128 :       patterns.push_back (e->clone_pattern ());
    1394           64 :   }
    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           64 :   SlicePatternItemsNoRest *clone_pattern_items_impl () const override
    1428              :   {
    1429           64 :     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              : public:
    1441           49 :   SlicePatternItemsHasRest (
    1442              :     std::vector<std::unique_ptr<Pattern>> lower_patterns,
    1443              :     std::vector<std::unique_ptr<Pattern>> upper_patterns)
    1444           49 :     : lower_patterns (std::move (lower_patterns)),
    1445           49 :       upper_patterns (std::move (upper_patterns))
    1446              :   {}
    1447              : 
    1448              :   // Copy constructor with vector clone
    1449           88 :   SlicePatternItemsHasRest (SlicePatternItemsHasRest const &other)
    1450           88 :   {
    1451           88 :     lower_patterns.reserve (other.lower_patterns.size ());
    1452          175 :     for (const auto &e : other.lower_patterns)
    1453           87 :       lower_patterns.push_back (e->clone_pattern ());
    1454              : 
    1455           88 :     upper_patterns.reserve (other.upper_patterns.size ());
    1456          175 :     for (const auto &e : other.upper_patterns)
    1457           87 :       upper_patterns.push_back (e->clone_pattern ());
    1458           88 :   }
    1459              : 
    1460              :   // Overloaded assignment operator to clone
    1461              :   SlicePatternItemsHasRest &operator= (SlicePatternItemsHasRest const &other)
    1462              :   {
    1463              :     lower_patterns.clear ();
    1464              :     lower_patterns.reserve (other.lower_patterns.size ());
    1465              :     for (const auto &e : other.lower_patterns)
    1466              :       lower_patterns.push_back (e->clone_pattern ());
    1467              : 
    1468              :     lower_patterns.clear ();
    1469              :     upper_patterns.reserve (other.upper_patterns.size ());
    1470              :     for (const auto &e : other.upper_patterns)
    1471              :       upper_patterns.push_back (e->clone_pattern ());
    1472              : 
    1473              :     return *this;
    1474              :   }
    1475              : 
    1476              :   // move constructors
    1477              :   SlicePatternItemsHasRest (SlicePatternItemsHasRest &&other) = default;
    1478              :   SlicePatternItemsHasRest &operator= (SlicePatternItemsHasRest &&other)
    1479              :     = default;
    1480              : 
    1481              :   std::string to_string () const override;
    1482              : 
    1483              :   void accept_vis (HIRFullVisitor &vis) override;
    1484              : 
    1485          190 :   ItemType get_item_type () const override { return ItemType::HAS_REST; }
    1486              : 
    1487            0 :   std::vector<std::unique_ptr<Pattern>> &get_lower_patterns ()
    1488              :   {
    1489          181 :     return lower_patterns;
    1490              :   }
    1491              :   const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const
    1492              :   {
    1493            5 :     return lower_patterns;
    1494              :   }
    1495              : 
    1496            0 :   std::vector<std::unique_ptr<Pattern>> &get_upper_patterns ()
    1497              :   {
    1498          181 :     return upper_patterns;
    1499              :   }
    1500              :   const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const
    1501              :   {
    1502            5 :     return upper_patterns;
    1503              :   }
    1504              : 
    1505              : protected:
    1506              :   /* Use covariance to implement clone function as returning this object rather
    1507              :    * than base */
    1508           88 :   SlicePatternItemsHasRest *clone_pattern_items_impl () const override
    1509              :   {
    1510           88 :     return new SlicePatternItemsHasRest (*this);
    1511              :   }
    1512              : };
    1513              : 
    1514              : // HIR node representing patterns that can match slices and arrays
    1515              : class SlicePattern : public Pattern
    1516              : {
    1517              :   std::unique_ptr<SlicePatternItems> items;
    1518              :   location_t locus;
    1519              :   Analysis::NodeMapping mappings;
    1520              : 
    1521              : public:
    1522              :   bool is_refutable (const TyTy::BaseType &scrutinee) const override;
    1523            0 :   bool is_refutable () const override
    1524              :   {
    1525              :     // Needs to be called with the other overload
    1526            0 :     rust_unreachable ();
    1527              :   }
    1528              :   std::string to_string () const override;
    1529              : 
    1530           83 :   SlicePattern (Analysis::NodeMapping mappings,
    1531              :                 std::unique_ptr<SlicePatternItems> items, location_t locus)
    1532           83 :     : items (std::move (items)), locus (locus), mappings (mappings)
    1533              :   {}
    1534              : 
    1535              :   // Copy constructor requires clone
    1536          152 :   SlicePattern (SlicePattern const &other)
    1537          152 :     : items (other.items->clone_slice_pattern_items ()), locus (other.locus),
    1538          152 :       mappings (other.mappings)
    1539          152 :   {}
    1540              : 
    1541              :   // Overloaded assignment operator to vector clone
    1542              :   SlicePattern &operator= (SlicePattern const &other)
    1543              :   {
    1544              :     items = other.items->clone_slice_pattern_items ();
    1545              :     locus = other.locus;
    1546              :     mappings = other.mappings;
    1547              : 
    1548              :     return *this;
    1549              :   }
    1550              : 
    1551              :   // move constructors
    1552              :   SlicePattern (SlicePattern &&other) = default;
    1553              :   SlicePattern &operator= (SlicePattern &&other) = default;
    1554              : 
    1555          705 :   SlicePatternItems &get_items () { return *items; }
    1556              :   const SlicePatternItems &get_items () const { return *items; }
    1557              : 
    1558          882 :   location_t get_locus () const override { return locus; }
    1559              : 
    1560              :   void accept_vis (HIRFullVisitor &vis) override;
    1561              :   void accept_vis (HIRPatternVisitor &vis) override;
    1562              : 
    1563          570 :   const Analysis::NodeMapping &get_mappings () const override final
    1564              :   {
    1565          570 :     return mappings;
    1566              :   }
    1567              : 
    1568           75 :   PatternType get_pattern_type () const override final
    1569              :   {
    1570           75 :     return PatternType::SLICE;
    1571              :   }
    1572              : 
    1573              : protected:
    1574              :   /* Use covariance to implement clone function as returning this object rather
    1575              :    * than base */
    1576          152 :   SlicePattern *clone_pattern_impl () const override
    1577              :   {
    1578          152 :     return new SlicePattern (*this);
    1579              :   }
    1580              : };
    1581              : 
    1582              : // HIR node for alternative patterns
    1583              : class AltPattern : public Pattern
    1584              : {
    1585              :   std::vector<std::unique_ptr<Pattern>> alts;
    1586              :   location_t locus;
    1587              :   Analysis::NodeMapping mappings;
    1588              : 
    1589              : public:
    1590              :   std::string to_string () const override;
    1591              : 
    1592          151 :   AltPattern (Analysis::NodeMapping mappings,
    1593              :               std::vector<std::unique_ptr<Pattern>> alts, location_t locus)
    1594          151 :     : alts (std::move (alts)), locus (locus), mappings (mappings)
    1595          151 :   {}
    1596              : 
    1597              :   // Copy constructor with vector clone
    1598          148 :   AltPattern (AltPattern const &other)
    1599          148 :     : locus (other.locus), mappings (other.mappings)
    1600              :   {
    1601          148 :     alts.reserve (other.alts.size ());
    1602          446 :     for (const auto &e : other.alts)
    1603          298 :       alts.push_back (e->clone_pattern ());
    1604          148 :   }
    1605              : 
    1606              :   // Overloaded assignment operator to vector clone
    1607              :   AltPattern &operator= (AltPattern const &other)
    1608              :   {
    1609              :     locus = other.locus;
    1610              :     mappings = other.mappings;
    1611              : 
    1612              :     alts.clear ();
    1613              :     alts.reserve (other.alts.size ());
    1614              :     for (const auto &e : other.alts)
    1615              :       alts.push_back (e->clone_pattern ());
    1616              : 
    1617              :     return *this;
    1618              :   }
    1619              : 
    1620              :   // move constructors
    1621              :   AltPattern (AltPattern &&other) = default;
    1622              :   AltPattern &operator= (AltPattern &&other) = default;
    1623              : 
    1624              :   using Pattern::is_refutable;
    1625            2 :   bool is_refutable () const override
    1626              :   {
    1627              :     // TODO We need exhaustiveness checks of the type being matched on to
    1628              :     // correctly determine refutability, so we conservatively return true
    1629            2 :     rust_sorry_at (get_locus (),
    1630              :                    "alt pattern refutability is not yet implemented");
    1631            2 :     rust_unreachable ();
    1632              :   }
    1633              : 
    1634          337 :   std::vector<std::unique_ptr<Pattern>> &get_alts () { return alts; }
    1635              :   const std::vector<std::unique_ptr<Pattern>> &get_alts () const
    1636              :   {
    1637              :     return alts;
    1638              :   }
    1639              : 
    1640          837 :   location_t get_locus () const override { return locus; }
    1641              : 
    1642              :   void accept_vis (HIRFullVisitor &vis) override;
    1643              :   void accept_vis (HIRPatternVisitor &vis) override;
    1644              : 
    1645         1015 :   const Analysis::NodeMapping &get_mappings () const override final
    1646              :   {
    1647         1015 :     return mappings;
    1648              :   }
    1649              : 
    1650          145 :   PatternType get_pattern_type () const override final
    1651              :   {
    1652          145 :     return PatternType::ALT;
    1653              :   }
    1654              : 
    1655              : protected:
    1656              :   /* Use covariance to implement clone function as returning this object rather
    1657              :    * than base */
    1658          148 :   AltPattern *clone_pattern_impl () const override
    1659              :   {
    1660          148 :     return new AltPattern (*this);
    1661              :   }
    1662              : };
    1663              : 
    1664              : // Moved definition to rust-path.h
    1665              : class PathPattern;
    1666              : 
    1667              : // Forward decls for paths (defined in rust-path.h)
    1668              : class PathInExpression;
    1669              : class QualifiedPathInExpression;
    1670              : 
    1671              : } // namespace HIR
    1672              : } // namespace Rust
    1673              : 
    1674              : #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.