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