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