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
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
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
26 // Literal pattern AST node (comparing to a literal)
27 class LiteralPattern
: public Pattern
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
; }
61 /* Use covariance to implement clone function as returning this object rather
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
;
77 std::unique_ptr
<Pattern
> to_bind
;
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; }
88 IdentifierPattern (Identifier ident
, location_t locus
, bool is_ref
= 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
),
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
;
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 ();
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 ());
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
;
160 /* Use covariance to implement clone function as returning this object rather
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
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
; }
190 /* Use covariance to implement clone function as returning this object rather
192 WildcardPattern
*clone_pattern_impl () const override
194 return new WildcardPattern (*this);
198 class RestPattern
: public Pattern
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
; }
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
229 enum RangePatternBoundType
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;
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
260 /* Can only be a char, byte, int, or float literal - same impl here as
263 // Minus prefixed to literal (if integer or floating-point)
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
;
291 /* Use covariance to implement clone function as returning this object rather
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? */
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
;
326 /* Use covariance to implement clone function as returning this object rather
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? */
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
;
363 /* Use covariance to implement clone function as returning this object rather
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 */
385 std::string
as_string () const override
;
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
;
411 node_id
= other
.node_id
;
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);
437 RangePatternBound
&get_upper_bound ()
439 rust_assert (upper
!= nullptr);
443 NodeId
get_node_id () const override
{ return node_id
; }
445 Pattern::Kind
get_pattern_kind () override
{ return Pattern::Kind::Range
; }
448 /* Use covariance to implement clone function as returning this object rather
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
461 std::unique_ptr
<Pattern
> pattern
;
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
;
489 node_id
= other
.node_id
;
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);
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
;
521 /* Use covariance to implement clone function as returning this object rather
523 ReferencePattern
*clone_pattern_impl () const override
525 return new ReferencePattern (*this);
530 // aka StructPatternEtCetera; potential element in struct pattern
531 struct StructPatternEtc
534 std::vector
<Attribute
> outer_attrs
;
536 // should this store location data?
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
> ());
551 // Base class for a single field in a struct pattern - abstract
552 class StructPatternField
554 std::vector
<Attribute
> outer_attrs
;
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
; }
594 StructPatternField (std::vector
<Attribute
> outer_attribs
, location_t locus
,
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
607 std::unique_ptr
<Pattern
> tuple_pattern
;
610 StructPatternFieldTuplePat (TupleIndex index
,
611 std::unique_ptr
<Pattern
> tuple_pattern
,
612 std::vector
<Attribute
> outer_attribs
,
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
);
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 ();
642 tuple_pattern
= nullptr;
647 // default move semantics
648 StructPatternFieldTuplePat (StructPatternFieldTuplePat
&&other
) = default;
649 StructPatternFieldTuplePat
&operator= (StructPatternFieldTuplePat
&&other
)
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
; }
675 /* Use covariance to implement clone function as returning this object rather
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
687 std::unique_ptr
<Pattern
> ident_pattern
;
690 StructPatternFieldIdentPat (Identifier ident
,
691 std::unique_ptr
<Pattern
> ident_pattern
,
692 std::vector
<Attribute
> outer_attrs
,
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
);
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 ();
722 ident_pattern
= nullptr;
727 // default move semantics
728 StructPatternFieldIdentPat (StructPatternFieldIdentPat
&&other
) = default;
729 StructPatternFieldIdentPat
&operator= (StructPatternFieldIdentPat
&&other
)
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
; }
755 /* Use covariance to implement clone function as returning this object rather
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
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
; }
795 /* Use covariance to implement clone function as returning this object rather
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?
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,
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
;
862 fields
.reserve (other
.fields
.size ());
863 for (const auto &e
: other
.fields
)
864 fields
.push_back (e
->clone_struct_pattern_field ());
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 ()
887 const std::vector
<std::unique_ptr
<StructPatternField
>> &
888 get_struct_pattern_fields () const
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
;
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
;
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
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
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
; }
958 /* Use covariance to implement clone function as returning this object rather
960 StructPattern
*clone_pattern_impl () const override
962 return new StructPattern (*this);
966 // Base abstract class for patterns used in TupleStructPattern
967 class TupleStructItems
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;
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
;
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
)
1019 patterns
.reserve (other
.patterns
.size ());
1020 for (const auto &e
: other
.patterns
)
1021 patterns
.push_back (e
->clone_pattern ());
1026 // move constructors
1027 TupleStructItemsNoRange (TupleStructItemsNoRange
&&other
) = default;
1028 TupleStructItemsNoRange
&operator= (TupleStructItemsNoRange
&&other
)
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
1042 ItemType
get_item_type () const override final
{ return ItemType::NO_RANGE
; }
1045 /* Use covariance to implement clone function as returning this object rather
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
;
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 ());
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
; }
1125 /* Use covariance to implement clone function as returning this object rather
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
;
1140 /* TOOD: should this store location data? current accessor uses path location
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
)
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 ();
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);
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
;
1203 /* Use covariance to implement clone function as returning this object rather
1205 TupleStructPattern
*clone_pattern_impl () const override
1207 return new TupleStructPattern (*this);
1211 // Base abstract class representing TuplePattern patterns
1212 class TuplePatternItems
1215 enum TuplePatternItemType
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;
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
;
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
)
1265 patterns
.reserve (other
.patterns
.size ());
1266 for (const auto &e
: other
.patterns
)
1267 patterns
.push_back (e
->clone_pattern ());
1272 // move constructors
1273 TuplePatternItemsMultiple (TuplePatternItemsMultiple
&&other
) = default;
1274 TuplePatternItemsMultiple
&operator= (TuplePatternItemsMultiple
&&other
)
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
1288 TuplePatternItemType
get_pattern_type () const override
1290 return TuplePatternItemType::MULTIPLE
;
1294 /* Use covariance to implement clone function as returning this object rather
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
;
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 ());
1343 // move constructors
1344 TuplePatternItemsRanged (TuplePatternItemsRanged
&&other
) = default;
1345 TuplePatternItemsRanged
&operator= (TuplePatternItemsRanged
&&other
)
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
;
1378 /* Use covariance to implement clone function as returning this object rather
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
;
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 ();
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);
1437 NodeId
get_node_id () const override
{ return node_id
; }
1439 Pattern::Kind
get_pattern_kind () override
{ return Pattern::Kind::Tuple
; }
1442 /* Use covariance to implement clone function as returning this object rather
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
;
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
;
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
; }
1504 /* Use covariance to implement clone function as returning this object rather
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
;
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
;
1543 items
.reserve (other
.items
.size ());
1544 for (const auto &e
: other
.items
)
1545 items
.push_back (e
->clone_pattern ());
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
1565 NodeId
get_node_id () const override
{ return node_id
; }
1567 Pattern::Kind
get_pattern_kind () override
{ return Pattern::Kind::Slice
; }
1570 /* Use covariance to implement clone function as returning this object rather
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
;
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
;
1610 alts
.reserve (other
.alts
.size ());
1611 for (const auto &e
: other
.alts
)
1612 alts
.push_back (e
->clone_pattern ());
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
1632 NodeId
get_node_id () const override
{ return node_id
; }
1634 Pattern::Kind
get_pattern_kind () override
{ return Pattern::Kind::Alt
; }
1637 /* Use covariance to implement clone function as returning this object rather
1639 AltPattern
*clone_pattern_impl () const override
1641 return new AltPattern (*this);
1645 // Moved definition to rust-path.h
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
;