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