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);
379 tokenid_to_rangekind (TokenId id
);
380 // AST node for matching within a certain range (range pattern)
381 class RangePattern
: public Pattern
383 std::unique_ptr
<RangePatternBound
> lower
;
384 std::unique_ptr
<RangePatternBound
> upper
;
386 RangeKind range_kind
;
388 /* location only stored to avoid a dereference - lower pattern should give
389 * correct location so maybe change in future */
394 std::string
as_string () const override
;
397 RangePattern (std::unique_ptr
<RangePatternBound
> lower
,
398 std::unique_ptr
<RangePatternBound
> upper
, RangeKind range_kind
,
400 : lower (std::move (lower
)), upper (std::move (upper
)),
401 range_kind (range_kind
), locus (locus
),
402 node_id (Analysis::Mappings::get ().get_next_node_id ())
405 // Copy constructor with clone
406 RangePattern (RangePattern
const &other
)
407 : lower (other
.lower
->clone_range_pattern_bound ()),
408 upper (other
.upper
->clone_range_pattern_bound ()),
409 range_kind (other
.range_kind
), locus (other
.locus
),
410 node_id (other
.node_id
)
413 // Overloaded assignment operator to clone
414 RangePattern
&operator= (RangePattern
const &other
)
416 lower
= other
.lower
->clone_range_pattern_bound ();
417 upper
= other
.upper
->clone_range_pattern_bound ();
418 range_kind
= other
.range_kind
;
420 node_id
= other
.node_id
;
425 // default move semantics
426 RangePattern (RangePattern
&&other
) = default;
427 RangePattern
&operator= (RangePattern
&&other
) = default;
429 location_t
get_locus () const override final
{ return locus
; }
431 bool get_has_ellipsis_syntax () const
433 return range_kind
== RangeKind::ELLIPSIS
;
436 RangeKind
get_range_kind () const { return range_kind
; }
438 bool get_has_lower_bound () const { return lower
!= nullptr; }
440 bool get_has_upper_bound () const { return upper
!= nullptr; }
442 void accept_vis (ASTVisitor
&vis
) override
;
444 // TODO: is this better? or is a "vis_bound" better?
445 RangePatternBound
&get_lower_bound ()
447 rust_assert (lower
!= nullptr);
451 RangePatternBound
&get_upper_bound ()
453 rust_assert (upper
!= nullptr);
457 NodeId
get_node_id () const override
{ return node_id
; }
459 Pattern::Kind
get_pattern_kind () override
{ return Pattern::Kind::Range
; }
462 /* Use covariance to implement clone function as returning this object rather
464 RangePattern
*clone_pattern_impl () const override
466 return new RangePattern (*this);
470 // AST node for pattern based on dereferencing the pointers given
471 class ReferencePattern
: public Pattern
475 std::unique_ptr
<Pattern
> pattern
;
480 std::string
as_string () const override
;
482 ReferencePattern (std::unique_ptr
<Pattern
> pattern
, bool is_mut_reference
,
483 bool ref_has_two_amps
, location_t locus
)
484 : has_two_amps (ref_has_two_amps
), is_mut (is_mut_reference
),
485 pattern (std::move (pattern
)), locus (locus
),
486 node_id (Analysis::Mappings::get ().get_next_node_id ())
489 // Copy constructor requires clone
490 ReferencePattern (ReferencePattern
const &other
)
491 : has_two_amps (other
.has_two_amps
), is_mut (other
.is_mut
),
492 pattern (other
.pattern
->clone_pattern ()), locus (other
.locus
),
493 node_id (other
.node_id
)
496 // Overload assignment operator to clone
497 ReferencePattern
&operator= (ReferencePattern
const &other
)
499 pattern
= other
.pattern
->clone_pattern ();
500 is_mut
= other
.is_mut
;
501 has_two_amps
= other
.has_two_amps
;
503 node_id
= other
.node_id
;
508 // default move semantics
509 ReferencePattern (ReferencePattern
&&other
) = default;
510 ReferencePattern
&operator= (ReferencePattern
&&other
) = default;
512 location_t
get_locus () const override final
{ return locus
; }
514 void accept_vis (ASTVisitor
&vis
) override
;
516 // TODO: is this better? Or is a "vis_pattern" better?
517 Pattern
&get_referenced_pattern ()
519 rust_assert (pattern
!= nullptr);
523 bool is_double_reference () const { return has_two_amps
; }
525 bool get_is_mut () const { return is_mut
; }
527 NodeId
get_node_id () const override
{ return node_id
; }
529 Pattern::Kind
get_pattern_kind () override
531 return Pattern::Kind::Reference
;
535 /* Use covariance to implement clone function as returning this object rather
537 ReferencePattern
*clone_pattern_impl () const override
539 return new ReferencePattern (*this);
544 // aka StructPatternEtCetera; potential element in struct pattern
545 struct StructPatternEtc
548 std::vector
<Attribute
> outer_attrs
;
550 // should this store location data?
553 StructPatternEtc (std::vector
<Attribute
> outer_attribs
)
554 : outer_attrs (std::move (outer_attribs
))
557 // Creates an empty StructPatternEtc
558 static StructPatternEtc
create_empty ()
560 return StructPatternEtc (std::vector
<Attribute
> ());
565 // Base class for a single field in a struct pattern - abstract
566 class StructPatternField
568 std::vector
<Attribute
> outer_attrs
;
582 virtual ~StructPatternField () {}
584 // Unique pointer custom clone function
585 std::unique_ptr
<StructPatternField
> clone_struct_pattern_field () const
587 return std::unique_ptr
<StructPatternField
> (
588 clone_struct_pattern_field_impl ());
591 virtual std::string
as_string () const;
593 location_t
get_locus () const { return locus
; }
595 virtual void accept_vis (ASTVisitor
&vis
) = 0;
597 virtual void mark_for_strip () = 0;
598 virtual bool is_marked_for_strip () const = 0;
599 virtual ItemType
get_item_type () const = 0;
601 NodeId
get_node_id () const { return node_id
; }
603 // TODO: seems kinda dodgy. Think of better way.
604 std::vector
<Attribute
> &get_outer_attrs () { return outer_attrs
; }
605 const std::vector
<Attribute
> &get_outer_attrs () const { return outer_attrs
; }
608 StructPatternField (std::vector
<Attribute
> outer_attribs
, location_t locus
,
610 : outer_attrs (std::move (outer_attribs
)), locus (locus
), node_id (node_id
)
613 // Clone function implementation as pure virtual method
614 virtual StructPatternField
*clone_struct_pattern_field_impl () const = 0;
617 // Tuple pattern single field in a struct pattern
618 class StructPatternFieldTuplePat
: public StructPatternField
621 std::unique_ptr
<Pattern
> tuple_pattern
;
624 StructPatternFieldTuplePat (TupleIndex index
,
625 std::unique_ptr
<Pattern
> tuple_pattern
,
626 std::vector
<Attribute
> outer_attribs
,
628 : StructPatternField (std::move (outer_attribs
), locus
,
629 Analysis::Mappings::get ().get_next_node_id ()),
630 index (index
), tuple_pattern (std::move (tuple_pattern
))
633 // Copy constructor requires clone
634 StructPatternFieldTuplePat (StructPatternFieldTuplePat
const &other
)
635 : StructPatternField (other
), index (other
.index
)
637 // guard to prevent null dereference (only required if error state)
638 node_id
= other
.get_node_id ();
639 if (other
.tuple_pattern
!= nullptr)
640 tuple_pattern
= other
.tuple_pattern
->clone_pattern ();
643 // Overload assignment operator to perform clone
644 StructPatternFieldTuplePat
&
645 operator= (StructPatternFieldTuplePat
const &other
)
647 StructPatternField::operator= (other
);
649 // outer_attrs = other.outer_attrs;
650 node_id
= other
.get_node_id ();
652 // guard to prevent null dereference (only required if error state)
653 if (other
.tuple_pattern
!= nullptr)
654 tuple_pattern
= other
.tuple_pattern
->clone_pattern ();
656 tuple_pattern
= nullptr;
661 // default move semantics
662 StructPatternFieldTuplePat (StructPatternFieldTuplePat
&&other
) = default;
663 StructPatternFieldTuplePat
&operator= (StructPatternFieldTuplePat
&&other
)
666 std::string
as_string () const override
;
668 void accept_vis (ASTVisitor
&vis
) override
;
670 // based on idea of tuple pattern no longer existing
671 void mark_for_strip () override
{ tuple_pattern
= nullptr; }
672 bool is_marked_for_strip () const override
674 return tuple_pattern
== nullptr;
677 TupleIndex
get_index () { return index
; }
679 // TODO: is this better? Or is a "vis_pattern" better?
680 Pattern
&get_index_pattern ()
682 rust_assert (tuple_pattern
!= nullptr);
683 return *tuple_pattern
;
686 ItemType
get_item_type () const override final
{ return ItemType::TUPLE_PAT
; }
689 /* Use covariance to implement clone function as returning this object rather
691 StructPatternFieldTuplePat
*clone_struct_pattern_field_impl () const override
693 return new StructPatternFieldTuplePat (*this);
697 // Identifier pattern single field in a struct pattern
698 class StructPatternFieldIdentPat
: public StructPatternField
701 std::unique_ptr
<Pattern
> ident_pattern
;
704 StructPatternFieldIdentPat (Identifier ident
,
705 std::unique_ptr
<Pattern
> ident_pattern
,
706 std::vector
<Attribute
> outer_attrs
,
708 : StructPatternField (std::move (outer_attrs
), locus
,
709 Analysis::Mappings::get ().get_next_node_id ()),
710 ident (std::move (ident
)), ident_pattern (std::move (ident_pattern
))
713 // Copy constructor requires clone
714 StructPatternFieldIdentPat (StructPatternFieldIdentPat
const &other
)
715 : StructPatternField (other
), ident (other
.ident
)
717 // guard to prevent null dereference (only required if error state)
718 node_id
= other
.get_node_id ();
719 if (other
.ident_pattern
!= nullptr)
720 ident_pattern
= other
.ident_pattern
->clone_pattern ();
723 // Overload assignment operator to clone
724 StructPatternFieldIdentPat
&
725 operator= (StructPatternFieldIdentPat
const &other
)
727 StructPatternField::operator= (other
);
729 // outer_attrs = other.outer_attrs;
730 node_id
= other
.get_node_id ();
732 // guard to prevent null dereference (only required if error state)
733 if (other
.ident_pattern
!= nullptr)
734 ident_pattern
= other
.ident_pattern
->clone_pattern ();
736 ident_pattern
= nullptr;
741 // default move semantics
742 StructPatternFieldIdentPat (StructPatternFieldIdentPat
&&other
) = default;
743 StructPatternFieldIdentPat
&operator= (StructPatternFieldIdentPat
&&other
)
746 std::string
as_string () const override
;
748 void accept_vis (ASTVisitor
&vis
) override
;
750 // based on idea of identifier pattern no longer existing
751 void mark_for_strip () override
{ ident_pattern
= nullptr; }
752 bool is_marked_for_strip () const override
754 return ident_pattern
== nullptr;
757 const Identifier
&get_identifier () const { return ident
; }
759 // TODO: is this better? Or is a "vis_pattern" better?
760 Pattern
&get_ident_pattern ()
762 rust_assert (ident_pattern
!= nullptr);
763 return *ident_pattern
;
766 ItemType
get_item_type () const override final
{ return ItemType::IDENT_PAT
; }
769 /* Use covariance to implement clone function as returning this object rather
771 StructPatternFieldIdentPat
*clone_struct_pattern_field_impl () const override
773 return new StructPatternFieldIdentPat (*this);
777 // Identifier only (with no pattern) single field in a struct pattern
778 class StructPatternFieldIdent
: public StructPatternField
785 StructPatternFieldIdent (Identifier ident
, bool is_ref
, bool is_mut
,
786 std::vector
<Attribute
> outer_attrs
, location_t locus
)
787 : StructPatternField (std::move (outer_attrs
), locus
,
788 Analysis::Mappings::get ().get_next_node_id ()),
789 has_ref (is_ref
), has_mut (is_mut
), ident (std::move (ident
))
792 std::string
as_string () const override
;
794 void accept_vis (ASTVisitor
&vis
) override
;
796 // based on idea of identifier no longer existing
797 void mark_for_strip () override
{ ident
= {""}; }
798 bool is_marked_for_strip () const override
{ return ident
.empty (); }
800 const Identifier
&get_identifier () const { return ident
; }
802 ItemType
get_item_type () const override final
{ return ItemType::IDENT
; }
804 bool is_ref () const { return has_ref
; }
806 bool is_mut () const { return has_mut
; }
809 /* Use covariance to implement clone function as returning this object rather
811 StructPatternFieldIdent
*clone_struct_pattern_field_impl () const override
813 return new StructPatternFieldIdent (*this);
817 // Elements of a struct pattern
818 class StructPatternElements
820 // bool has_struct_pattern_fields;
821 std::vector
<std::unique_ptr
<StructPatternField
>> fields
;
823 bool has_struct_pattern_etc
;
824 std::vector
<Attribute
> struct_pattern_etc_attrs
;
825 // StructPatternEtc etc;
827 // must have at least one of the two and maybe both
829 // should this store location data?
832 // Returns whether there are any struct pattern fields
833 bool has_struct_pattern_fields () const { return !fields
.empty (); }
835 /* Returns whether the struct pattern elements is entirely empty (no fields,
837 bool is_empty () const
839 return !has_struct_pattern_fields () && !has_struct_pattern_etc
;
842 bool has_etc () const { return has_struct_pattern_etc
; }
844 // Constructor for StructPatternElements with both (potentially)
845 StructPatternElements (
846 std::vector
<std::unique_ptr
<StructPatternField
>> fields
,
847 std::vector
<Attribute
> etc_attrs
)
848 : fields (std::move (fields
)), has_struct_pattern_etc (true),
849 struct_pattern_etc_attrs (std::move (etc_attrs
))
852 // Constructor for StructPatternElements with no StructPatternEtc
853 StructPatternElements (
854 std::vector
<std::unique_ptr
<StructPatternField
>> fields
)
855 : fields (std::move (fields
)), has_struct_pattern_etc (false),
856 struct_pattern_etc_attrs ()
859 // Copy constructor with vector clone
860 StructPatternElements (StructPatternElements
const &other
)
861 : has_struct_pattern_etc (other
.has_struct_pattern_etc
),
862 struct_pattern_etc_attrs (other
.struct_pattern_etc_attrs
)
864 fields
.reserve (other
.fields
.size ());
865 for (const auto &e
: other
.fields
)
866 fields
.push_back (e
->clone_struct_pattern_field ());
869 // Overloaded assignment operator with vector clone
870 StructPatternElements
&operator= (StructPatternElements
const &other
)
872 struct_pattern_etc_attrs
= other
.struct_pattern_etc_attrs
;
873 has_struct_pattern_etc
= other
.has_struct_pattern_etc
;
876 fields
.reserve (other
.fields
.size ());
877 for (const auto &e
: other
.fields
)
878 fields
.push_back (e
->clone_struct_pattern_field ());
884 StructPatternElements (StructPatternElements
&&other
) = default;
885 StructPatternElements
&operator= (StructPatternElements
&&other
) = default;
887 // Creates an empty StructPatternElements
888 static StructPatternElements
create_empty ()
890 return StructPatternElements (
891 std::vector
<std::unique_ptr
<StructPatternField
>> ());
894 std::string
as_string () const;
896 // TODO: seems kinda dodgy. Think of better way.
897 std::vector
<std::unique_ptr
<StructPatternField
>> &get_struct_pattern_fields ()
901 const std::vector
<std::unique_ptr
<StructPatternField
>> &
902 get_struct_pattern_fields () const
907 std::vector
<Attribute
> &get_etc_outer_attrs ()
909 return struct_pattern_etc_attrs
;
911 const std::vector
<Attribute
> &get_etc_outer_attrs () const
913 return struct_pattern_etc_attrs
;
918 has_struct_pattern_etc
= false;
919 struct_pattern_etc_attrs
.clear ();
920 struct_pattern_etc_attrs
.shrink_to_fit ();
924 // Struct pattern AST node representation
925 class StructPattern
: public Pattern
927 PathInExpression path
;
929 // bool has_struct_pattern_elements;
930 StructPatternElements elems
;
936 std::string
as_string () const override
;
938 // Constructs a struct pattern from specified StructPatternElements
939 StructPattern (PathInExpression struct_path
, location_t locus
,
940 StructPatternElements elems
941 = StructPatternElements::create_empty ())
942 : path (std::move (struct_path
)), elems (std::move (elems
)),
943 node_id (Analysis::Mappings::get ().get_next_node_id ()), locus (locus
)
946 /* TODO: constructor to construct via elements included in
947 * StructPatternElements */
949 /* Returns whether struct pattern has any struct pattern elements (if not, it
951 bool has_struct_pattern_elems () const { return !elems
.is_empty (); }
953 location_t
get_locus () const override
{ return path
.get_locus (); }
955 void accept_vis (ASTVisitor
&vis
) override
;
957 // TODO: seems kinda dodgy. Think of better way.
958 StructPatternElements
&get_struct_pattern_elems () { return elems
; }
959 const StructPatternElements
&get_struct_pattern_elems () const
964 PathInExpression
&get_path () { return path
; }
965 const PathInExpression
&get_path () const { return path
; }
967 NodeId
get_node_id () const override
{ return node_id
; }
969 Pattern::Kind
get_pattern_kind () override
{ return Pattern::Kind::Struct
; }
972 /* Use covariance to implement clone function as returning this object rather
974 StructPattern
*clone_pattern_impl () const override
976 return new StructPattern (*this);
980 // Base abstract class for patterns used in TupleStructPattern
981 class TupleStructItems
990 virtual ~TupleStructItems () {}
992 // TODO: should this store location data?
994 // Unique pointer custom clone function
995 std::unique_ptr
<TupleStructItems
> clone_tuple_struct_items () const
997 return std::unique_ptr
<TupleStructItems
> (clone_tuple_struct_items_impl ());
1000 virtual std::string
as_string () const = 0;
1002 virtual void accept_vis (ASTVisitor
&vis
) = 0;
1004 virtual ItemType
get_item_type () const = 0;
1007 // pure virtual clone implementation
1008 virtual TupleStructItems
*clone_tuple_struct_items_impl () const = 0;
1011 // Class for non-ranged tuple struct pattern patterns
1012 class TupleStructItemsNoRange
: public TupleStructItems
1014 std::vector
<std::unique_ptr
<Pattern
>> patterns
;
1017 TupleStructItemsNoRange (std::vector
<std::unique_ptr
<Pattern
>> patterns
)
1018 : patterns (std::move (patterns
))
1021 // Copy constructor with vector clone
1022 TupleStructItemsNoRange (TupleStructItemsNoRange
const &other
)
1024 patterns
.reserve (other
.patterns
.size ());
1025 for (const auto &e
: other
.patterns
)
1026 patterns
.push_back (e
->clone_pattern ());
1029 // Overloaded assignment operator with vector clone
1030 TupleStructItemsNoRange
&operator= (TupleStructItemsNoRange
const &other
)
1033 patterns
.reserve (other
.patterns
.size ());
1034 for (const auto &e
: other
.patterns
)
1035 patterns
.push_back (e
->clone_pattern ());
1040 // move constructors
1041 TupleStructItemsNoRange (TupleStructItemsNoRange
&&other
) = default;
1042 TupleStructItemsNoRange
&operator= (TupleStructItemsNoRange
&&other
)
1045 std::string
as_string () const override
;
1047 void accept_vis (ASTVisitor
&vis
) override
;
1049 // TODO: seems kinda dodgy. Think of better way.
1050 std::vector
<std::unique_ptr
<Pattern
>> &get_patterns () { return patterns
; }
1051 const std::vector
<std::unique_ptr
<Pattern
>> &get_patterns () const
1056 ItemType
get_item_type () const override final
{ return ItemType::NO_RANGE
; }
1059 /* Use covariance to implement clone function as returning this object rather
1061 TupleStructItemsNoRange
*clone_tuple_struct_items_impl () const override
1063 return new TupleStructItemsNoRange (*this);
1067 // Class for ranged tuple struct pattern patterns
1068 class TupleStructItemsRange
: public TupleStructItems
1070 std::vector
<std::unique_ptr
<Pattern
>> lower_patterns
;
1071 std::vector
<std::unique_ptr
<Pattern
>> upper_patterns
;
1074 TupleStructItemsRange (std::vector
<std::unique_ptr
<Pattern
>> lower_patterns
,
1075 std::vector
<std::unique_ptr
<Pattern
>> upper_patterns
)
1076 : lower_patterns (std::move (lower_patterns
)),
1077 upper_patterns (std::move (upper_patterns
))
1080 // Copy constructor with vector clone
1081 TupleStructItemsRange (TupleStructItemsRange
const &other
)
1083 lower_patterns
.reserve (other
.lower_patterns
.size ());
1084 for (const auto &e
: other
.lower_patterns
)
1085 lower_patterns
.push_back (e
->clone_pattern ());
1087 upper_patterns
.reserve (other
.upper_patterns
.size ());
1088 for (const auto &e
: other
.upper_patterns
)
1089 upper_patterns
.push_back (e
->clone_pattern ());
1092 // Overloaded assignment operator to clone
1093 TupleStructItemsRange
&operator= (TupleStructItemsRange
const &other
)
1095 lower_patterns
.clear ();
1096 lower_patterns
.reserve (other
.lower_patterns
.size ());
1097 for (const auto &e
: other
.lower_patterns
)
1098 lower_patterns
.push_back (e
->clone_pattern ());
1100 upper_patterns
.clear ();
1101 upper_patterns
.reserve (other
.upper_patterns
.size ());
1102 for (const auto &e
: other
.upper_patterns
)
1103 upper_patterns
.push_back (e
->clone_pattern ());
1108 // move constructors
1109 TupleStructItemsRange (TupleStructItemsRange
&&other
) = default;
1110 TupleStructItemsRange
&operator= (TupleStructItemsRange
&&other
) = default;
1112 std::string
as_string () const override
;
1114 void accept_vis (ASTVisitor
&vis
) override
;
1116 // TODO: seems kinda dodgy. Think of better way.
1117 std::vector
<std::unique_ptr
<Pattern
>> &get_lower_patterns ()
1119 return lower_patterns
;
1121 const std::vector
<std::unique_ptr
<Pattern
>> &get_lower_patterns () const
1123 return lower_patterns
;
1126 // TODO: seems kinda dodgy. Think of better way.
1127 std::vector
<std::unique_ptr
<Pattern
>> &get_upper_patterns ()
1129 return upper_patterns
;
1131 const std::vector
<std::unique_ptr
<Pattern
>> &get_upper_patterns () const
1133 return upper_patterns
;
1136 ItemType
get_item_type () const override final
{ return ItemType::RANGE
; }
1139 /* Use covariance to implement clone function as returning this object rather
1141 TupleStructItemsRange
*clone_tuple_struct_items_impl () const override
1143 return new TupleStructItemsRange (*this);
1147 // AST node representing a tuple struct pattern
1148 class TupleStructPattern
: public Pattern
1150 PathInExpression path
;
1151 std::unique_ptr
<TupleStructItems
> items
;
1154 /* TOOD: should this store location data? current accessor uses path location
1158 std::string
as_string () const override
;
1160 TupleStructPattern (PathInExpression tuple_struct_path
,
1161 std::unique_ptr
<TupleStructItems
> items
)
1162 : path (std::move (tuple_struct_path
)), items (std::move (items
)),
1163 node_id (Analysis::Mappings::get ().get_next_node_id ())
1165 rust_assert (this->items
!= nullptr);
1168 // Copy constructor required to clone
1169 TupleStructPattern (TupleStructPattern
const &other
) : path (other
.path
)
1171 // guard to protect from null dereference
1172 rust_assert (other
.items
!= nullptr);
1174 node_id
= other
.node_id
;
1175 items
= other
.items
->clone_tuple_struct_items ();
1178 // Operator overload assignment operator to clone
1179 TupleStructPattern
&operator= (TupleStructPattern
const &other
)
1182 node_id
= other
.node_id
;
1184 // guard to protect from null dereference
1185 rust_assert (other
.items
!= nullptr);
1187 items
= other
.items
->clone_tuple_struct_items ();
1192 // move constructors
1193 TupleStructPattern (TupleStructPattern
&&other
) = default;
1194 TupleStructPattern
&operator= (TupleStructPattern
&&other
) = default;
1196 location_t
get_locus () const override
{ return path
.get_locus (); }
1198 void accept_vis (ASTVisitor
&vis
) override
;
1200 TupleStructItems
&get_items ()
1202 rust_assert (items
!= nullptr);
1206 PathInExpression
&get_path () { return path
; }
1207 const PathInExpression
&get_path () const { return path
; }
1209 NodeId
get_node_id () const override
{ return node_id
; }
1211 Pattern::Kind
get_pattern_kind () override
1213 return Pattern::Kind::TupleStruct
;
1217 /* Use covariance to implement clone function as returning this object rather
1219 TupleStructPattern
*clone_pattern_impl () const override
1221 return new TupleStructPattern (*this);
1225 // Base abstract class representing TuplePattern patterns
1226 class TuplePatternItems
1229 enum TuplePatternItemType
1235 virtual ~TuplePatternItems () {}
1237 // TODO: should this store location data?
1239 // Unique pointer custom clone function
1240 std::unique_ptr
<TuplePatternItems
> clone_tuple_pattern_items () const
1242 return std::unique_ptr
<TuplePatternItems
> (
1243 clone_tuple_pattern_items_impl ());
1246 virtual std::string
as_string () const = 0;
1248 virtual void accept_vis (ASTVisitor
&vis
) = 0;
1250 virtual TuplePatternItemType
get_pattern_type () const = 0;
1253 // pure virtual clone implementation
1254 virtual TuplePatternItems
*clone_tuple_pattern_items_impl () const = 0;
1257 // Class representing TuplePattern patterns where there are multiple patterns
1258 class TuplePatternItemsMultiple
: public TuplePatternItems
1260 std::vector
<std::unique_ptr
<Pattern
>> patterns
;
1263 TuplePatternItemsMultiple (std::vector
<std::unique_ptr
<Pattern
>> patterns
)
1264 : patterns (std::move (patterns
))
1267 // Copy constructor with vector clone
1268 TuplePatternItemsMultiple (TuplePatternItemsMultiple
const &other
)
1270 patterns
.reserve (other
.patterns
.size ());
1271 for (const auto &e
: other
.patterns
)
1272 patterns
.push_back (e
->clone_pattern ());
1275 // Overloaded assignment operator to vector clone
1276 TuplePatternItemsMultiple
&operator= (TuplePatternItemsMultiple
const &other
)
1279 patterns
.reserve (other
.patterns
.size ());
1280 for (const auto &e
: other
.patterns
)
1281 patterns
.push_back (e
->clone_pattern ());
1286 // move constructors
1287 TuplePatternItemsMultiple (TuplePatternItemsMultiple
&&other
) = default;
1288 TuplePatternItemsMultiple
&operator= (TuplePatternItemsMultiple
&&other
)
1291 std::string
as_string () const override
;
1293 void accept_vis (ASTVisitor
&vis
) override
;
1295 // TODO: seems kinda dodgy. Think of better way.
1296 std::vector
<std::unique_ptr
<Pattern
>> &get_patterns () { return patterns
; }
1297 const std::vector
<std::unique_ptr
<Pattern
>> &get_patterns () const
1302 TuplePatternItemType
get_pattern_type () const override
1304 return TuplePatternItemType::MULTIPLE
;
1308 /* Use covariance to implement clone function as returning this object rather
1310 TuplePatternItemsMultiple
*clone_tuple_pattern_items_impl () const override
1312 return new TuplePatternItemsMultiple (*this);
1316 // Class representing TuplePattern patterns where there are a range of patterns
1317 class TuplePatternItemsRanged
: public TuplePatternItems
1319 std::vector
<std::unique_ptr
<Pattern
>> lower_patterns
;
1320 std::vector
<std::unique_ptr
<Pattern
>> upper_patterns
;
1323 TuplePatternItemsRanged (std::vector
<std::unique_ptr
<Pattern
>> lower_patterns
,
1324 std::vector
<std::unique_ptr
<Pattern
>> upper_patterns
)
1325 : lower_patterns (std::move (lower_patterns
)),
1326 upper_patterns (std::move (upper_patterns
))
1329 // Copy constructor with vector clone
1330 TuplePatternItemsRanged (TuplePatternItemsRanged
const &other
)
1332 lower_patterns
.reserve (other
.lower_patterns
.size ());
1333 for (const auto &e
: other
.lower_patterns
)
1334 lower_patterns
.push_back (e
->clone_pattern ());
1336 upper_patterns
.reserve (other
.upper_patterns
.size ());
1337 for (const auto &e
: other
.upper_patterns
)
1338 upper_patterns
.push_back (e
->clone_pattern ());
1341 // Overloaded assignment operator to clone
1342 TuplePatternItemsRanged
&operator= (TuplePatternItemsRanged
const &other
)
1344 lower_patterns
.clear ();
1345 lower_patterns
.reserve (other
.lower_patterns
.size ());
1346 for (const auto &e
: other
.lower_patterns
)
1347 lower_patterns
.push_back (e
->clone_pattern ());
1349 upper_patterns
.clear ();
1350 upper_patterns
.reserve (other
.upper_patterns
.size ());
1351 for (const auto &e
: other
.upper_patterns
)
1352 upper_patterns
.push_back (e
->clone_pattern ());
1357 // move constructors
1358 TuplePatternItemsRanged (TuplePatternItemsRanged
&&other
) = default;
1359 TuplePatternItemsRanged
&operator= (TuplePatternItemsRanged
&&other
)
1362 std::string
as_string () const override
;
1364 void accept_vis (ASTVisitor
&vis
) override
;
1366 // TODO: seems kinda dodgy. Think of better way.
1367 std::vector
<std::unique_ptr
<Pattern
>> &get_lower_patterns ()
1369 return lower_patterns
;
1371 const std::vector
<std::unique_ptr
<Pattern
>> &get_lower_patterns () const
1373 return lower_patterns
;
1376 // TODO: seems kinda dodgy. Think of better way.
1377 std::vector
<std::unique_ptr
<Pattern
>> &get_upper_patterns ()
1379 return upper_patterns
;
1381 const std::vector
<std::unique_ptr
<Pattern
>> &get_upper_patterns () const
1383 return upper_patterns
;
1386 TuplePatternItemType
get_pattern_type () const override
1388 return TuplePatternItemType::RANGED
;
1392 /* Use covariance to implement clone function as returning this object rather
1394 TuplePatternItemsRanged
*clone_tuple_pattern_items_impl () const override
1396 return new TuplePatternItemsRanged (*this);
1400 // AST node representing a tuple pattern
1401 class TuplePattern
: public Pattern
1403 std::unique_ptr
<TuplePatternItems
> items
;
1408 std::string
as_string () const override
;
1410 TuplePattern (std::unique_ptr
<TuplePatternItems
> items
, location_t locus
)
1411 : items (std::move (items
)), locus (locus
),
1412 node_id (Analysis::Mappings::get ().get_next_node_id ())
1414 rust_assert (this->items
!= nullptr);
1417 // Copy constructor requires clone
1418 TuplePattern (TuplePattern
const &other
) : locus (other
.locus
)
1420 // guard to prevent null dereference
1421 rust_assert (other
.items
!= nullptr);
1423 node_id
= other
.node_id
;
1424 items
= other
.items
->clone_tuple_pattern_items ();
1427 // Overload assignment operator to clone
1428 TuplePattern
&operator= (TuplePattern
const &other
)
1430 locus
= other
.locus
;
1431 node_id
= other
.node_id
;
1433 // guard to prevent null dereference
1434 rust_assert (other
.items
!= nullptr);
1436 items
= other
.items
->clone_tuple_pattern_items ();
1440 location_t
get_locus () const override final
{ return locus
; }
1442 void accept_vis (ASTVisitor
&vis
) override
;
1444 // TODO: seems kinda dodgy. Think of better way.
1445 TuplePatternItems
&get_items ()
1447 rust_assert (items
!= nullptr);
1451 NodeId
get_node_id () const override
{ return node_id
; }
1453 Pattern::Kind
get_pattern_kind () override
{ return Pattern::Kind::Tuple
; }
1456 /* Use covariance to implement clone function as returning this object rather
1458 TuplePattern
*clone_pattern_impl () const override
1460 return new TuplePattern (*this);
1464 // AST node representing a pattern in parentheses, used to control precedence
1465 class GroupedPattern
: public Pattern
1467 std::unique_ptr
<Pattern
> pattern_in_parens
;
1472 std::string
as_string () const override
1474 return "(" + pattern_in_parens
->as_string () + ")";
1477 GroupedPattern (std::unique_ptr
<Pattern
> pattern_in_parens
, location_t locus
)
1478 : pattern_in_parens (std::move (pattern_in_parens
)), locus (locus
),
1479 node_id (Analysis::Mappings::get ().get_next_node_id ())
1482 // Copy constructor uses clone
1483 GroupedPattern (GroupedPattern
const &other
)
1484 : pattern_in_parens (other
.pattern_in_parens
->clone_pattern ()),
1485 locus (other
.locus
), node_id (other
.node_id
)
1488 // Overload assignment operator to clone
1489 GroupedPattern
&operator= (GroupedPattern
const &other
)
1491 pattern_in_parens
= other
.pattern_in_parens
->clone_pattern ();
1492 locus
= other
.locus
;
1493 node_id
= other
.node_id
;
1498 // default move semantics
1499 GroupedPattern (GroupedPattern
&&other
) = default;
1500 GroupedPattern
&operator= (GroupedPattern
&&other
) = default;
1502 location_t
get_locus () const override final
{ return locus
; }
1504 void accept_vis (ASTVisitor
&vis
) override
;
1506 // TODO: seems kinda dodgy. Think of better way.
1507 Pattern
&get_pattern_in_parens ()
1509 rust_assert (pattern_in_parens
!= nullptr);
1510 return *pattern_in_parens
;
1513 NodeId
get_node_id () const override
{ return node_id
; }
1515 Pattern::Kind
get_pattern_kind () override
{ return Pattern::Kind::Grouped
; }
1518 /* Use covariance to implement clone function as returning this object rather
1520 GroupedPattern
*clone_pattern_impl () const override
1522 return new GroupedPattern (*this);
1526 // AST node representing patterns that can match slices and arrays
1527 class SlicePattern
: public Pattern
1529 std::vector
<std::unique_ptr
<Pattern
>> items
;
1534 std::string
as_string () const override
;
1536 SlicePattern (std::vector
<std::unique_ptr
<Pattern
>> items
, location_t locus
)
1537 : items (std::move (items
)), locus (locus
),
1538 node_id (Analysis::Mappings::get ().get_next_node_id ())
1541 // Copy constructor with vector clone
1542 SlicePattern (SlicePattern
const &other
) : locus (other
.locus
)
1544 node_id
= other
.node_id
;
1545 items
.reserve (other
.items
.size ());
1546 for (const auto &e
: other
.items
)
1547 items
.push_back (e
->clone_pattern ());
1550 // Overloaded assignment operator to vector clone
1551 SlicePattern
&operator= (SlicePattern
const &other
)
1553 locus
= other
.locus
;
1554 node_id
= other
.node_id
;
1557 items
.reserve (other
.items
.size ());
1558 for (const auto &e
: other
.items
)
1559 items
.push_back (e
->clone_pattern ());
1564 // move constructors
1565 SlicePattern (SlicePattern
&&other
) = default;
1566 SlicePattern
&operator= (SlicePattern
&&other
) = default;
1568 location_t
get_locus () const override final
{ return locus
; }
1570 void accept_vis (ASTVisitor
&vis
) override
;
1572 // TODO: seems kinda dodgy. Think of better way.
1573 std::vector
<std::unique_ptr
<Pattern
>> &get_items () { return items
; }
1574 const std::vector
<std::unique_ptr
<Pattern
>> &get_items () const
1579 NodeId
get_node_id () const override
{ return node_id
; }
1581 Pattern::Kind
get_pattern_kind () override
{ return Pattern::Kind::Slice
; }
1584 /* Use covariance to implement clone function as returning this object rather
1586 SlicePattern
*clone_pattern_impl () const override
1588 return new SlicePattern (*this);
1592 // AST node for alternate patterns
1593 // joins together what are technically 'PatternNoTopAlt's
1594 class AltPattern
: public Pattern
1596 std::vector
<std::unique_ptr
<Pattern
>> alts
;
1601 std::string
as_string () const override
;
1603 AltPattern (std::vector
<std::unique_ptr
<Pattern
>> alts
, location_t locus
)
1604 : alts (std::move (alts
)), locus (locus
),
1605 node_id (Analysis::Mappings::get ().get_next_node_id ())
1608 // Copy constructor with vector clone
1609 AltPattern (AltPattern
const &other
) : locus (other
.locus
)
1611 node_id
= other
.node_id
;
1612 alts
.reserve (other
.alts
.size ());
1613 for (const auto &e
: other
.alts
)
1614 alts
.push_back (e
->clone_pattern ());
1617 // Overloaded assignment operator to vector clone
1618 AltPattern
&operator= (AltPattern
const &other
)
1620 locus
= other
.locus
;
1621 node_id
= other
.node_id
;
1624 alts
.reserve (other
.alts
.size ());
1625 for (const auto &e
: other
.alts
)
1626 alts
.push_back (e
->clone_pattern ());
1631 // move constructors
1632 AltPattern (AltPattern
&&other
) = default;
1633 AltPattern
&operator= (AltPattern
&&other
) = default;
1635 location_t
get_locus () const override final
{ return locus
; }
1637 void accept_vis (ASTVisitor
&vis
) override
;
1639 // TODO: seems kinda dodgy. Think of better way.
1640 std::vector
<std::unique_ptr
<Pattern
>> &get_alts () { return alts
; }
1641 const std::vector
<std::unique_ptr
<Pattern
>> &get_alts () const
1646 NodeId
get_node_id () const override
{ return node_id
; }
1648 Pattern::Kind
get_pattern_kind () override
{ return Pattern::Kind::Alt
; }
1651 /* Use covariance to implement clone function as returning this object rather
1653 AltPattern
*clone_pattern_impl () const override
1655 return new AltPattern (*this);
1659 // Moved definition to rust-path.h
1662 // Forward decls for paths (defined in rust-path.h)
1663 class PathInExpression
;
1664 class QualifiedPathInExpression
;
1666 // Replaced with forward decl - defined in rust-macro.h
1667 class MacroInvocation
;