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