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