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