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