[PR testsuite/116860] Testsuite adjustment for recently added tests
[official-gcc.git] / gcc / rust / ast / rust-pattern.h
blob172f359dbb560eeb7522f62f420eba97dac09b17
1 // Copyright (C) 2020-2025 Free Software Foundation, Inc.
3 // This file is part of GCC.
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.
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.
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/>.
19 #ifndef RUST_AST_PATTERN_H
20 #define RUST_AST_PATTERN_H
22 #include "rust-ast.h"
24 namespace Rust {
25 namespace AST {
26 // Literal pattern AST node (comparing to a literal)
27 class LiteralPattern : public Pattern
29 Literal lit;
30 location_t locus;
31 NodeId node_id;
33 public:
34 std::string as_string () const override;
36 // Constructor for a literal pattern
37 LiteralPattern (Literal lit, location_t locus)
38 : lit (std::move (lit)), locus (locus),
39 node_id (Analysis::Mappings::get ()->get_next_node_id ())
42 LiteralPattern (std::string val, Literal::LitType type, location_t locus,
43 PrimitiveCoreType type_hint)
44 : lit (Literal (std::move (val), type, type_hint)), locus (locus),
45 node_id (Analysis::Mappings::get ()->get_next_node_id ())
48 location_t get_locus () const override final { return locus; }
50 void accept_vis (ASTVisitor &vis) override;
52 NodeId get_node_id () const override { return node_id; }
54 Literal &get_literal () { return lit; }
56 const Literal &get_literal () const { return lit; }
58 Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Literal; }
60 protected:
61 /* Use covariance to implement clone function as returning this object rather
62 * than base */
63 virtual LiteralPattern *clone_pattern_impl () const override
65 return new LiteralPattern (*this);
69 // Identifier pattern AST node (bind value matched to a variable)
70 class IdentifierPattern : public Pattern
72 Identifier variable_ident;
73 bool is_ref;
74 bool is_mut;
76 // bool has_pattern;
77 std::unique_ptr<Pattern> to_bind;
78 location_t locus;
79 NodeId node_id;
81 public:
82 std::string as_string () const override;
84 // Returns whether the IdentifierPattern has a pattern to bind.
85 bool has_pattern_to_bind () const { return to_bind != nullptr; }
87 // Constructor
88 IdentifierPattern (Identifier ident, location_t locus, bool is_ref = false,
89 bool is_mut = false,
90 std::unique_ptr<Pattern> to_bind = nullptr)
91 : Pattern (), variable_ident (std::move (ident)), is_ref (is_ref),
92 is_mut (is_mut), to_bind (std::move (to_bind)), locus (locus),
93 node_id (Analysis::Mappings::get ()->get_next_node_id ())
96 IdentifierPattern (NodeId node_id, Identifier ident, location_t locus,
97 bool is_ref = false, bool is_mut = false,
98 std::unique_ptr<Pattern> to_bind = nullptr)
99 : Pattern (), variable_ident (std::move (ident)), is_ref (is_ref),
100 is_mut (is_mut), to_bind (std::move (to_bind)), locus (locus),
101 node_id (node_id)
104 // Copy constructor with clone
105 IdentifierPattern (IdentifierPattern const &other)
106 : variable_ident (other.variable_ident), is_ref (other.is_ref),
107 is_mut (other.is_mut), locus (other.locus), node_id (other.node_id)
109 // fix to get prevent null pointer dereference
110 if (other.to_bind != nullptr)
111 to_bind = other.to_bind->clone_pattern ();
114 // Overload assignment operator to use clone
115 IdentifierPattern &operator= (IdentifierPattern const &other)
117 variable_ident = other.variable_ident;
118 is_ref = other.is_ref;
119 is_mut = other.is_mut;
120 locus = other.locus;
121 node_id = other.node_id;
123 // fix to prevent null pointer dereference
124 if (other.to_bind != nullptr)
125 to_bind = other.to_bind->clone_pattern ();
126 else
127 to_bind = nullptr;
129 return *this;
132 // default move semantics
133 IdentifierPattern (IdentifierPattern &&other) = default;
134 IdentifierPattern &operator= (IdentifierPattern &&other) = default;
136 location_t get_locus () const override final { return locus; }
138 void accept_vis (ASTVisitor &vis) override;
140 // TODO: is this better? Or is a "vis_pattern" better?
141 Pattern &get_pattern_to_bind ()
143 rust_assert (has_pattern_to_bind ());
144 return *to_bind;
147 Identifier get_ident () const { return variable_ident; }
149 bool get_is_mut () const { return is_mut; }
150 bool get_is_ref () const { return is_ref; }
152 NodeId get_node_id () const override { return node_id; }
154 Pattern::Kind get_pattern_kind () override
156 return Pattern::Kind::Identifier;
159 protected:
160 /* Use covariance to implement clone function as returning this object rather
161 * than base */
162 IdentifierPattern *clone_pattern_impl () const override
164 return new IdentifierPattern (*this);
168 // AST node for using the '_' wildcard "match any value" pattern
169 class WildcardPattern : public Pattern
171 location_t locus;
172 NodeId node_id;
174 public:
175 std::string as_string () const override { return std::string (1, '_'); }
177 WildcardPattern (location_t locus)
178 : locus (locus), node_id (Analysis::Mappings::get ()->get_next_node_id ())
181 location_t get_locus () const override final { return locus; }
183 void accept_vis (ASTVisitor &vis) override;
185 NodeId get_node_id () const override { return node_id; }
187 Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Wildcard; }
189 protected:
190 /* Use covariance to implement clone function as returning this object rather
191 * than base */
192 WildcardPattern *clone_pattern_impl () const override
194 return new WildcardPattern (*this);
198 class RestPattern : public Pattern
200 location_t locus;
201 NodeId node_id;
203 public:
204 std::string as_string () const override { return ".."; }
206 RestPattern (location_t locus)
207 : locus (locus), node_id (Analysis::Mappings::get ()->get_next_node_id ())
210 location_t get_locus () const override final { return locus; }
212 void accept_vis (ASTVisitor &vis) override;
214 NodeId get_node_id () const override final { return node_id; }
216 Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Rest; }
218 protected:
219 RestPattern *clone_pattern_impl () const override
221 return new RestPattern (*this);
225 // Base range pattern bound (lower or upper limit) - abstract
226 class RangePatternBound
228 public:
229 enum RangePatternBoundType
231 LITERAL,
232 PATH,
233 QUALPATH
236 virtual ~RangePatternBound () {}
238 // Unique pointer custom clone function
239 std::unique_ptr<RangePatternBound> clone_range_pattern_bound () const
241 return std::unique_ptr<RangePatternBound> (
242 clone_range_pattern_bound_impl ());
245 virtual std::string as_string () const = 0;
247 virtual void accept_vis (ASTVisitor &vis) = 0;
249 virtual RangePatternBoundType get_bound_type () const = 0;
251 protected:
252 // pure virtual as RangePatternBound is abstract
253 virtual RangePatternBound *clone_range_pattern_bound_impl () const = 0;
256 // Literal-based pattern bound
257 class RangePatternBoundLiteral : public RangePatternBound
259 Literal literal;
260 /* Can only be a char, byte, int, or float literal - same impl here as
261 * previously */
263 // Minus prefixed to literal (if integer or floating-point)
264 bool has_minus;
266 location_t locus;
268 public:
269 // Constructor
270 RangePatternBoundLiteral (Literal literal, location_t locus,
271 bool has_minus = false)
272 : literal (literal), has_minus (has_minus), locus (locus)
275 std::string as_string () const override;
277 Literal get_literal () const { return literal; }
279 bool get_has_minus () const { return has_minus; }
281 location_t get_locus () const { return locus; }
283 void accept_vis (ASTVisitor &vis) override;
285 RangePatternBoundType get_bound_type () const override
287 return RangePatternBoundType::LITERAL;
290 protected:
291 /* Use covariance to implement clone function as returning this object rather
292 * than base */
293 RangePatternBoundLiteral *clone_range_pattern_bound_impl () const override
295 return new RangePatternBoundLiteral (*this);
299 // Path-based pattern bound
300 class RangePatternBoundPath : public RangePatternBound
302 PathInExpression path;
304 /* TODO: should this be refactored so that PathInExpression is a subclass of
305 * RangePatternBound? */
307 public:
308 RangePatternBoundPath (PathInExpression path) : path (std::move (path)) {}
310 std::string as_string () const override { return path.as_string (); }
312 location_t get_locus () const { return path.get_locus (); }
314 void accept_vis (ASTVisitor &vis) override;
316 // TODO: this mutable getter seems kinda dodgy
317 PathInExpression &get_path () { return path; }
318 const PathInExpression &get_path () const { return path; }
320 RangePatternBoundType get_bound_type () const override
322 return RangePatternBoundType::PATH;
325 protected:
326 /* Use covariance to implement clone function as returning this object rather
327 * than base */
328 RangePatternBoundPath *clone_range_pattern_bound_impl () const override
330 return new RangePatternBoundPath (*this);
334 // Qualified path-based pattern bound
335 class RangePatternBoundQualPath : public RangePatternBound
337 QualifiedPathInExpression path;
339 /* TODO: should this be refactored so that QualifiedPathInExpression is a
340 * subclass of RangePatternBound? */
342 public:
343 RangePatternBoundQualPath (QualifiedPathInExpression path)
344 : path (std::move (path))
347 std::string as_string () const override { return path.as_string (); }
349 location_t get_locus () const { return path.get_locus (); }
351 void accept_vis (ASTVisitor &vis) override;
353 // TODO: this mutable getter seems kinda dodgy
354 QualifiedPathInExpression &get_qualified_path () { return path; }
355 const QualifiedPathInExpression &get_qualified_path () const { return path; }
357 RangePatternBoundType get_bound_type () const override
359 return RangePatternBoundType::QUALPATH;
362 protected:
363 /* Use covariance to implement clone function as returning this object rather
364 * than base */
365 RangePatternBoundQualPath *clone_range_pattern_bound_impl () const override
367 return new RangePatternBoundQualPath (*this);
371 // AST node for matching within a certain range (range pattern)
372 class RangePattern : public Pattern
374 std::unique_ptr<RangePatternBound> lower;
375 std::unique_ptr<RangePatternBound> upper;
377 bool has_ellipsis_syntax;
379 /* location only stored to avoid a dereference - lower pattern should give
380 * correct location so maybe change in future */
381 location_t locus;
382 NodeId node_id;
384 public:
385 std::string as_string () const override;
387 // Constructor
388 RangePattern (std::unique_ptr<RangePatternBound> lower,
389 std::unique_ptr<RangePatternBound> upper, location_t locus,
390 bool has_ellipsis_syntax = false)
391 : lower (std::move (lower)), upper (std::move (upper)),
392 has_ellipsis_syntax (has_ellipsis_syntax), locus (locus),
393 node_id (Analysis::Mappings::get ()->get_next_node_id ())
396 // Copy constructor with clone
397 RangePattern (RangePattern const &other)
398 : lower (other.lower->clone_range_pattern_bound ()),
399 upper (other.upper->clone_range_pattern_bound ()),
400 has_ellipsis_syntax (other.has_ellipsis_syntax), locus (other.locus),
401 node_id (other.node_id)
404 // Overloaded assignment operator to clone
405 RangePattern &operator= (RangePattern const &other)
407 lower = other.lower->clone_range_pattern_bound ();
408 upper = other.upper->clone_range_pattern_bound ();
409 has_ellipsis_syntax = other.has_ellipsis_syntax;
410 locus = other.locus;
411 node_id = other.node_id;
413 return *this;
416 // default move semantics
417 RangePattern (RangePattern &&other) = default;
418 RangePattern &operator= (RangePattern &&other) = default;
420 location_t get_locus () const override final { return locus; }
422 bool get_has_ellipsis_syntax () { return has_ellipsis_syntax; }
424 bool get_has_lower_bound () { return lower != nullptr; }
426 bool get_has_upper_bound () { return upper != nullptr; }
428 void accept_vis (ASTVisitor &vis) override;
430 // TODO: is this better? or is a "vis_bound" better?
431 RangePatternBound &get_lower_bound ()
433 rust_assert (lower != nullptr);
434 return *lower;
437 RangePatternBound &get_upper_bound ()
439 rust_assert (upper != nullptr);
440 return *upper;
443 NodeId get_node_id () const override { return node_id; }
445 Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Range; }
447 protected:
448 /* Use covariance to implement clone function as returning this object rather
449 * than base */
450 RangePattern *clone_pattern_impl () const override
452 return new RangePattern (*this);
456 // AST node for pattern based on dereferencing the pointers given
457 class ReferencePattern : public Pattern
459 bool has_two_amps;
460 bool is_mut;
461 std::unique_ptr<Pattern> pattern;
462 location_t locus;
463 NodeId node_id;
465 public:
466 std::string as_string () const override;
468 ReferencePattern (std::unique_ptr<Pattern> pattern, bool is_mut_reference,
469 bool ref_has_two_amps, location_t locus)
470 : has_two_amps (ref_has_two_amps), is_mut (is_mut_reference),
471 pattern (std::move (pattern)), locus (locus),
472 node_id (Analysis::Mappings::get ()->get_next_node_id ())
475 // Copy constructor requires clone
476 ReferencePattern (ReferencePattern const &other)
477 : has_two_amps (other.has_two_amps), is_mut (other.is_mut),
478 pattern (other.pattern->clone_pattern ()), locus (other.locus),
479 node_id (other.node_id)
482 // Overload assignment operator to clone
483 ReferencePattern &operator= (ReferencePattern const &other)
485 pattern = other.pattern->clone_pattern ();
486 is_mut = other.is_mut;
487 has_two_amps = other.has_two_amps;
488 locus = other.locus;
489 node_id = other.node_id;
491 return *this;
494 // default move semantics
495 ReferencePattern (ReferencePattern &&other) = default;
496 ReferencePattern &operator= (ReferencePattern &&other) = default;
498 location_t get_locus () const override final { return locus; }
500 void accept_vis (ASTVisitor &vis) override;
502 // TODO: is this better? Or is a "vis_pattern" better?
503 Pattern &get_referenced_pattern ()
505 rust_assert (pattern != nullptr);
506 return *pattern;
509 bool is_double_reference () const { return has_two_amps; }
511 bool get_is_mut () const { return is_mut; }
513 NodeId get_node_id () const override { return node_id; }
515 Pattern::Kind get_pattern_kind () override
517 return Pattern::Kind::Reference;
520 protected:
521 /* Use covariance to implement clone function as returning this object rather
522 * than base */
523 ReferencePattern *clone_pattern_impl () const override
525 return new ReferencePattern (*this);
529 #if 0
530 // aka StructPatternEtCetera; potential element in struct pattern
531 struct StructPatternEtc
533 private:
534 std::vector<Attribute> outer_attrs;
536 // should this store location data?
538 public:
539 StructPatternEtc (std::vector<Attribute> outer_attribs)
540 : outer_attrs (std::move (outer_attribs))
543 // Creates an empty StructPatternEtc
544 static StructPatternEtc create_empty ()
546 return StructPatternEtc (std::vector<Attribute> ());
549 #endif
551 // Base class for a single field in a struct pattern - abstract
552 class StructPatternField
554 std::vector<Attribute> outer_attrs;
555 location_t locus;
557 protected:
558 NodeId node_id;
560 public:
561 enum ItemType
563 TUPLE_PAT,
564 IDENT_PAT,
565 IDENT
568 virtual ~StructPatternField () {}
570 // Unique pointer custom clone function
571 std::unique_ptr<StructPatternField> clone_struct_pattern_field () const
573 return std::unique_ptr<StructPatternField> (
574 clone_struct_pattern_field_impl ());
577 virtual std::string as_string () const;
579 location_t get_locus () const { return locus; }
581 virtual void accept_vis (ASTVisitor &vis) = 0;
583 virtual void mark_for_strip () = 0;
584 virtual bool is_marked_for_strip () const = 0;
585 virtual ItemType get_item_type () const = 0;
587 NodeId get_node_id () const { return node_id; }
589 // TODO: seems kinda dodgy. Think of better way.
590 std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
591 const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
593 protected:
594 StructPatternField (std::vector<Attribute> outer_attribs, location_t locus,
595 NodeId node_id)
596 : outer_attrs (std::move (outer_attribs)), locus (locus), node_id (node_id)
599 // Clone function implementation as pure virtual method
600 virtual StructPatternField *clone_struct_pattern_field_impl () const = 0;
603 // Tuple pattern single field in a struct pattern
604 class StructPatternFieldTuplePat : public StructPatternField
606 TupleIndex index;
607 std::unique_ptr<Pattern> tuple_pattern;
609 public:
610 StructPatternFieldTuplePat (TupleIndex index,
611 std::unique_ptr<Pattern> tuple_pattern,
612 std::vector<Attribute> outer_attribs,
613 location_t locus)
614 : StructPatternField (std::move (outer_attribs), locus,
615 Analysis::Mappings::get ()->get_next_node_id ()),
616 index (index), tuple_pattern (std::move (tuple_pattern))
619 // Copy constructor requires clone
620 StructPatternFieldTuplePat (StructPatternFieldTuplePat const &other)
621 : StructPatternField (other), index (other.index)
623 // guard to prevent null dereference (only required if error state)
624 node_id = other.get_node_id ();
625 if (other.tuple_pattern != nullptr)
626 tuple_pattern = other.tuple_pattern->clone_pattern ();
629 // Overload assignment operator to perform clone
630 StructPatternFieldTuplePat &
631 operator= (StructPatternFieldTuplePat const &other)
633 StructPatternField::operator= (other);
634 index = other.index;
635 // outer_attrs = other.outer_attrs;
636 node_id = other.get_node_id ();
638 // guard to prevent null dereference (only required if error state)
639 if (other.tuple_pattern != nullptr)
640 tuple_pattern = other.tuple_pattern->clone_pattern ();
641 else
642 tuple_pattern = nullptr;
644 return *this;
647 // default move semantics
648 StructPatternFieldTuplePat (StructPatternFieldTuplePat &&other) = default;
649 StructPatternFieldTuplePat &operator= (StructPatternFieldTuplePat &&other)
650 = default;
652 std::string as_string () const override;
654 void accept_vis (ASTVisitor &vis) override;
656 // based on idea of tuple pattern no longer existing
657 void mark_for_strip () override { tuple_pattern = nullptr; }
658 bool is_marked_for_strip () const override
660 return tuple_pattern == nullptr;
663 TupleIndex get_index () { return index; }
665 // TODO: is this better? Or is a "vis_pattern" better?
666 Pattern &get_index_pattern ()
668 rust_assert (tuple_pattern != nullptr);
669 return *tuple_pattern;
672 ItemType get_item_type () const override final { return ItemType::TUPLE_PAT; }
674 protected:
675 /* Use covariance to implement clone function as returning this object rather
676 * than base */
677 StructPatternFieldTuplePat *clone_struct_pattern_field_impl () const override
679 return new StructPatternFieldTuplePat (*this);
683 // Identifier pattern single field in a struct pattern
684 class StructPatternFieldIdentPat : public StructPatternField
686 Identifier ident;
687 std::unique_ptr<Pattern> ident_pattern;
689 public:
690 StructPatternFieldIdentPat (Identifier ident,
691 std::unique_ptr<Pattern> ident_pattern,
692 std::vector<Attribute> outer_attrs,
693 location_t locus)
694 : StructPatternField (std::move (outer_attrs), locus,
695 Analysis::Mappings::get ()->get_next_node_id ()),
696 ident (std::move (ident)), ident_pattern (std::move (ident_pattern))
699 // Copy constructor requires clone
700 StructPatternFieldIdentPat (StructPatternFieldIdentPat const &other)
701 : StructPatternField (other), ident (other.ident)
703 // guard to prevent null dereference (only required if error state)
704 node_id = other.get_node_id ();
705 if (other.ident_pattern != nullptr)
706 ident_pattern = other.ident_pattern->clone_pattern ();
709 // Overload assignment operator to clone
710 StructPatternFieldIdentPat &
711 operator= (StructPatternFieldIdentPat const &other)
713 StructPatternField::operator= (other);
714 ident = other.ident;
715 // outer_attrs = other.outer_attrs;
716 node_id = other.get_node_id ();
718 // guard to prevent null dereference (only required if error state)
719 if (other.ident_pattern != nullptr)
720 ident_pattern = other.ident_pattern->clone_pattern ();
721 else
722 ident_pattern = nullptr;
724 return *this;
727 // default move semantics
728 StructPatternFieldIdentPat (StructPatternFieldIdentPat &&other) = default;
729 StructPatternFieldIdentPat &operator= (StructPatternFieldIdentPat &&other)
730 = default;
732 std::string as_string () const override;
734 void accept_vis (ASTVisitor &vis) override;
736 // based on idea of identifier pattern no longer existing
737 void mark_for_strip () override { ident_pattern = nullptr; }
738 bool is_marked_for_strip () const override
740 return ident_pattern == nullptr;
743 const Identifier &get_identifier () const { return ident; }
745 // TODO: is this better? Or is a "vis_pattern" better?
746 Pattern &get_ident_pattern ()
748 rust_assert (ident_pattern != nullptr);
749 return *ident_pattern;
752 ItemType get_item_type () const override final { return ItemType::IDENT_PAT; }
754 protected:
755 /* Use covariance to implement clone function as returning this object rather
756 * than base */
757 StructPatternFieldIdentPat *clone_struct_pattern_field_impl () const override
759 return new StructPatternFieldIdentPat (*this);
763 // Identifier only (with no pattern) single field in a struct pattern
764 class StructPatternFieldIdent : public StructPatternField
766 bool has_ref;
767 bool has_mut;
768 Identifier ident;
770 public:
771 StructPatternFieldIdent (Identifier ident, bool is_ref, bool is_mut,
772 std::vector<Attribute> outer_attrs, location_t locus)
773 : StructPatternField (std::move (outer_attrs), locus,
774 Analysis::Mappings::get ()->get_next_node_id ()),
775 has_ref (is_ref), has_mut (is_mut), ident (std::move (ident))
778 std::string as_string () const override;
780 void accept_vis (ASTVisitor &vis) override;
782 // based on idea of identifier no longer existing
783 void mark_for_strip () override { ident = {""}; }
784 bool is_marked_for_strip () const override { return ident.empty (); }
786 const Identifier &get_identifier () const { return ident; }
788 ItemType get_item_type () const override final { return ItemType::IDENT; }
790 bool is_ref () const { return has_ref; }
792 bool is_mut () const { return has_mut; }
794 protected:
795 /* Use covariance to implement clone function as returning this object rather
796 * than base */
797 StructPatternFieldIdent *clone_struct_pattern_field_impl () const override
799 return new StructPatternFieldIdent (*this);
803 // Elements of a struct pattern
804 class StructPatternElements
806 // bool has_struct_pattern_fields;
807 std::vector<std::unique_ptr<StructPatternField>> fields;
809 bool has_struct_pattern_etc;
810 std::vector<Attribute> struct_pattern_etc_attrs;
811 // StructPatternEtc etc;
813 // must have at least one of the two and maybe both
815 // should this store location data?
817 public:
818 // Returns whether there are any struct pattern fields
819 bool has_struct_pattern_fields () const { return !fields.empty (); }
821 /* Returns whether the struct pattern elements is entirely empty (no fields,
822 * no etc). */
823 bool is_empty () const
825 return !has_struct_pattern_fields () && !has_struct_pattern_etc;
828 bool has_etc () const { return has_struct_pattern_etc; }
830 // Constructor for StructPatternElements with both (potentially)
831 StructPatternElements (
832 std::vector<std::unique_ptr<StructPatternField>> fields,
833 std::vector<Attribute> etc_attrs)
834 : fields (std::move (fields)), has_struct_pattern_etc (true),
835 struct_pattern_etc_attrs (std::move (etc_attrs))
838 // Constructor for StructPatternElements with no StructPatternEtc
839 StructPatternElements (
840 std::vector<std::unique_ptr<StructPatternField>> fields)
841 : fields (std::move (fields)), has_struct_pattern_etc (false),
842 struct_pattern_etc_attrs ()
845 // Copy constructor with vector clone
846 StructPatternElements (StructPatternElements const &other)
847 : has_struct_pattern_etc (other.has_struct_pattern_etc),
848 struct_pattern_etc_attrs (other.struct_pattern_etc_attrs)
850 fields.reserve (other.fields.size ());
851 for (const auto &e : other.fields)
852 fields.push_back (e->clone_struct_pattern_field ());
855 // Overloaded assignment operator with vector clone
856 StructPatternElements &operator= (StructPatternElements const &other)
858 struct_pattern_etc_attrs = other.struct_pattern_etc_attrs;
859 has_struct_pattern_etc = other.has_struct_pattern_etc;
861 fields.clear ();
862 fields.reserve (other.fields.size ());
863 for (const auto &e : other.fields)
864 fields.push_back (e->clone_struct_pattern_field ());
866 return *this;
869 // move constructors
870 StructPatternElements (StructPatternElements &&other) = default;
871 StructPatternElements &operator= (StructPatternElements &&other) = default;
873 // Creates an empty StructPatternElements
874 static StructPatternElements create_empty ()
876 return StructPatternElements (
877 std::vector<std::unique_ptr<StructPatternField>> ());
880 std::string as_string () const;
882 // TODO: seems kinda dodgy. Think of better way.
883 std::vector<std::unique_ptr<StructPatternField>> &get_struct_pattern_fields ()
885 return fields;
887 const std::vector<std::unique_ptr<StructPatternField>> &
888 get_struct_pattern_fields () const
890 return fields;
893 std::vector<Attribute> &get_etc_outer_attrs ()
895 return struct_pattern_etc_attrs;
897 const std::vector<Attribute> &get_etc_outer_attrs () const
899 return struct_pattern_etc_attrs;
902 void strip_etc ()
904 has_struct_pattern_etc = false;
905 struct_pattern_etc_attrs.clear ();
906 struct_pattern_etc_attrs.shrink_to_fit ();
910 // Struct pattern AST node representation
911 class StructPattern : public Pattern
913 PathInExpression path;
915 // bool has_struct_pattern_elements;
916 StructPatternElements elems;
918 NodeId node_id;
919 location_t locus;
921 public:
922 std::string as_string () const override;
924 // Constructs a struct pattern from specified StructPatternElements
925 StructPattern (PathInExpression struct_path, location_t locus,
926 StructPatternElements elems
927 = StructPatternElements::create_empty ())
928 : path (std::move (struct_path)), elems (std::move (elems)),
929 node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus)
932 /* TODO: constructor to construct via elements included in
933 * StructPatternElements */
935 /* Returns whether struct pattern has any struct pattern elements (if not, it
936 * is empty). */
937 bool has_struct_pattern_elems () const { return !elems.is_empty (); }
939 location_t get_locus () const override { return path.get_locus (); }
941 void accept_vis (ASTVisitor &vis) override;
943 // TODO: seems kinda dodgy. Think of better way.
944 StructPatternElements &get_struct_pattern_elems () { return elems; }
945 const StructPatternElements &get_struct_pattern_elems () const
947 return elems;
950 PathInExpression &get_path () { return path; }
951 const PathInExpression &get_path () const { return path; }
953 NodeId get_node_id () const override { return node_id; }
955 Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Struct; }
957 protected:
958 /* Use covariance to implement clone function as returning this object rather
959 * than base */
960 StructPattern *clone_pattern_impl () const override
962 return new StructPattern (*this);
966 // Base abstract class for patterns used in TupleStructPattern
967 class TupleStructItems
969 public:
970 enum ItemType
972 RANGE,
973 NO_RANGE
976 virtual ~TupleStructItems () {}
978 // TODO: should this store location data?
980 // Unique pointer custom clone function
981 std::unique_ptr<TupleStructItems> clone_tuple_struct_items () const
983 return std::unique_ptr<TupleStructItems> (clone_tuple_struct_items_impl ());
986 virtual std::string as_string () const = 0;
988 virtual void accept_vis (ASTVisitor &vis) = 0;
990 virtual ItemType get_item_type () const = 0;
992 protected:
993 // pure virtual clone implementation
994 virtual TupleStructItems *clone_tuple_struct_items_impl () const = 0;
997 // Class for non-ranged tuple struct pattern patterns
998 class TupleStructItemsNoRange : public TupleStructItems
1000 std::vector<std::unique_ptr<Pattern>> patterns;
1002 public:
1003 TupleStructItemsNoRange (std::vector<std::unique_ptr<Pattern>> patterns)
1004 : patterns (std::move (patterns))
1007 // Copy constructor with vector clone
1008 TupleStructItemsNoRange (TupleStructItemsNoRange const &other)
1010 patterns.reserve (other.patterns.size ());
1011 for (const auto &e : other.patterns)
1012 patterns.push_back (e->clone_pattern ());
1015 // Overloaded assignment operator with vector clone
1016 TupleStructItemsNoRange &operator= (TupleStructItemsNoRange const &other)
1018 patterns.clear ();
1019 patterns.reserve (other.patterns.size ());
1020 for (const auto &e : other.patterns)
1021 patterns.push_back (e->clone_pattern ());
1023 return *this;
1026 // move constructors
1027 TupleStructItemsNoRange (TupleStructItemsNoRange &&other) = default;
1028 TupleStructItemsNoRange &operator= (TupleStructItemsNoRange &&other)
1029 = default;
1031 std::string as_string () const override;
1033 void accept_vis (ASTVisitor &vis) override;
1035 // TODO: seems kinda dodgy. Think of better way.
1036 std::vector<std::unique_ptr<Pattern>> &get_patterns () { return patterns; }
1037 const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
1039 return patterns;
1042 ItemType get_item_type () const override final { return ItemType::NO_RANGE; }
1044 protected:
1045 /* Use covariance to implement clone function as returning this object rather
1046 * than base */
1047 TupleStructItemsNoRange *clone_tuple_struct_items_impl () const override
1049 return new TupleStructItemsNoRange (*this);
1053 // Class for ranged tuple struct pattern patterns
1054 class TupleStructItemsRange : public TupleStructItems
1056 std::vector<std::unique_ptr<Pattern>> lower_patterns;
1057 std::vector<std::unique_ptr<Pattern>> upper_patterns;
1059 public:
1060 TupleStructItemsRange (std::vector<std::unique_ptr<Pattern>> lower_patterns,
1061 std::vector<std::unique_ptr<Pattern>> upper_patterns)
1062 : lower_patterns (std::move (lower_patterns)),
1063 upper_patterns (std::move (upper_patterns))
1066 // Copy constructor with vector clone
1067 TupleStructItemsRange (TupleStructItemsRange const &other)
1069 lower_patterns.reserve (other.lower_patterns.size ());
1070 for (const auto &e : other.lower_patterns)
1071 lower_patterns.push_back (e->clone_pattern ());
1073 upper_patterns.reserve (other.upper_patterns.size ());
1074 for (const auto &e : other.upper_patterns)
1075 upper_patterns.push_back (e->clone_pattern ());
1078 // Overloaded assignment operator to clone
1079 TupleStructItemsRange &operator= (TupleStructItemsRange const &other)
1081 lower_patterns.clear ();
1082 lower_patterns.reserve (other.lower_patterns.size ());
1083 for (const auto &e : other.lower_patterns)
1084 lower_patterns.push_back (e->clone_pattern ());
1086 upper_patterns.clear ();
1087 upper_patterns.reserve (other.upper_patterns.size ());
1088 for (const auto &e : other.upper_patterns)
1089 upper_patterns.push_back (e->clone_pattern ());
1091 return *this;
1094 // move constructors
1095 TupleStructItemsRange (TupleStructItemsRange &&other) = default;
1096 TupleStructItemsRange &operator= (TupleStructItemsRange &&other) = default;
1098 std::string as_string () const override;
1100 void accept_vis (ASTVisitor &vis) override;
1102 // TODO: seems kinda dodgy. Think of better way.
1103 std::vector<std::unique_ptr<Pattern>> &get_lower_patterns ()
1105 return lower_patterns;
1107 const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const
1109 return lower_patterns;
1112 // TODO: seems kinda dodgy. Think of better way.
1113 std::vector<std::unique_ptr<Pattern>> &get_upper_patterns ()
1115 return upper_patterns;
1117 const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const
1119 return upper_patterns;
1122 ItemType get_item_type () const override final { return ItemType::RANGE; }
1124 protected:
1125 /* Use covariance to implement clone function as returning this object rather
1126 * than base */
1127 TupleStructItemsRange *clone_tuple_struct_items_impl () const override
1129 return new TupleStructItemsRange (*this);
1133 // AST node representing a tuple struct pattern
1134 class TupleStructPattern : public Pattern
1136 PathInExpression path;
1137 std::unique_ptr<TupleStructItems> items;
1138 NodeId node_id;
1140 /* TOOD: should this store location data? current accessor uses path location
1141 * data */
1143 public:
1144 std::string as_string () const override;
1146 TupleStructPattern (PathInExpression tuple_struct_path,
1147 std::unique_ptr<TupleStructItems> items)
1148 : path (std::move (tuple_struct_path)), items (std::move (items)),
1149 node_id (Analysis::Mappings::get ()->get_next_node_id ())
1151 rust_assert (this->items != nullptr);
1154 // Copy constructor required to clone
1155 TupleStructPattern (TupleStructPattern const &other) : path (other.path)
1157 // guard to protect from null dereference
1158 rust_assert (other.items != nullptr);
1160 node_id = other.node_id;
1161 items = other.items->clone_tuple_struct_items ();
1164 // Operator overload assignment operator to clone
1165 TupleStructPattern &operator= (TupleStructPattern const &other)
1167 path = other.path;
1168 node_id = other.node_id;
1170 // guard to protect from null dereference
1171 rust_assert (other.items != nullptr);
1173 items = other.items->clone_tuple_struct_items ();
1175 return *this;
1178 // move constructors
1179 TupleStructPattern (TupleStructPattern &&other) = default;
1180 TupleStructPattern &operator= (TupleStructPattern &&other) = default;
1182 location_t get_locus () const override { return path.get_locus (); }
1184 void accept_vis (ASTVisitor &vis) override;
1186 TupleStructItems &get_items ()
1188 rust_assert (items != nullptr);
1189 return *items;
1192 PathInExpression &get_path () { return path; }
1193 const PathInExpression &get_path () const { return path; }
1195 NodeId get_node_id () const override { return node_id; }
1197 Pattern::Kind get_pattern_kind () override
1199 return Pattern::Kind::TupleStruct;
1202 protected:
1203 /* Use covariance to implement clone function as returning this object rather
1204 * than base */
1205 TupleStructPattern *clone_pattern_impl () const override
1207 return new TupleStructPattern (*this);
1211 // Base abstract class representing TuplePattern patterns
1212 class TuplePatternItems
1214 public:
1215 enum TuplePatternItemType
1217 MULTIPLE,
1218 RANGED,
1221 virtual ~TuplePatternItems () {}
1223 // TODO: should this store location data?
1225 // Unique pointer custom clone function
1226 std::unique_ptr<TuplePatternItems> clone_tuple_pattern_items () const
1228 return std::unique_ptr<TuplePatternItems> (
1229 clone_tuple_pattern_items_impl ());
1232 virtual std::string as_string () const = 0;
1234 virtual void accept_vis (ASTVisitor &vis) = 0;
1236 virtual TuplePatternItemType get_pattern_type () const = 0;
1238 protected:
1239 // pure virtual clone implementation
1240 virtual TuplePatternItems *clone_tuple_pattern_items_impl () const = 0;
1243 // Class representing TuplePattern patterns where there are multiple patterns
1244 class TuplePatternItemsMultiple : public TuplePatternItems
1246 std::vector<std::unique_ptr<Pattern>> patterns;
1248 public:
1249 TuplePatternItemsMultiple (std::vector<std::unique_ptr<Pattern>> patterns)
1250 : patterns (std::move (patterns))
1253 // Copy constructor with vector clone
1254 TuplePatternItemsMultiple (TuplePatternItemsMultiple const &other)
1256 patterns.reserve (other.patterns.size ());
1257 for (const auto &e : other.patterns)
1258 patterns.push_back (e->clone_pattern ());
1261 // Overloaded assignment operator to vector clone
1262 TuplePatternItemsMultiple &operator= (TuplePatternItemsMultiple const &other)
1264 patterns.clear ();
1265 patterns.reserve (other.patterns.size ());
1266 for (const auto &e : other.patterns)
1267 patterns.push_back (e->clone_pattern ());
1269 return *this;
1272 // move constructors
1273 TuplePatternItemsMultiple (TuplePatternItemsMultiple &&other) = default;
1274 TuplePatternItemsMultiple &operator= (TuplePatternItemsMultiple &&other)
1275 = default;
1277 std::string as_string () const override;
1279 void accept_vis (ASTVisitor &vis) override;
1281 // TODO: seems kinda dodgy. Think of better way.
1282 std::vector<std::unique_ptr<Pattern>> &get_patterns () { return patterns; }
1283 const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
1285 return patterns;
1288 TuplePatternItemType get_pattern_type () const override
1290 return TuplePatternItemType::MULTIPLE;
1293 protected:
1294 /* Use covariance to implement clone function as returning this object rather
1295 * than base */
1296 TuplePatternItemsMultiple *clone_tuple_pattern_items_impl () const override
1298 return new TuplePatternItemsMultiple (*this);
1302 // Class representing TuplePattern patterns where there are a range of patterns
1303 class TuplePatternItemsRanged : public TuplePatternItems
1305 std::vector<std::unique_ptr<Pattern>> lower_patterns;
1306 std::vector<std::unique_ptr<Pattern>> upper_patterns;
1308 public:
1309 TuplePatternItemsRanged (std::vector<std::unique_ptr<Pattern>> lower_patterns,
1310 std::vector<std::unique_ptr<Pattern>> upper_patterns)
1311 : lower_patterns (std::move (lower_patterns)),
1312 upper_patterns (std::move (upper_patterns))
1315 // Copy constructor with vector clone
1316 TuplePatternItemsRanged (TuplePatternItemsRanged const &other)
1318 lower_patterns.reserve (other.lower_patterns.size ());
1319 for (const auto &e : other.lower_patterns)
1320 lower_patterns.push_back (e->clone_pattern ());
1322 upper_patterns.reserve (other.upper_patterns.size ());
1323 for (const auto &e : other.upper_patterns)
1324 upper_patterns.push_back (e->clone_pattern ());
1327 // Overloaded assignment operator to clone
1328 TuplePatternItemsRanged &operator= (TuplePatternItemsRanged const &other)
1330 lower_patterns.clear ();
1331 lower_patterns.reserve (other.lower_patterns.size ());
1332 for (const auto &e : other.lower_patterns)
1333 lower_patterns.push_back (e->clone_pattern ());
1335 upper_patterns.clear ();
1336 upper_patterns.reserve (other.upper_patterns.size ());
1337 for (const auto &e : other.upper_patterns)
1338 upper_patterns.push_back (e->clone_pattern ());
1340 return *this;
1343 // move constructors
1344 TuplePatternItemsRanged (TuplePatternItemsRanged &&other) = default;
1345 TuplePatternItemsRanged &operator= (TuplePatternItemsRanged &&other)
1346 = default;
1348 std::string as_string () const override;
1350 void accept_vis (ASTVisitor &vis) override;
1352 // TODO: seems kinda dodgy. Think of better way.
1353 std::vector<std::unique_ptr<Pattern>> &get_lower_patterns ()
1355 return lower_patterns;
1357 const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const
1359 return lower_patterns;
1362 // TODO: seems kinda dodgy. Think of better way.
1363 std::vector<std::unique_ptr<Pattern>> &get_upper_patterns ()
1365 return upper_patterns;
1367 const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const
1369 return upper_patterns;
1372 TuplePatternItemType get_pattern_type () const override
1374 return TuplePatternItemType::RANGED;
1377 protected:
1378 /* Use covariance to implement clone function as returning this object rather
1379 * than base */
1380 TuplePatternItemsRanged *clone_tuple_pattern_items_impl () const override
1382 return new TuplePatternItemsRanged (*this);
1386 // AST node representing a tuple pattern
1387 class TuplePattern : public Pattern
1389 std::unique_ptr<TuplePatternItems> items;
1390 location_t locus;
1391 NodeId node_id;
1393 public:
1394 std::string as_string () const override;
1396 TuplePattern (std::unique_ptr<TuplePatternItems> items, location_t locus)
1397 : items (std::move (items)), locus (locus),
1398 node_id (Analysis::Mappings::get ()->get_next_node_id ())
1400 rust_assert (this->items != nullptr);
1403 // Copy constructor requires clone
1404 TuplePattern (TuplePattern const &other) : locus (other.locus)
1406 // guard to prevent null dereference
1407 rust_assert (other.items != nullptr);
1409 node_id = other.node_id;
1410 items = other.items->clone_tuple_pattern_items ();
1413 // Overload assignment operator to clone
1414 TuplePattern &operator= (TuplePattern const &other)
1416 locus = other.locus;
1417 node_id = other.node_id;
1419 // guard to prevent null dereference
1420 rust_assert (other.items != nullptr);
1422 items = other.items->clone_tuple_pattern_items ();
1423 return *this;
1426 location_t get_locus () const override final { return locus; }
1428 void accept_vis (ASTVisitor &vis) override;
1430 // TODO: seems kinda dodgy. Think of better way.
1431 TuplePatternItems &get_items ()
1433 rust_assert (items != nullptr);
1434 return *items;
1437 NodeId get_node_id () const override { return node_id; }
1439 Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Tuple; }
1441 protected:
1442 /* Use covariance to implement clone function as returning this object rather
1443 * than base */
1444 TuplePattern *clone_pattern_impl () const override
1446 return new TuplePattern (*this);
1450 // AST node representing a pattern in parentheses, used to control precedence
1451 class GroupedPattern : public Pattern
1453 std::unique_ptr<Pattern> pattern_in_parens;
1454 location_t locus;
1455 NodeId node_id;
1457 public:
1458 std::string as_string () const override
1460 return "(" + pattern_in_parens->as_string () + ")";
1463 GroupedPattern (std::unique_ptr<Pattern> pattern_in_parens, location_t locus)
1464 : pattern_in_parens (std::move (pattern_in_parens)), locus (locus),
1465 node_id (Analysis::Mappings::get ()->get_next_node_id ())
1468 // Copy constructor uses clone
1469 GroupedPattern (GroupedPattern const &other)
1470 : pattern_in_parens (other.pattern_in_parens->clone_pattern ()),
1471 locus (other.locus), node_id (other.node_id)
1474 // Overload assignment operator to clone
1475 GroupedPattern &operator= (GroupedPattern const &other)
1477 pattern_in_parens = other.pattern_in_parens->clone_pattern ();
1478 locus = other.locus;
1479 node_id = other.node_id;
1481 return *this;
1484 // default move semantics
1485 GroupedPattern (GroupedPattern &&other) = default;
1486 GroupedPattern &operator= (GroupedPattern &&other) = default;
1488 location_t get_locus () const override final { return locus; }
1490 void accept_vis (ASTVisitor &vis) override;
1492 // TODO: seems kinda dodgy. Think of better way.
1493 Pattern &get_pattern_in_parens ()
1495 rust_assert (pattern_in_parens != nullptr);
1496 return *pattern_in_parens;
1499 NodeId get_node_id () const override { return node_id; }
1501 Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Grouped; }
1503 protected:
1504 /* Use covariance to implement clone function as returning this object rather
1505 * than base */
1506 GroupedPattern *clone_pattern_impl () const override
1508 return new GroupedPattern (*this);
1512 // AST node representing patterns that can match slices and arrays
1513 class SlicePattern : public Pattern
1515 std::vector<std::unique_ptr<Pattern>> items;
1516 location_t locus;
1517 NodeId node_id;
1519 public:
1520 std::string as_string () const override;
1522 SlicePattern (std::vector<std::unique_ptr<Pattern>> items, location_t locus)
1523 : items (std::move (items)), locus (locus),
1524 node_id (Analysis::Mappings::get ()->get_next_node_id ())
1527 // Copy constructor with vector clone
1528 SlicePattern (SlicePattern const &other) : locus (other.locus)
1530 node_id = other.node_id;
1531 items.reserve (other.items.size ());
1532 for (const auto &e : other.items)
1533 items.push_back (e->clone_pattern ());
1536 // Overloaded assignment operator to vector clone
1537 SlicePattern &operator= (SlicePattern const &other)
1539 locus = other.locus;
1540 node_id = other.node_id;
1542 items.clear ();
1543 items.reserve (other.items.size ());
1544 for (const auto &e : other.items)
1545 items.push_back (e->clone_pattern ());
1547 return *this;
1550 // move constructors
1551 SlicePattern (SlicePattern &&other) = default;
1552 SlicePattern &operator= (SlicePattern &&other) = default;
1554 location_t get_locus () const override final { return locus; }
1556 void accept_vis (ASTVisitor &vis) override;
1558 // TODO: seems kinda dodgy. Think of better way.
1559 std::vector<std::unique_ptr<Pattern>> &get_items () { return items; }
1560 const std::vector<std::unique_ptr<Pattern>> &get_items () const
1562 return items;
1565 NodeId get_node_id () const override { return node_id; }
1567 Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Slice; }
1569 protected:
1570 /* Use covariance to implement clone function as returning this object rather
1571 * than base */
1572 SlicePattern *clone_pattern_impl () const override
1574 return new SlicePattern (*this);
1578 // AST node for alternate patterns
1579 // joins together what are technically 'PatternNoTopAlt's
1580 class AltPattern : public Pattern
1582 std::vector<std::unique_ptr<Pattern>> alts;
1583 location_t locus;
1584 NodeId node_id;
1586 public:
1587 std::string as_string () const override;
1589 AltPattern (std::vector<std::unique_ptr<Pattern>> alts, location_t locus)
1590 : alts (std::move (alts)), locus (locus),
1591 node_id (Analysis::Mappings::get ()->get_next_node_id ())
1594 // Copy constructor with vector clone
1595 AltPattern (AltPattern const &other) : locus (other.locus)
1597 node_id = other.node_id;
1598 alts.reserve (other.alts.size ());
1599 for (const auto &e : other.alts)
1600 alts.push_back (e->clone_pattern ());
1603 // Overloaded assignment operator to vector clone
1604 AltPattern &operator= (AltPattern const &other)
1606 locus = other.locus;
1607 node_id = other.node_id;
1609 alts.clear ();
1610 alts.reserve (other.alts.size ());
1611 for (const auto &e : other.alts)
1612 alts.push_back (e->clone_pattern ());
1614 return *this;
1617 // move constructors
1618 AltPattern (AltPattern &&other) = default;
1619 AltPattern &operator= (AltPattern &&other) = default;
1621 location_t get_locus () const override final { return locus; }
1623 void accept_vis (ASTVisitor &vis) override;
1625 // TODO: seems kinda dodgy. Think of better way.
1626 std::vector<std::unique_ptr<Pattern>> &get_alts () { return alts; }
1627 const std::vector<std::unique_ptr<Pattern>> &get_alts () const
1629 return alts;
1632 NodeId get_node_id () const override { return node_id; }
1634 Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Alt; }
1636 protected:
1637 /* Use covariance to implement clone function as returning this object rather
1638 * than base */
1639 AltPattern *clone_pattern_impl () const override
1641 return new AltPattern (*this);
1645 // Moved definition to rust-path.h
1646 class PathPattern;
1648 // Forward decls for paths (defined in rust-path.h)
1649 class PathInExpression;
1650 class QualifiedPathInExpression;
1652 // Replaced with forward decl - defined in rust-macro.h
1653 class MacroInvocation;
1654 } // namespace AST
1655 } // namespace Rust
1657 #endif