]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rust/hir/tree/rust-hir-expr.h
Update copyright years.
[thirdparty/gcc.git] / gcc / rust / hir / tree / rust-hir-expr.h
1 // Copyright (C) 2020-2023 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_EXPR_H
20 #define RUST_HIR_EXPR_H
21
22 #include "rust-common.h"
23 #include "rust-ast-full-decls.h"
24 #include "rust-hir.h"
25 #include "rust-hir-path.h"
26 #include "operator.h"
27
28 namespace Rust {
29 namespace HIR {
30
31 // HIR node for an expression with an accompanying block - abstract
32 class ExprWithBlock : public Expr
33 {
34 // TODO: should this mean that a BlockExpr should be a member variable?
35 protected:
36 ExprWithBlock (Analysis::NodeMapping mappings,
37 AST::AttrVec outer_attrs = AST::AttrVec ())
38 : Expr (std::move (mappings), std::move (outer_attrs))
39 {}
40
41 // pure virtual clone implementation
42 virtual ExprWithBlock *clone_expr_with_block_impl () const = 0;
43
44 // prevent having to define multiple clone expressions
45 ExprWithBlock *clone_expr_impl () const override
46 {
47 return clone_expr_with_block_impl ();
48 }
49
50 public:
51 // Unique pointer custom clone function
52 std::unique_ptr<ExprWithBlock> clone_expr_with_block () const
53 {
54 return std::unique_ptr<ExprWithBlock> (clone_expr_with_block_impl ());
55 }
56
57 BlockType get_block_expr_type () const final override
58 {
59 return BlockType::WITH_BLOCK;
60 };
61 };
62
63 // Literals? Or literal base?
64 class LiteralExpr : public ExprWithoutBlock
65 {
66 Literal literal;
67 Location locus;
68
69 public:
70 std::string as_string () const override
71 {
72 return "( " + literal.as_string () + " (" + get_mappings ().as_string ()
73 + "))";
74 }
75
76 Literal::LitType get_lit_type () const { return literal.get_lit_type (); }
77
78 LiteralExpr (Analysis::NodeMapping mappings, std::string value_as_string,
79 Literal::LitType type, PrimitiveCoreType type_hint,
80 Location locus, AST::AttrVec outer_attrs)
81 : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
82 literal (std::move (value_as_string), type, type_hint), locus (locus)
83 {}
84
85 LiteralExpr (Analysis::NodeMapping mappings, Literal literal, Location locus,
86 AST::AttrVec outer_attrs)
87 : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
88 literal (std::move (literal)), locus (locus)
89 {}
90
91 // Unique pointer custom clone function
92 std::unique_ptr<LiteralExpr> clone_literal_expr () const
93 {
94 return std::unique_ptr<LiteralExpr> (clone_literal_expr_impl ());
95 }
96
97 Location get_locus () const override final { return locus; }
98
99 void accept_vis (HIRFullVisitor &vis) override;
100 void accept_vis (HIRExpressionVisitor &vis) override;
101
102 Literal &get_literal () { return literal; }
103 const Literal &get_literal () const { return literal; }
104
105 ExprType get_expression_type () const override final { return ExprType::Lit; }
106
107 protected:
108 /* Use covariance to implement clone function as returning this object rather
109 * than base */
110 LiteralExpr *clone_expr_impl () const override
111 {
112 return new LiteralExpr (*this);
113 }
114
115 /* Use covariance to implement clone function as returning this object rather
116 * than base */
117 LiteralExpr *clone_expr_without_block_impl () const override
118 {
119 return new LiteralExpr (*this);
120 }
121
122 /* not virtual as currently no subclasses of LiteralExpr, but could be in
123 * future */
124 /*virtual*/ LiteralExpr *clone_literal_expr_impl () const
125 {
126 return new LiteralExpr (*this);
127 }
128 };
129
130 /* Represents an expression using unary or binary operators as HIR node. Can be
131 * overloaded. */
132 class OperatorExpr : public ExprWithoutBlock
133 {
134 // TODO: create binary and unary operator subclasses?
135 public:
136 Location locus;
137
138 protected:
139 /* Variable must be protected to allow derived classes to use it as a first
140 * class citizen */
141 std::unique_ptr<Expr> main_or_left_expr;
142
143 // Constructor (only for initialisation of expr purposes)
144 OperatorExpr (Analysis::NodeMapping mappings,
145 std::unique_ptr<Expr> main_or_left_expr,
146 AST::AttrVec outer_attribs, Location locus)
147 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
148 locus (locus), main_or_left_expr (std::move (main_or_left_expr))
149 {}
150
151 // Copy constructor (only for initialisation of expr purposes)
152 OperatorExpr (OperatorExpr const &other)
153 : ExprWithoutBlock (other), locus (other.locus),
154 main_or_left_expr (other.main_or_left_expr->clone_expr ())
155 {}
156
157 // Overload assignment operator to deep copy expr
158 OperatorExpr &operator= (OperatorExpr const &other)
159 {
160 ExprWithoutBlock::operator= (other);
161 main_or_left_expr = other.main_or_left_expr->clone_expr ();
162 locus = other.locus;
163 // outer_attrs = other.outer_attrs;
164
165 return *this;
166 }
167
168 // move constructors
169 OperatorExpr (OperatorExpr &&other) = default;
170 OperatorExpr &operator= (OperatorExpr &&other) = default;
171
172 public:
173 Location get_locus () const override final { return locus; }
174
175 std::unique_ptr<Expr> &get_expr () { return main_or_left_expr; }
176
177 ExprType get_expression_type () const override final
178 {
179 return ExprType::Operator;
180 }
181 };
182
183 /* Unary prefix & or &mut (or && and &&mut) borrow operator. Cannot be
184 * overloaded. */
185 class BorrowExpr : public OperatorExpr
186 {
187 Mutability mut;
188 bool double_borrow;
189
190 public:
191 std::string as_string () const override;
192
193 BorrowExpr (Analysis::NodeMapping mappings,
194 std::unique_ptr<Expr> borrow_lvalue, Mutability mut,
195 bool is_double_borrow, AST::AttrVec outer_attribs, Location locus)
196 : OperatorExpr (std::move (mappings), std::move (borrow_lvalue),
197 std::move (outer_attribs), locus),
198 mut (mut), double_borrow (is_double_borrow)
199 {}
200
201 void accept_vis (HIRFullVisitor &vis) override;
202 void accept_vis (HIRExpressionVisitor &vis) override;
203
204 Mutability get_mut () const { return mut; }
205 bool is_mut () const { return mut == Mutability::Mut; }
206 bool get_is_double_borrow () const { return double_borrow; }
207
208 protected:
209 /* Use covariance to implement clone function as returning this object rather
210 * than base */
211 BorrowExpr *clone_expr_impl () const override
212 {
213 return new BorrowExpr (*this);
214 }
215
216 /* Use covariance to implement clone function as returning this object rather
217 * than base */
218 BorrowExpr *clone_expr_without_block_impl () const override
219 {
220 return new BorrowExpr (*this);
221 }
222 };
223
224 // Unary prefix * deference operator
225 class DereferenceExpr : public OperatorExpr
226 {
227 public:
228 std::string as_string () const override;
229
230 // Constructor calls OperatorExpr's protected constructor
231 DereferenceExpr (Analysis::NodeMapping mappings,
232 std::unique_ptr<Expr> deref_lvalue,
233 AST::AttrVec outer_attribs, Location locus)
234 : OperatorExpr (std::move (mappings), std::move (deref_lvalue),
235 std::move (outer_attribs), locus)
236 {}
237
238 void accept_vis (HIRFullVisitor &vis) override;
239 void accept_vis (HIRExpressionVisitor &vis) override;
240
241 protected:
242 /* Use covariance to implement clone function as returning this object rather
243 * than base */
244 DereferenceExpr *clone_expr_impl () const override
245 {
246 return new DereferenceExpr (*this);
247 }
248
249 /* Use covariance to implement clone function as returning this object rather
250 * than base */
251 DereferenceExpr *clone_expr_without_block_impl () const override
252 {
253 return new DereferenceExpr (*this);
254 }
255 };
256
257 // Unary postfix ? error propogation operator. Cannot be overloaded.
258 class ErrorPropagationExpr : public OperatorExpr
259 {
260 public:
261 std::string as_string () const override;
262
263 // Constructor calls OperatorExpr's protected constructor
264 ErrorPropagationExpr (Analysis::NodeMapping mappings,
265 std::unique_ptr<Expr> potential_error_value,
266 AST::AttrVec outer_attribs, Location locus)
267 : OperatorExpr (std::move (mappings), std::move (potential_error_value),
268 std::move (outer_attribs), locus)
269 {}
270
271 void accept_vis (HIRFullVisitor &vis) override;
272 void accept_vis (HIRExpressionVisitor &vis) override;
273
274 protected:
275 /* Use covariance to implement clone function as returning this object rather
276 * than base */
277 ErrorPropagationExpr *clone_expr_impl () const override
278 {
279 return new ErrorPropagationExpr (*this);
280 }
281
282 /* Use covariance to implement clone function as returning this object rather
283 * than base */
284 ErrorPropagationExpr *clone_expr_without_block_impl () const override
285 {
286 return new ErrorPropagationExpr (*this);
287 }
288 };
289
290 // Unary prefix - or ! negation or NOT operators.
291 class NegationExpr : public OperatorExpr
292 {
293 public:
294 using ExprType = NegationOperator;
295
296 private:
297 /* Note: overload negation via std::ops::Neg and not via std::ops::Not
298 * Negation only works for signed integer and floating-point types, NOT only
299 * works for boolean and integer types (via bitwise NOT) */
300 ExprType expr_type;
301
302 public:
303 std::string as_string () const override;
304
305 ExprType get_expr_type () const { return expr_type; }
306
307 // Constructor calls OperatorExpr's protected constructor
308 NegationExpr (Analysis::NodeMapping mappings,
309 std::unique_ptr<Expr> negated_value, ExprType expr_kind,
310 AST::AttrVec outer_attribs, Location locus)
311 : OperatorExpr (std::move (mappings), std::move (negated_value),
312 std::move (outer_attribs), locus),
313 expr_type (expr_kind)
314 {}
315
316 void accept_vis (HIRFullVisitor &vis) override;
317 void accept_vis (HIRExpressionVisitor &vis) override;
318
319 protected:
320 /* Use covariance to implement clone function as returning this object rather
321 * than base */
322 NegationExpr *clone_expr_impl () const override
323 {
324 return new NegationExpr (*this);
325 }
326
327 /* Use covariance to implement clone function as returning this object rather
328 * than base */
329 NegationExpr *clone_expr_without_block_impl () const override
330 {
331 return new NegationExpr (*this);
332 }
333 };
334
335 // Infix binary operators. +, -, *, /, %, &, |, ^, <<, >>
336 class ArithmeticOrLogicalExpr : public OperatorExpr
337 {
338 public:
339 using ExprType = ArithmeticOrLogicalOperator;
340
341 private:
342 // Note: overloading trait specified in comments
343 ExprType expr_type;
344
345 std::unique_ptr<Expr> right_expr;
346
347 public:
348 std::string as_string () const override;
349
350 ExprType get_expr_type () const { return expr_type; }
351
352 // Constructor calls OperatorExpr's protected constructor
353 ArithmeticOrLogicalExpr (Analysis::NodeMapping mappings,
354 std::unique_ptr<Expr> left_value,
355 std::unique_ptr<Expr> right_value,
356 ExprType expr_kind, Location locus)
357 : OperatorExpr (std::move (mappings), std::move (left_value),
358 AST::AttrVec (), locus),
359 expr_type (expr_kind), right_expr (std::move (right_value))
360 {}
361 // outer attributes not allowed
362
363 // Copy constructor - probably required due to unique pointer
364 ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr const &other)
365 : OperatorExpr (other), expr_type (other.expr_type),
366 right_expr (other.right_expr->clone_expr ())
367 {}
368
369 // Overload assignment operator
370 ArithmeticOrLogicalExpr &operator= (ArithmeticOrLogicalExpr const &other)
371 {
372 OperatorExpr::operator= (other);
373 // main_or_left_expr = other.main_or_left_expr->clone_expr();
374 right_expr = other.right_expr->clone_expr ();
375 expr_type = other.expr_type;
376
377 return *this;
378 }
379
380 // move constructors
381 ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr &&other) = default;
382 ArithmeticOrLogicalExpr &operator= (ArithmeticOrLogicalExpr &&other)
383 = default;
384
385 void accept_vis (HIRFullVisitor &vis) override;
386 void accept_vis (HIRExpressionVisitor &vis) override;
387
388 void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); }
389 void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); }
390
391 Expr *get_lhs () { return main_or_left_expr.get (); }
392 Expr *get_rhs () { return right_expr.get (); }
393
394 protected:
395 /* Use covariance to implement clone function as returning this object rather
396 * than base */
397 ArithmeticOrLogicalExpr *clone_expr_impl () const override
398 {
399 return new ArithmeticOrLogicalExpr (*this);
400 }
401
402 /* Use covariance to implement clone function as returning this object rather
403 * than base */
404 ArithmeticOrLogicalExpr *clone_expr_without_block_impl () const override
405 {
406 return new ArithmeticOrLogicalExpr (*this);
407 }
408 };
409
410 // Infix binary comparison operators. ==, !=, <, <=, >, >=
411 class ComparisonExpr : public OperatorExpr
412 {
413 public:
414 using ExprType = ComparisonOperator;
415
416 private:
417 // Note: overloading trait specified in comments
418 ExprType expr_type;
419
420 std::unique_ptr<Expr> right_expr;
421
422 public:
423 std::string as_string () const override;
424
425 ExprType get_expr_type () const { return expr_type; }
426
427 // Constructor requires pointers for polymorphism
428 ComparisonExpr (Analysis::NodeMapping mappings,
429 std::unique_ptr<Expr> left_value,
430 std::unique_ptr<Expr> right_value, ExprType comparison_kind,
431 Location locus)
432 : OperatorExpr (std::move (mappings), std::move (left_value),
433 AST::AttrVec (), locus),
434 expr_type (comparison_kind), right_expr (std::move (right_value))
435 {}
436 // outer attributes not allowed
437
438 // Copy constructor also calls OperatorExpr's protected constructor
439 ComparisonExpr (ComparisonExpr const &other)
440 : OperatorExpr (other), expr_type (other.expr_type),
441 right_expr (other.right_expr->clone_expr ())
442 {}
443
444 // Overload assignment operator to deep copy
445 ComparisonExpr &operator= (ComparisonExpr const &other)
446 {
447 OperatorExpr::operator= (other);
448 // main_or_left_expr = other.main_or_left_expr->clone_expr();
449 right_expr = other.right_expr->clone_expr ();
450 expr_type = other.expr_type;
451 // outer_attrs = other.outer_attrs;
452
453 return *this;
454 }
455
456 // move constructors
457 ComparisonExpr (ComparisonExpr &&other) = default;
458 ComparisonExpr &operator= (ComparisonExpr &&other) = default;
459
460 void accept_vis (HIRFullVisitor &vis) override;
461 void accept_vis (HIRExpressionVisitor &vis) override;
462
463 Expr *get_lhs () { return main_or_left_expr.get (); }
464 Expr *get_rhs () { return right_expr.get (); }
465
466 ExprType get_kind () { return expr_type; }
467
468 /* TODO: implement via a function call to std::cmp::PartialEq::eq(&op1, &op2)
469 * maybe? */
470 protected:
471 /* Use covariance to implement clone function as returning this object rather
472 * than base */
473 ComparisonExpr *clone_expr_impl () const override
474 {
475 return new ComparisonExpr (*this);
476 }
477
478 /* Use covariance to implement clone function as returning this object rather
479 * than base */
480 ComparisonExpr *clone_expr_without_block_impl () const override
481 {
482 return new ComparisonExpr (*this);
483 }
484 };
485
486 // Infix binary lazy boolean logical operators && and ||.
487 class LazyBooleanExpr : public OperatorExpr
488 {
489 public:
490 using ExprType = LazyBooleanOperator;
491
492 private:
493 ExprType expr_type;
494
495 std::unique_ptr<Expr> right_expr;
496
497 public:
498 // Constructor calls OperatorExpr's protected constructor
499 LazyBooleanExpr (Analysis::NodeMapping mappings,
500 std::unique_ptr<Expr> left_bool_expr,
501 std::unique_ptr<Expr> right_bool_expr, ExprType expr_kind,
502 Location locus)
503 : OperatorExpr (std::move (mappings), std::move (left_bool_expr),
504 AST::AttrVec (), locus),
505 expr_type (expr_kind), right_expr (std::move (right_bool_expr))
506 {}
507 // outer attributes not allowed
508
509 // Copy constructor also calls OperatorExpr's protected constructor
510 LazyBooleanExpr (LazyBooleanExpr const &other)
511 : OperatorExpr (other), expr_type (other.expr_type),
512 right_expr (other.right_expr->clone_expr ())
513 {}
514
515 // Overload assignment operator to deep copy
516 LazyBooleanExpr &operator= (LazyBooleanExpr const &other)
517 {
518 OperatorExpr::operator= (other);
519 // main_or_left_expr = other.main_or_left_expr->clone_expr();
520 right_expr = other.right_expr->clone_expr ();
521 expr_type = other.expr_type;
522
523 return *this;
524 }
525
526 // move constructors
527 LazyBooleanExpr (LazyBooleanExpr &&other) = default;
528 LazyBooleanExpr &operator= (LazyBooleanExpr &&other) = default;
529
530 std::string as_string () const override;
531
532 ExprType get_expr_type () const { return expr_type; }
533
534 void accept_vis (HIRFullVisitor &vis) override;
535 void accept_vis (HIRExpressionVisitor &vis) override;
536
537 Expr *get_lhs () { return main_or_left_expr.get (); }
538
539 Expr *get_rhs () { return right_expr.get (); }
540
541 protected:
542 /* Use covariance to implement clone function as returning this object rather
543 * than base */
544 LazyBooleanExpr *clone_expr_impl () const override
545 {
546 return new LazyBooleanExpr (*this);
547 }
548
549 /* Use covariance to implement clone function as returning this object rather
550 * than base */
551 LazyBooleanExpr *clone_expr_without_block_impl () const override
552 {
553 return new LazyBooleanExpr (*this);
554 }
555 };
556
557 // Binary infix "as" chir expression.
558 class TypeCastExpr : public OperatorExpr
559 {
560 std::unique_ptr<Type> type_to_convert_to;
561
562 // Note: only certain type casts allowed, outlined in reference
563 public:
564 std::string as_string () const override;
565
566 // Constructor requires calling protected constructor of OperatorExpr
567 TypeCastExpr (Analysis::NodeMapping mappings,
568 std::unique_ptr<Expr> expr_to_cast,
569 std::unique_ptr<Type> type_to_cast_to, Location locus)
570 : OperatorExpr (std::move (mappings), std::move (expr_to_cast),
571 AST::AttrVec (), locus),
572 type_to_convert_to (std::move (type_to_cast_to))
573 {}
574 // outer attributes not allowed
575
576 // Copy constructor also requires calling protected constructor
577 TypeCastExpr (TypeCastExpr const &other)
578 : OperatorExpr (other),
579 type_to_convert_to (other.type_to_convert_to->clone_type ())
580 {}
581
582 // Overload assignment operator to deep copy
583 TypeCastExpr &operator= (TypeCastExpr const &other)
584 {
585 OperatorExpr::operator= (other);
586 // main_or_left_expr = other.main_or_left_expr->clone_expr();
587 type_to_convert_to = other.type_to_convert_to->clone_type ();
588
589 return *this;
590 }
591
592 // move constructors as not supported in c++03
593 TypeCastExpr (TypeCastExpr &&other) = default;
594 TypeCastExpr &operator= (TypeCastExpr &&other) = default;
595
596 void accept_vis (HIRFullVisitor &vis) override;
597 void accept_vis (HIRExpressionVisitor &vis) override;
598
599 std::unique_ptr<Expr> &get_casted_expr ()
600 {
601 rust_assert (main_or_left_expr != nullptr);
602 return main_or_left_expr;
603 }
604
605 std::unique_ptr<Type> &get_type_to_convert_to ()
606 {
607 rust_assert (type_to_convert_to != nullptr);
608 return type_to_convert_to;
609 }
610
611 protected:
612 /* Use covariance to implement clone function as returning this object rather
613 * than base */
614 TypeCastExpr *clone_expr_impl () const override
615 {
616 return new TypeCastExpr (*this);
617 }
618
619 /* Use covariance to implement clone function as returning this object rather
620 * than base */
621 TypeCastExpr *clone_expr_without_block_impl () const override
622 {
623 return new TypeCastExpr (*this);
624 }
625 };
626
627 // Binary assignment expression.
628 class AssignmentExpr : public OperatorExpr
629 {
630 std::unique_ptr<Expr> right_expr;
631
632 public:
633 std::string as_string () const override;
634
635 // Call OperatorExpr constructor to initialise left_expr
636 AssignmentExpr (Analysis::NodeMapping mappings,
637 std::unique_ptr<Expr> value_to_assign_to,
638 std::unique_ptr<Expr> value_to_assign, Location locus)
639 : OperatorExpr (std::move (mappings), std::move (value_to_assign_to),
640 AST::AttrVec (), locus),
641 right_expr (std::move (value_to_assign))
642 {}
643 // outer attributes not allowed
644
645 // Call OperatorExpr constructor in copy constructor, as well as clone
646 AssignmentExpr (AssignmentExpr const &other)
647 : OperatorExpr (other), right_expr (other.right_expr->clone_expr ())
648 {}
649
650 // Overload assignment operator to clone unique_ptr right_expr
651 AssignmentExpr &operator= (AssignmentExpr const &other)
652 {
653 OperatorExpr::operator= (other);
654 // main_or_left_expr = other.main_or_left_expr->clone_expr();
655 right_expr = other.right_expr->clone_expr ();
656 // outer_attrs = other.outer_attrs;
657
658 return *this;
659 }
660
661 // move constructors
662 AssignmentExpr (AssignmentExpr &&other) = default;
663 AssignmentExpr &operator= (AssignmentExpr &&other) = default;
664
665 void accept_vis (HIRFullVisitor &vis) override;
666 void accept_vis (HIRExpressionVisitor &vis) override;
667
668 void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); }
669 void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); }
670
671 Expr *get_lhs () { return main_or_left_expr.get (); }
672 Expr *get_rhs () { return right_expr.get (); }
673
674 protected:
675 /* Use covariance to implement clone function as returning this object rather
676 * than base */
677 AssignmentExpr *clone_expr_impl () const override
678 {
679 return new AssignmentExpr (*this);
680 }
681
682 /* Use covariance to implement clone function as returning this object rather
683 * than base */
684 AssignmentExpr *clone_expr_without_block_impl () const override
685 {
686 return new AssignmentExpr (*this);
687 }
688 };
689
690 class CompoundAssignmentExpr : public OperatorExpr
691 {
692 public:
693 using ExprType = ArithmeticOrLogicalOperator;
694
695 private:
696 // Note: overloading trait specified in comments
697 ExprType expr_type;
698 std::unique_ptr<Expr> right_expr;
699
700 public:
701 std::string as_string () const override;
702
703 ExprType get_expr_type () const { return expr_type; }
704
705 // Use pointers in constructor to enable polymorphism
706 CompoundAssignmentExpr (Analysis::NodeMapping mappings,
707 std::unique_ptr<Expr> value_to_assign_to,
708 std::unique_ptr<Expr> value_to_assign,
709 ExprType expr_kind, Location locus)
710 : OperatorExpr (std::move (mappings), std::move (value_to_assign_to),
711 AST::AttrVec (), locus),
712 expr_type (expr_kind), right_expr (std::move (value_to_assign))
713 {}
714 // outer attributes not allowed
715
716 // Have clone in copy constructor
717 CompoundAssignmentExpr (CompoundAssignmentExpr const &other)
718 : OperatorExpr (other), expr_type (other.expr_type),
719 right_expr (other.right_expr->clone_expr ())
720 {}
721
722 // Overload assignment operator to clone
723 CompoundAssignmentExpr &operator= (CompoundAssignmentExpr const &other)
724 {
725 OperatorExpr::operator= (other);
726 // main_or_left_expr = other.main_or_left_expr->clone_expr();
727 right_expr = other.right_expr->clone_expr ();
728 expr_type = other.expr_type;
729 // outer_attrs = other.outer_attrs;
730
731 return *this;
732 }
733
734 // move constructors
735 CompoundAssignmentExpr (CompoundAssignmentExpr &&other) = default;
736 CompoundAssignmentExpr &operator= (CompoundAssignmentExpr &&other) = default;
737
738 void accept_vis (HIRFullVisitor &vis) override;
739 void accept_vis (HIRExpressionVisitor &vis) override;
740
741 std::unique_ptr<Expr> &get_left_expr ()
742 {
743 rust_assert (main_or_left_expr != nullptr);
744 return main_or_left_expr;
745 }
746
747 std::unique_ptr<Expr> &get_right_expr ()
748 {
749 rust_assert (right_expr != nullptr);
750 return right_expr;
751 }
752
753 void visit_lhs (HIRFullVisitor &vis) { main_or_left_expr->accept_vis (vis); }
754 void visit_rhs (HIRFullVisitor &vis) { right_expr->accept_vis (vis); }
755
756 protected:
757 /* Use covariance to implement clone function as returning this object rather
758 * than base */
759 CompoundAssignmentExpr *clone_expr_without_block_impl () const override
760 {
761 return new CompoundAssignmentExpr (*this);
762 }
763 };
764
765 // Expression in parentheses (i.e. like literally just any 3 + (2 * 6))
766 class GroupedExpr : public ExprWithoutBlock
767 {
768 AST::AttrVec inner_attrs;
769 std::unique_ptr<Expr> expr_in_parens;
770
771 Location locus;
772
773 public:
774 std::string as_string () const override;
775
776 AST::AttrVec get_inner_attrs () const { return inner_attrs; }
777
778 GroupedExpr (Analysis::NodeMapping mappings,
779 std::unique_ptr<Expr> parenthesised_expr,
780 AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
781 Location locus)
782 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
783 inner_attrs (std::move (inner_attribs)),
784 expr_in_parens (std::move (parenthesised_expr)), locus (locus)
785 {}
786
787 // Copy constructor includes clone for expr_in_parens
788 GroupedExpr (GroupedExpr const &other)
789 : ExprWithoutBlock (other), inner_attrs (other.inner_attrs),
790 expr_in_parens (other.expr_in_parens->clone_expr ()), locus (other.locus)
791 {}
792
793 // Overloaded assignment operator to clone expr_in_parens
794 GroupedExpr &operator= (GroupedExpr const &other)
795 {
796 ExprWithoutBlock::operator= (other);
797 inner_attrs = other.inner_attrs;
798 expr_in_parens = other.expr_in_parens->clone_expr ();
799 locus = other.locus;
800 // outer_attrs = other.outer_attrs;
801
802 return *this;
803 }
804
805 // move constructors
806 GroupedExpr (GroupedExpr &&other) = default;
807 GroupedExpr &operator= (GroupedExpr &&other) = default;
808
809 Location get_locus () const override final { return locus; }
810
811 void accept_vis (HIRFullVisitor &vis) override;
812 void accept_vis (HIRExpressionVisitor &vis) override;
813
814 std::unique_ptr<Expr> &get_expr_in_parens ()
815 {
816 rust_assert (expr_in_parens != nullptr);
817 return expr_in_parens;
818 }
819
820 ExprType get_expression_type () const override final
821 {
822 return ExprType::Grouped;
823 }
824
825 protected:
826 /* Use covariance to implement clone function as returning this object rather
827 * than base */
828 GroupedExpr *clone_expr_impl () const override
829 {
830 return new GroupedExpr (*this);
831 }
832
833 /* Use covariance to implement clone function as returning this object rather
834 * than base */
835 GroupedExpr *clone_expr_without_block_impl () const override
836 {
837 return new GroupedExpr (*this);
838 }
839 };
840
841 // Base array initialisation internal element representation thing (abstract)
842 // aka ArrayElements
843 class ArrayElems
844 {
845 public:
846 enum ArrayExprType
847 {
848 VALUES,
849 COPIED,
850 };
851
852 ArrayElems (Analysis::NodeMapping mappings) : mappings (mappings){};
853
854 virtual ~ArrayElems () {}
855
856 // Unique pointer custom clone ArrayElems function
857 std::unique_ptr<ArrayElems> clone_array_elems () const
858 {
859 return std::unique_ptr<ArrayElems> (clone_array_elems_impl ());
860 }
861
862 virtual std::string as_string () const = 0;
863
864 virtual void accept_vis (HIRFullVisitor &vis) = 0;
865
866 virtual ArrayExprType get_array_expr_type () const = 0;
867
868 Analysis::NodeMapping &get_mappings () { return mappings; }
869
870 protected:
871 // pure virtual clone implementation
872 virtual ArrayElems *clone_array_elems_impl () const = 0;
873
874 Analysis::NodeMapping mappings;
875 };
876
877 // Value array elements
878 class ArrayElemsValues : public ArrayElems
879 {
880 std::vector<std::unique_ptr<Expr> > values;
881
882 // TODO: should this store location data?
883
884 public:
885 ArrayElemsValues (Analysis::NodeMapping mappings,
886 std::vector<std::unique_ptr<Expr> > elems)
887 : ArrayElems (mappings), values (std::move (elems))
888 {}
889
890 // copy constructor with vector clone
891 ArrayElemsValues (ArrayElemsValues const &other) : ArrayElems (other)
892 {
893 values.reserve (other.values.size ());
894 for (const auto &e : other.values)
895 values.push_back (e->clone_expr ());
896 }
897
898 // overloaded assignment operator with vector clone
899 ArrayElemsValues &operator= (ArrayElemsValues const &other)
900 {
901 values.reserve (other.values.size ());
902 for (const auto &e : other.values)
903 values.push_back (e->clone_expr ());
904
905 return *this;
906 }
907
908 // move constructors
909 ArrayElemsValues (ArrayElemsValues &&other) = default;
910 ArrayElemsValues &operator= (ArrayElemsValues &&other) = default;
911
912 std::string as_string () const override;
913
914 void accept_vis (HIRFullVisitor &vis) override;
915
916 size_t get_num_elements () const { return values.size (); }
917
918 std::vector<std::unique_ptr<Expr> > &get_values () { return values; }
919
920 ArrayElems::ArrayExprType get_array_expr_type () const override final
921 {
922 return ArrayElems::ArrayExprType::VALUES;
923 }
924
925 protected:
926 ArrayElemsValues *clone_array_elems_impl () const override
927 {
928 return new ArrayElemsValues (*this);
929 }
930 };
931
932 // Copied array element and number of copies
933 class ArrayElemsCopied : public ArrayElems
934 {
935 std::unique_ptr<Expr> elem_to_copy;
936 std::unique_ptr<Expr> num_copies;
937
938 public:
939 // Constructor requires pointers for polymorphism
940 ArrayElemsCopied (Analysis::NodeMapping mappings,
941 std::unique_ptr<Expr> copied_elem,
942 std::unique_ptr<Expr> copy_amount)
943 : ArrayElems (mappings), elem_to_copy (std::move (copied_elem)),
944 num_copies (std::move (copy_amount))
945 {}
946
947 // Copy constructor required due to unique_ptr - uses custom clone
948 ArrayElemsCopied (ArrayElemsCopied const &other)
949 : ArrayElems (other), elem_to_copy (other.elem_to_copy->clone_expr ()),
950 num_copies (other.num_copies->clone_expr ())
951 {}
952
953 // Overloaded assignment operator for deep copying
954 ArrayElemsCopied &operator= (ArrayElemsCopied const &other)
955 {
956 elem_to_copy = other.elem_to_copy->clone_expr ();
957 num_copies = other.num_copies->clone_expr ();
958
959 return *this;
960 }
961
962 // move constructors
963 ArrayElemsCopied (ArrayElemsCopied &&other) = default;
964 ArrayElemsCopied &operator= (ArrayElemsCopied &&other) = default;
965
966 std::string as_string () const override;
967
968 void accept_vis (HIRFullVisitor &vis) override;
969
970 Expr *get_elem_to_copy () { return elem_to_copy.get (); }
971
972 Expr *get_num_copies_expr () { return num_copies.get (); }
973
974 ArrayElems::ArrayExprType get_array_expr_type () const override final
975 {
976 return ArrayElems::ArrayExprType::COPIED;
977 }
978
979 protected:
980 ArrayElemsCopied *clone_array_elems_impl () const override
981 {
982 return new ArrayElemsCopied (*this);
983 }
984 };
985
986 // Array definition-ish expression
987 class ArrayExpr : public ExprWithoutBlock
988 {
989 AST::AttrVec inner_attrs;
990 std::unique_ptr<ArrayElems> internal_elements;
991
992 Location locus;
993
994 public:
995 std::string as_string () const override;
996
997 AST::AttrVec get_inner_attrs () const { return inner_attrs; }
998
999 // Returns whether array expr has array elems or if it is just empty.
1000 bool has_array_elems () const { return internal_elements != nullptr; }
1001
1002 // Constructor requires ArrayElems pointer
1003 ArrayExpr (Analysis::NodeMapping mappings,
1004 std::unique_ptr<ArrayElems> array_elems,
1005 AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
1006 Location locus)
1007 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
1008 inner_attrs (std::move (inner_attribs)),
1009 internal_elements (std::move (array_elems)), locus (locus)
1010 {}
1011
1012 // Copy constructor requires cloning ArrayElems for polymorphism to hold
1013 ArrayExpr (ArrayExpr const &other)
1014 : ExprWithoutBlock (other), inner_attrs (other.inner_attrs),
1015 locus (other.locus)
1016 {
1017 if (other.has_array_elems ())
1018 internal_elements = other.internal_elements->clone_array_elems ();
1019 }
1020
1021 // Overload assignment operator to clone internal_elements
1022 ArrayExpr &operator= (ArrayExpr const &other)
1023 {
1024 ExprWithoutBlock::operator= (other);
1025 inner_attrs = other.inner_attrs;
1026 if (other.has_array_elems ())
1027 internal_elements = other.internal_elements->clone_array_elems ();
1028 locus = other.locus;
1029 // outer_attrs = other.outer_attrs;
1030
1031 return *this;
1032 }
1033
1034 // move constructors
1035 ArrayExpr (ArrayExpr &&other) = default;
1036 ArrayExpr &operator= (ArrayExpr &&other) = default;
1037
1038 Location get_locus () const override final { return locus; }
1039
1040 void accept_vis (HIRFullVisitor &vis) override;
1041 void accept_vis (HIRExpressionVisitor &vis) override;
1042
1043 ArrayElems *get_internal_elements () { return internal_elements.get (); };
1044
1045 ExprType get_expression_type () const override final
1046 {
1047 return ExprType::Array;
1048 }
1049
1050 protected:
1051 /* Use covariance to implement clone function as returning this object rather
1052 * than base */
1053 ArrayExpr *clone_expr_impl () const override { return new ArrayExpr (*this); }
1054
1055 /* Use covariance to implement clone function as returning this object rather
1056 * than base */
1057 ArrayExpr *clone_expr_without_block_impl () const override
1058 {
1059 return new ArrayExpr (*this);
1060 }
1061 };
1062
1063 class ArrayIndexExpr : public ExprWithoutBlock
1064 {
1065 std::unique_ptr<Expr> array_expr;
1066 std::unique_ptr<Expr> index_expr;
1067
1068 Location locus;
1069
1070 public:
1071 std::string as_string () const override;
1072
1073 ArrayIndexExpr (Analysis::NodeMapping mappings,
1074 std::unique_ptr<Expr> array_expr,
1075 std::unique_ptr<Expr> array_index_expr,
1076 AST::AttrVec outer_attribs, Location locus)
1077 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
1078 array_expr (std::move (array_expr)),
1079 index_expr (std::move (array_index_expr)), locus (locus)
1080 {}
1081
1082 // Copy constructor requires special cloning due to unique_ptr
1083 ArrayIndexExpr (ArrayIndexExpr const &other)
1084 : ExprWithoutBlock (other), array_expr (other.array_expr->clone_expr ()),
1085 index_expr (other.index_expr->clone_expr ()), locus (other.locus)
1086 {}
1087
1088 // Overload assignment operator to clone unique_ptrs
1089 ArrayIndexExpr &operator= (ArrayIndexExpr const &other)
1090 {
1091 ExprWithoutBlock::operator= (other);
1092 array_expr = other.array_expr->clone_expr ();
1093 index_expr = other.index_expr->clone_expr ();
1094 // outer_attrs = other.outer_attrs;
1095 locus = other.locus;
1096
1097 return *this;
1098 }
1099
1100 // move constructors
1101 ArrayIndexExpr (ArrayIndexExpr &&other) = default;
1102 ArrayIndexExpr &operator= (ArrayIndexExpr &&other) = default;
1103
1104 Location get_locus () const override final { return locus; }
1105
1106 void accept_vis (HIRFullVisitor &vis) override;
1107 void accept_vis (HIRExpressionVisitor &vis) override;
1108
1109 Expr *get_array_expr () { return array_expr.get (); }
1110 Expr *get_index_expr () { return index_expr.get (); }
1111
1112 ExprType get_expression_type () const override final
1113 {
1114 return ExprType::ArrayIndex;
1115 }
1116
1117 protected:
1118 /* Use covariance to implement clone function as returning this object rather
1119 * than base */
1120 ArrayIndexExpr *clone_expr_impl () const override
1121 {
1122 return new ArrayIndexExpr (*this);
1123 }
1124
1125 /* Use covariance to implement clone function as returning this object rather
1126 * than base */
1127 ArrayIndexExpr *clone_expr_without_block_impl () const override
1128 {
1129 return new ArrayIndexExpr (*this);
1130 }
1131 };
1132
1133 // HIR representation of a tuple
1134 class TupleExpr : public ExprWithoutBlock
1135 {
1136 AST::AttrVec inner_attrs;
1137
1138 std::vector<std::unique_ptr<Expr> > tuple_elems;
1139 // replaces (inlined version of) TupleElements
1140
1141 Location locus;
1142
1143 public:
1144 std::string as_string () const override;
1145
1146 AST::AttrVec get_inner_attrs () const { return inner_attrs; }
1147
1148 TupleExpr (Analysis::NodeMapping mappings,
1149 std::vector<std::unique_ptr<Expr> > tuple_elements,
1150 AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
1151 Location locus)
1152 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
1153 inner_attrs (std::move (inner_attribs)),
1154 tuple_elems (std::move (tuple_elements)), locus (locus)
1155 {}
1156
1157 // copy constructor with vector clone
1158 TupleExpr (TupleExpr const &other)
1159 : ExprWithoutBlock (other), inner_attrs (other.inner_attrs),
1160 locus (other.locus)
1161 {
1162 tuple_elems.reserve (other.tuple_elems.size ());
1163 for (const auto &e : other.tuple_elems)
1164 tuple_elems.push_back (e->clone_expr ());
1165 }
1166
1167 // overloaded assignment operator to vector clone
1168 TupleExpr &operator= (TupleExpr const &other)
1169 {
1170 ExprWithoutBlock::operator= (other);
1171 inner_attrs = other.inner_attrs;
1172 locus = other.locus;
1173
1174 tuple_elems.reserve (other.tuple_elems.size ());
1175 for (const auto &e : other.tuple_elems)
1176 tuple_elems.push_back (e->clone_expr ());
1177
1178 return *this;
1179 }
1180
1181 // move constructors
1182 TupleExpr (TupleExpr &&other) = default;
1183 TupleExpr &operator= (TupleExpr &&other) = default;
1184
1185 /* Note: syntactically, can disambiguate single-element tuple from parens with
1186 * comma, i.e. (0,) rather than (0) */
1187
1188 Location get_locus () const override final { return locus; }
1189
1190 void accept_vis (HIRFullVisitor &vis) override;
1191 void accept_vis (HIRExpressionVisitor &vis) override;
1192
1193 const std::vector<std::unique_ptr<Expr> > &get_tuple_elems () const
1194 {
1195 return tuple_elems;
1196 }
1197 std::vector<std::unique_ptr<Expr> > &get_tuple_elems ()
1198 {
1199 return tuple_elems;
1200 }
1201
1202 bool is_unit () const { return tuple_elems.size () == 0; }
1203
1204 ExprType get_expression_type () const override final
1205 {
1206 return ExprType::Tuple;
1207 }
1208
1209 protected:
1210 /* Use covariance to implement clone function as returning this object rather
1211 * than base */
1212 TupleExpr *clone_expr_impl () const override { return new TupleExpr (*this); }
1213
1214 /* Use covariance to implement clone function as returning this object rather
1215 * than base */
1216 TupleExpr *clone_expr_without_block_impl () const override
1217 {
1218 return new TupleExpr (*this);
1219 }
1220 };
1221
1222 class TupleIndexExpr : public ExprWithoutBlock
1223 {
1224 std::unique_ptr<Expr> tuple_expr;
1225 TupleIndex tuple_index;
1226 Location locus;
1227
1228 public:
1229 std::string as_string () const override;
1230
1231 TupleIndex get_tuple_index () const { return tuple_index; }
1232
1233 TupleIndexExpr (Analysis::NodeMapping mappings,
1234 std::unique_ptr<Expr> tuple_expr, TupleIndex index,
1235 AST::AttrVec outer_attribs, Location locus)
1236 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
1237 tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus)
1238 {}
1239
1240 // Copy constructor requires a clone for tuple_expr
1241 TupleIndexExpr (TupleIndexExpr const &other)
1242 : ExprWithoutBlock (other), tuple_expr (other.tuple_expr->clone_expr ()),
1243 tuple_index (other.tuple_index), locus (other.locus)
1244 {}
1245
1246 // Overload assignment operator in order to clone
1247 TupleIndexExpr &operator= (TupleIndexExpr const &other)
1248 {
1249 ExprWithoutBlock::operator= (other);
1250 tuple_expr = other.tuple_expr->clone_expr ();
1251 tuple_index = other.tuple_index;
1252 locus = other.locus;
1253 // outer_attrs = other.outer_attrs;
1254
1255 return *this;
1256 }
1257
1258 // move constructors
1259 TupleIndexExpr (TupleIndexExpr &&other) = default;
1260 TupleIndexExpr &operator= (TupleIndexExpr &&other) = default;
1261
1262 Location get_locus () const override final { return locus; }
1263
1264 void accept_vis (HIRFullVisitor &vis) override;
1265 void accept_vis (HIRExpressionVisitor &vis) override;
1266
1267 std::unique_ptr<Expr> &get_tuple_expr ()
1268 {
1269 rust_assert (tuple_expr != nullptr);
1270 return tuple_expr;
1271 }
1272
1273 ExprType get_expression_type () const override final
1274 {
1275 return ExprType::TupleIdx;
1276 }
1277
1278 protected:
1279 /* Use covariance to implement clone function as returning this object rather
1280 * than base */
1281 TupleIndexExpr *clone_expr_impl () const override
1282 {
1283 return new TupleIndexExpr (*this);
1284 }
1285
1286 /* Use covariance to implement clone function as returning this object rather
1287 * than base */
1288 TupleIndexExpr *clone_expr_without_block_impl () const override
1289 {
1290 return new TupleIndexExpr (*this);
1291 }
1292 };
1293
1294 // Base struct/tuple/union value creator HIR node (abstract)
1295 class StructExpr : public ExprWithoutBlock
1296 {
1297 protected:
1298 PathInExpression struct_name;
1299
1300 // Protected constructor to allow initialising struct_name
1301 StructExpr (Analysis::NodeMapping mappings, PathInExpression struct_path,
1302 AST::AttrVec outer_attribs)
1303 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
1304 struct_name (std::move (struct_path))
1305 {}
1306
1307 public:
1308 PathInExpression &get_struct_name () { return struct_name; }
1309
1310 std::string as_string () const override;
1311
1312 ExprType get_expression_type () const override final
1313 {
1314 return ExprType::Struct;
1315 }
1316 };
1317
1318 // Actual HIR node of the struct creator (with no fields). Not abstract!
1319 class StructExprStruct : public StructExpr
1320 {
1321 AST::AttrVec inner_attrs;
1322
1323 Location locus;
1324
1325 public:
1326 std::string as_string () const override;
1327
1328 AST::AttrVec get_inner_attrs () const { return inner_attrs; }
1329
1330 // Constructor has to call protected constructor of base class
1331 StructExprStruct (Analysis::NodeMapping mappings,
1332 PathInExpression struct_path, AST::AttrVec inner_attribs,
1333 AST::AttrVec outer_attribs, Location locus)
1334 : StructExpr (std::move (mappings), std::move (struct_path),
1335 std::move (outer_attribs)),
1336 inner_attrs (std::move (inner_attribs)), locus (locus)
1337 {}
1338
1339 Location get_locus () const override final { return locus; }
1340
1341 void accept_vis (HIRFullVisitor &vis) override;
1342 void accept_vis (HIRExpressionVisitor &vis) override;
1343
1344 protected:
1345 /* Use covariance to implement clone function as returning this object rather
1346 * than base */
1347 StructExprStruct *clone_expr_impl () const override
1348 {
1349 return new StructExprStruct (*this);
1350 }
1351
1352 /* Use covariance to implement clone function as returning this object rather
1353 * than base */
1354 StructExprStruct *clone_expr_without_block_impl () const override
1355 {
1356 return new StructExprStruct (*this);
1357 }
1358 };
1359
1360 /* HIR node representing expression used to fill a struct's fields from another
1361 * struct */
1362 struct StructBase
1363 {
1364 public:
1365 std::unique_ptr<Expr> base_struct;
1366
1367 // TODO: should this store location data?
1368 StructBase (std::unique_ptr<Expr> base_struct_ptr)
1369 : base_struct (std::move (base_struct_ptr))
1370 {}
1371
1372 // Copy constructor requires clone
1373 StructBase (StructBase const &other)
1374 {
1375 /* HACK: gets around base_struct pointer being null (e.g. if no struct base
1376 * exists) */
1377 if (other.base_struct != nullptr)
1378 other.base_struct->clone_expr ();
1379 }
1380
1381 // Destructor
1382 ~StructBase () = default;
1383
1384 // Overload assignment operator to clone base_struct
1385 StructBase &operator= (StructBase const &other)
1386 {
1387 base_struct = other.base_struct->clone_expr ();
1388
1389 return *this;
1390 }
1391
1392 // move constructors
1393 StructBase (StructBase &&other) = default;
1394 StructBase &operator= (StructBase &&other) = default;
1395
1396 // Returns a null expr-ed StructBase - error state
1397 static StructBase error () { return StructBase (nullptr); }
1398
1399 // Returns whether StructBase is in error state
1400 bool is_invalid () const { return base_struct == nullptr; }
1401
1402 std::string as_string () const;
1403
1404 Expr *get_base () { return base_struct.get (); }
1405 };
1406
1407 /* Base HIR node for a single struct expression field (in struct instance
1408 * creation) - abstract */
1409 class StructExprField
1410 {
1411 public:
1412 enum StructExprFieldKind
1413 {
1414 IDENTIFIER_VALUE,
1415 IDENTIFIER,
1416 INDEX_VALUE,
1417 };
1418
1419 virtual ~StructExprField () {}
1420
1421 // Unique pointer custom clone function
1422 std::unique_ptr<StructExprField> clone_struct_expr_field () const
1423 {
1424 return std::unique_ptr<StructExprField> (clone_struct_expr_field_impl ());
1425 }
1426
1427 virtual std::string as_string () const = 0;
1428
1429 virtual void accept_vis (HIRFullVisitor &vis) = 0;
1430 virtual void accept_vis (HIRExpressionVisitor &vis) = 0;
1431
1432 Analysis::NodeMapping &get_mappings () { return mappings; }
1433
1434 Location get_locus () { return locus; }
1435
1436 virtual StructExprFieldKind get_kind () const = 0;
1437
1438 protected:
1439 // pure virtual clone implementation
1440 virtual StructExprField *clone_struct_expr_field_impl () const = 0;
1441
1442 StructExprField (Analysis::NodeMapping mapping, Location locus)
1443 : mappings (mapping), locus (locus)
1444 {}
1445
1446 Analysis::NodeMapping mappings;
1447 Location locus;
1448 };
1449
1450 // Identifier-only variant of StructExprField HIR node
1451 class StructExprFieldIdentifier : public StructExprField
1452 {
1453 private:
1454 Identifier field_name;
1455
1456 // TODO: should this store location data?
1457 public:
1458 StructExprFieldIdentifier (Analysis::NodeMapping mapping,
1459 Identifier field_identifier, Location locus)
1460 : StructExprField (mapping, locus),
1461 field_name (std::move (field_identifier))
1462 {}
1463
1464 std::string as_string () const override { return field_name; }
1465
1466 void accept_vis (HIRFullVisitor &vis) override;
1467 void accept_vis (HIRExpressionVisitor &vis) override;
1468
1469 Identifier get_field_name () const { return field_name; }
1470
1471 StructExprFieldKind get_kind () const override
1472 {
1473 return StructExprFieldKind::IDENTIFIER;
1474 }
1475
1476 protected:
1477 /* Use covariance to implement clone function as returning this object rather
1478 * than base */
1479 StructExprFieldIdentifier *clone_struct_expr_field_impl () const override
1480 {
1481 return new StructExprFieldIdentifier (*this);
1482 }
1483 };
1484
1485 /* Base HIR node for a single struct expression field with an assigned value -
1486 * abstract */
1487 class StructExprFieldWithVal : public StructExprField
1488 {
1489 std::unique_ptr<Expr> value;
1490
1491 protected:
1492 StructExprFieldWithVal (Analysis::NodeMapping mapping,
1493 std::unique_ptr<Expr> field_value, Location locus)
1494 : StructExprField (mapping, locus), value (std::move (field_value))
1495 {}
1496
1497 // Copy constructor requires clone
1498 StructExprFieldWithVal (StructExprFieldWithVal const &other)
1499 : StructExprField (other.mappings, other.locus),
1500 value (other.value->clone_expr ())
1501 {}
1502
1503 // Overload assignment operator to clone unique_ptr
1504 StructExprFieldWithVal &operator= (StructExprFieldWithVal const &other)
1505 {
1506 value = other.value->clone_expr ();
1507 mappings = other.mappings;
1508 locus = other.locus;
1509
1510 return *this;
1511 }
1512
1513 // move constructors
1514 StructExprFieldWithVal (StructExprFieldWithVal &&other) = default;
1515 StructExprFieldWithVal &operator= (StructExprFieldWithVal &&other) = default;
1516
1517 public:
1518 std::string as_string () const override;
1519
1520 Expr *get_value () { return value.get (); }
1521 };
1522
1523 // Identifier and value variant of StructExprField HIR node
1524 class StructExprFieldIdentifierValue : public StructExprFieldWithVal
1525 {
1526 public:
1527 Identifier field_name;
1528
1529 // TODO: should this store location data?
1530
1531 StructExprFieldIdentifierValue (Analysis::NodeMapping mapping,
1532 Identifier field_identifier,
1533 std::unique_ptr<Expr> field_value,
1534 Location locus)
1535 : StructExprFieldWithVal (mapping, std::move (field_value), locus),
1536 field_name (std::move (field_identifier))
1537 {}
1538
1539 std::string as_string () const override;
1540
1541 void accept_vis (HIRFullVisitor &vis) override;
1542 void accept_vis (HIRExpressionVisitor &vis) override;
1543
1544 StructExprFieldKind get_kind () const override
1545 {
1546 return StructExprFieldKind::IDENTIFIER_VALUE;
1547 }
1548
1549 protected:
1550 /* Use covariance to implement clone function as returning this object rather
1551 * than base */
1552 StructExprFieldIdentifierValue *clone_struct_expr_field_impl () const override
1553 {
1554 return new StructExprFieldIdentifierValue (*this);
1555 }
1556 };
1557
1558 // Tuple index and value variant of StructExprField HIR node
1559 class StructExprFieldIndexValue : public StructExprFieldWithVal
1560 {
1561 public:
1562 TupleIndex index;
1563
1564 // TODO: should this store location data?
1565
1566 StructExprFieldIndexValue (Analysis::NodeMapping mapping,
1567 TupleIndex tuple_index,
1568 std::unique_ptr<Expr> field_value, Location locus)
1569 : StructExprFieldWithVal (mapping, std::move (field_value), locus),
1570 index (tuple_index)
1571 {}
1572
1573 std::string as_string () const override;
1574
1575 TupleIndex get_tuple_index () const { return index; };
1576
1577 void accept_vis (HIRFullVisitor &vis) override;
1578 void accept_vis (HIRExpressionVisitor &vis) override;
1579
1580 StructExprFieldKind get_kind () const override
1581 {
1582 return StructExprFieldKind::INDEX_VALUE;
1583 }
1584
1585 protected:
1586 /* Use covariance to implement clone function as returning this object rather
1587 * than base */
1588 StructExprFieldIndexValue *clone_struct_expr_field_impl () const override
1589 {
1590 return new StructExprFieldIndexValue (*this);
1591 }
1592 };
1593
1594 // HIR node of a struct creator with fields
1595 class StructExprStructFields : public StructExprStruct
1596 {
1597 public:
1598 // std::vector<StructExprField> fields;
1599 std::vector<std::unique_ptr<StructExprField> > fields;
1600
1601 // bool has_struct_base;
1602 // FIXME make unique_ptr
1603 StructBase *struct_base;
1604
1605 // For unions there is just one field, the index
1606 // is set when type checking
1607 int union_index = -1;
1608
1609 std::string as_string () const override;
1610
1611 bool has_struct_base () const { return struct_base != nullptr; }
1612
1613 // Constructor for StructExprStructFields when no struct base is used
1614 StructExprStructFields (
1615 Analysis::NodeMapping mappings, PathInExpression struct_path,
1616 std::vector<std::unique_ptr<StructExprField> > expr_fields, Location locus,
1617 StructBase *base_struct, AST::AttrVec inner_attribs = AST::AttrVec (),
1618 AST::AttrVec outer_attribs = AST::AttrVec ())
1619 : StructExprStruct (std::move (mappings), std::move (struct_path),
1620 std::move (inner_attribs), std::move (outer_attribs),
1621 locus),
1622 fields (std::move (expr_fields)), struct_base (base_struct)
1623 {}
1624
1625 // copy constructor with vector clone
1626 StructExprStructFields (StructExprStructFields const &other)
1627 : StructExprStruct (other), struct_base (other.struct_base),
1628 union_index (other.union_index)
1629 {
1630 fields.reserve (other.fields.size ());
1631 for (const auto &e : other.fields)
1632 fields.push_back (e->clone_struct_expr_field ());
1633 }
1634
1635 // overloaded assignment operator with vector clone
1636 StructExprStructFields &operator= (StructExprStructFields const &other)
1637 {
1638 StructExprStruct::operator= (other);
1639 struct_base = other.struct_base;
1640 union_index = other.union_index;
1641
1642 fields.reserve (other.fields.size ());
1643 for (const auto &e : other.fields)
1644 fields.push_back (e->clone_struct_expr_field ());
1645
1646 return *this;
1647 }
1648
1649 // move constructors
1650 StructExprStructFields (StructExprStructFields &&other) = default;
1651 StructExprStructFields &operator= (StructExprStructFields &&other) = default;
1652
1653 void accept_vis (HIRFullVisitor &vis) override;
1654 void accept_vis (HIRExpressionVisitor &vis) override;
1655
1656 std::vector<std::unique_ptr<StructExprField> > &get_fields ()
1657 {
1658 return fields;
1659 };
1660
1661 const std::vector<std::unique_ptr<StructExprField> > &get_fields () const
1662 {
1663 return fields;
1664 };
1665
1666 void set_fields_as_owner (
1667 std::vector<std::unique_ptr<StructExprField> > new_fields)
1668 {
1669 fields = std::move (new_fields);
1670 }
1671
1672 protected:
1673 /* Use covariance to implement clone function as returning this object rather
1674 * than base */
1675 StructExprStructFields *clone_expr_impl () const override
1676 {
1677 return new StructExprStructFields (*this);
1678 }
1679
1680 /* Use covariance to implement clone function as returning this object rather
1681 * than base */
1682 StructExprStructFields *clone_expr_without_block_impl () const override
1683 {
1684 return new StructExprStructFields (*this);
1685 }
1686 };
1687
1688 // HIR node of the functional update struct creator
1689 class StructExprStructBase : public StructExprStruct
1690 {
1691 StructBase struct_base;
1692
1693 public:
1694 std::string as_string () const override;
1695
1696 /*inline StructBase get_struct_base() const {
1697 return struct_base;
1698 }*/
1699
1700 StructExprStructBase (Analysis::NodeMapping mappings,
1701 PathInExpression struct_path, StructBase base_struct,
1702 AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
1703 Location locus)
1704 : StructExprStruct (std::move (mappings), std::move (struct_path),
1705 std::move (inner_attribs), std::move (outer_attribs),
1706 locus),
1707 struct_base (std::move (base_struct))
1708 {}
1709
1710 void accept_vis (HIRFullVisitor &vis) override;
1711 void accept_vis (HIRExpressionVisitor &vis) override;
1712
1713 StructBase *get_struct_base () { return &struct_base; }
1714
1715 protected:
1716 /* Use covariance to implement clone function as returning this object rather
1717 * than base */
1718 StructExprStructBase *clone_expr_impl () const override
1719 {
1720 return new StructExprStructBase (*this);
1721 }
1722
1723 /* Use covariance to implement clone function as returning this object rather
1724 * than base */
1725 StructExprStructBase *clone_expr_without_block_impl () const override
1726 {
1727 return new StructExprStructBase (*this);
1728 }
1729 };
1730
1731 // Function call expression HIR node
1732 class CallExpr : public ExprWithoutBlock
1733 {
1734 std::unique_ptr<Expr> function;
1735 std::vector<std::unique_ptr<Expr> > params;
1736 Location locus;
1737
1738 public:
1739 std::string as_string () const override;
1740
1741 CallExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> function_expr,
1742 std::vector<std::unique_ptr<Expr> > function_params,
1743 AST::AttrVec outer_attribs, Location locus)
1744 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
1745 function (std::move (function_expr)),
1746 params (std::move (function_params)), locus (locus)
1747 {}
1748
1749 // copy constructor requires clone
1750 CallExpr (CallExpr const &other)
1751 : ExprWithoutBlock (other), function (other.function->clone_expr ()),
1752 locus (other.locus)
1753 /*, params(other.params),*/ {
1754 params.reserve (other.params.size ());
1755 for (const auto &e : other.params)
1756 params.push_back (e->clone_expr ());
1757 }
1758
1759 // Overload assignment operator to clone
1760 CallExpr &operator= (CallExpr const &other)
1761 {
1762 ExprWithoutBlock::operator= (other);
1763 function = other.function->clone_expr ();
1764 locus = other.locus;
1765 // params = other.params;
1766 // outer_attrs = other.outer_attrs;
1767
1768 params.reserve (other.params.size ());
1769 for (const auto &e : other.params)
1770 params.push_back (e->clone_expr ());
1771
1772 return *this;
1773 }
1774
1775 // move constructors
1776 CallExpr (CallExpr &&other) = default;
1777 CallExpr &operator= (CallExpr &&other) = default;
1778
1779 // Returns whether function call has parameters.
1780 bool has_params () const { return !params.empty (); }
1781
1782 Location get_locus () const override final { return locus; }
1783
1784 void accept_vis (HIRFullVisitor &vis) override;
1785 void accept_vis (HIRExpressionVisitor &vis) override;
1786
1787 Expr *get_fnexpr () { return function.get (); }
1788
1789 size_t num_params () const { return params.size (); }
1790
1791 std::vector<std::unique_ptr<Expr> > &get_arguments () { return params; }
1792
1793 const std::vector<std::unique_ptr<Expr> > &get_arguments () const
1794 {
1795 return params;
1796 }
1797
1798 ExprType get_expression_type () const override final
1799 {
1800 return ExprType::Call;
1801 }
1802
1803 protected:
1804 /* Use covariance to implement clone function as returning this object rather
1805 * than base */
1806 CallExpr *clone_expr_impl () const override { return new CallExpr (*this); }
1807
1808 /* Use covariance to implement clone function as returning this object rather
1809 * than base */
1810 CallExpr *clone_expr_without_block_impl () const override
1811 {
1812 return new CallExpr (*this);
1813 }
1814 };
1815
1816 // Method call expression HIR node
1817 class MethodCallExpr : public ExprWithoutBlock
1818 {
1819 std::unique_ptr<Expr> receiver;
1820 PathExprSegment method_name;
1821 std::vector<std::unique_ptr<Expr> > params;
1822 Location locus;
1823
1824 public:
1825 std::string as_string () const override;
1826
1827 MethodCallExpr (Analysis::NodeMapping mappings,
1828 std::unique_ptr<Expr> call_receiver,
1829 PathExprSegment method_path,
1830 std::vector<std::unique_ptr<Expr> > method_params,
1831 AST::AttrVec outer_attribs, Location locus)
1832 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
1833 receiver (std::move (call_receiver)),
1834 method_name (std::move (method_path)), params (std::move (method_params)),
1835 locus (locus)
1836 {}
1837
1838 // copy constructor required due to cloning
1839 MethodCallExpr (MethodCallExpr const &other)
1840 : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()),
1841 method_name (other.method_name), locus (other.locus)
1842 /*, params(other.params),*/ {
1843 params.reserve (other.params.size ());
1844 for (const auto &e : other.params)
1845 params.push_back (e->clone_expr ());
1846 }
1847
1848 // Overload assignment operator to clone receiver object
1849 MethodCallExpr &operator= (MethodCallExpr const &other)
1850 {
1851 ExprWithoutBlock::operator= (other);
1852 receiver = other.receiver->clone_expr ();
1853 method_name = other.method_name;
1854 locus = other.locus;
1855 // params = other.params;
1856 // outer_attrs = other.outer_attrs;
1857
1858 params.reserve (other.params.size ());
1859 for (const auto &e : other.params)
1860 params.push_back (e->clone_expr ());
1861
1862 return *this;
1863 }
1864
1865 // move constructors
1866 MethodCallExpr (MethodCallExpr &&other) = default;
1867 MethodCallExpr &operator= (MethodCallExpr &&other) = default;
1868
1869 Location get_locus () const override final { return locus; }
1870
1871 void accept_vis (HIRFullVisitor &vis) override;
1872 void accept_vis (HIRExpressionVisitor &vis) override;
1873
1874 std::unique_ptr<Expr> &get_receiver () { return receiver; }
1875
1876 PathExprSegment get_method_name () const { return method_name; };
1877
1878 size_t num_params () const { return params.size (); }
1879
1880 std::vector<std::unique_ptr<Expr> > &get_arguments () { return params; }
1881
1882 const std::vector<std::unique_ptr<Expr> > &get_arguments () const
1883 {
1884 return params;
1885 }
1886
1887 ExprType get_expression_type () const override final
1888 {
1889 return ExprType::MethodCall;
1890 }
1891
1892 protected:
1893 /* Use covariance to implement clone function as returning this object rather
1894 * than base */
1895 MethodCallExpr *clone_expr_impl () const override
1896 {
1897 return new MethodCallExpr (*this);
1898 }
1899
1900 /* Use covariance to implement clone function as returning this object rather
1901 * than base */
1902 MethodCallExpr *clone_expr_without_block_impl () const override
1903 {
1904 return new MethodCallExpr (*this);
1905 }
1906 };
1907
1908 // aka FieldExpression
1909 // Struct or union field access expression HIR node
1910 class FieldAccessExpr : public ExprWithoutBlock
1911 {
1912 std::unique_ptr<Expr> receiver;
1913 Identifier field;
1914
1915 Location locus;
1916
1917 public:
1918 std::string as_string () const override;
1919
1920 FieldAccessExpr (Analysis::NodeMapping mappings,
1921 std::unique_ptr<Expr> field_access_receiver,
1922 Identifier field_name, AST::AttrVec outer_attribs,
1923 Location locus)
1924 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
1925 receiver (std::move (field_access_receiver)),
1926 field (std::move (field_name)), locus (locus)
1927 {}
1928
1929 // Copy constructor required due to unique_ptr cloning
1930 FieldAccessExpr (FieldAccessExpr const &other)
1931 : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()),
1932 field (other.field), locus (other.locus)
1933 {}
1934
1935 // Overload assignment operator to clone unique_ptr
1936 FieldAccessExpr &operator= (FieldAccessExpr const &other)
1937 {
1938 ExprWithoutBlock::operator= (other);
1939 receiver = other.receiver->clone_expr ();
1940 field = other.field;
1941 locus = other.locus;
1942 // outer_attrs = other.outer_attrs;
1943
1944 return *this;
1945 }
1946
1947 // move constructors
1948 FieldAccessExpr (FieldAccessExpr &&other) = default;
1949 FieldAccessExpr &operator= (FieldAccessExpr &&other) = default;
1950
1951 Location get_locus () const override final { return locus; }
1952
1953 void accept_vis (HIRFullVisitor &vis) override;
1954 void accept_vis (HIRExpressionVisitor &vis) override;
1955
1956 std::unique_ptr<Expr> &get_receiver_expr ()
1957 {
1958 rust_assert (receiver != nullptr);
1959 return receiver;
1960 }
1961
1962 Identifier get_field_name () const { return field; }
1963
1964 ExprType get_expression_type () const override final
1965 {
1966 return ExprType::FieldAccess;
1967 }
1968
1969 protected:
1970 /* Use covariance to implement clone function as returning this object rather
1971 * than base */
1972 FieldAccessExpr *clone_expr_impl () const override
1973 {
1974 return new FieldAccessExpr (*this);
1975 }
1976
1977 /* Use covariance to implement clone function as returning this object rather
1978 * than base */
1979 FieldAccessExpr *clone_expr_without_block_impl () const override
1980 {
1981 return new FieldAccessExpr (*this);
1982 }
1983 };
1984
1985 // Closure parameter data structure
1986 struct ClosureParam
1987 {
1988 private:
1989 std::unique_ptr<Pattern> pattern;
1990
1991 // bool has_type_given;
1992 std::unique_ptr<Type> type;
1993
1994 // TODO: should this store location data?
1995
1996 public:
1997 // Returns whether the type of the parameter has been given.
1998 bool has_type_given () const { return type != nullptr; }
1999
2000 // Constructor for closure parameter
2001 ClosureParam (std::unique_ptr<Pattern> param_pattern,
2002 std::unique_ptr<Type> param_type = nullptr)
2003 : pattern (std::move (param_pattern)), type (std::move (param_type))
2004 {}
2005
2006 // Copy constructor required due to cloning as a result of unique_ptrs
2007 ClosureParam (ClosureParam const &other)
2008 : pattern (other.pattern->clone_pattern ())
2009 {
2010 // guard to protect from null pointer dereference
2011 if (other.type != nullptr)
2012 type = other.type->clone_type ();
2013 }
2014
2015 ~ClosureParam () = default;
2016
2017 // Assignment operator must be overloaded to clone as well
2018 ClosureParam &operator= (ClosureParam const &other)
2019 {
2020 pattern = other.pattern->clone_pattern ();
2021 type = other.type->clone_type ();
2022
2023 return *this;
2024 }
2025
2026 // move constructors
2027 ClosureParam (ClosureParam &&other) = default;
2028 ClosureParam &operator= (ClosureParam &&other) = default;
2029
2030 // Returns whether closure parameter is in an error state.
2031 bool is_error () const { return pattern == nullptr; }
2032
2033 // Creates an error state closure parameter.
2034 static ClosureParam create_error () { return ClosureParam (nullptr); }
2035
2036 std::string as_string () const;
2037 };
2038
2039 // Base closure definition expression HIR node - abstract
2040 class ClosureExpr : public ExprWithoutBlock
2041 {
2042 bool has_move;
2043 std::vector<ClosureParam> params;
2044 Location locus;
2045
2046 protected:
2047 ClosureExpr (Analysis::NodeMapping mappings,
2048 std::vector<ClosureParam> closure_params, bool has_move,
2049 AST::AttrVec outer_attribs, Location locus)
2050 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
2051 has_move (has_move), params (std::move (closure_params)), locus (locus)
2052 {}
2053
2054 public:
2055 std::string as_string () const override;
2056
2057 Location get_locus () const override final { return locus; }
2058
2059 ExprType get_expression_type () const override final
2060 {
2061 return ExprType::Closure;
2062 }
2063 };
2064
2065 // Represents a non-type-specified closure expression HIR node
2066 class ClosureExprInner : public ClosureExpr
2067 {
2068 std::unique_ptr<Expr> closure_inner;
2069
2070 public:
2071 std::string as_string () const override;
2072
2073 // Constructor for a ClosureExprInner
2074 ClosureExprInner (Analysis::NodeMapping mappings,
2075 std::unique_ptr<Expr> closure_inner_expr,
2076 std::vector<ClosureParam> closure_params, Location locus,
2077 bool is_move = false,
2078 AST::AttrVec outer_attribs = AST::AttrVec ())
2079 : ClosureExpr (std::move (mappings), std::move (closure_params), is_move,
2080 std::move (outer_attribs), locus),
2081 closure_inner (std::move (closure_inner_expr))
2082 {}
2083
2084 // Copy constructor must be defined to allow copying via cloning of unique_ptr
2085 ClosureExprInner (ClosureExprInner const &other)
2086 : ClosureExpr (other), closure_inner (other.closure_inner->clone_expr ())
2087 {}
2088
2089 // Overload assignment operator to clone closure_inner
2090 ClosureExprInner &operator= (ClosureExprInner const &other)
2091 {
2092 ClosureExpr::operator= (other);
2093 closure_inner = other.closure_inner->clone_expr ();
2094 // params = other.params;
2095 // has_move = other.has_move;
2096 // outer_attrs = other.outer_attrs;
2097
2098 return *this;
2099 }
2100
2101 // move constructors
2102 ClosureExprInner (ClosureExprInner &&other) = default;
2103 ClosureExprInner &operator= (ClosureExprInner &&other) = default;
2104
2105 void accept_vis (HIRFullVisitor &vis) override;
2106 void accept_vis (HIRExpressionVisitor &vis) override;
2107
2108 protected:
2109 /* Use covariance to implement clone function as returning this object rather
2110 * than base */
2111 ClosureExprInner *clone_expr_impl () const override
2112 {
2113 return new ClosureExprInner (*this);
2114 }
2115
2116 /* Use covariance to implement clone function as returning this object rather
2117 * than base */
2118 ClosureExprInner *clone_expr_without_block_impl () const override
2119 {
2120 return new ClosureExprInner (*this);
2121 }
2122 };
2123
2124 // A block HIR node
2125 class BlockExpr : public ExprWithBlock
2126 {
2127 public:
2128 AST::AttrVec inner_attrs;
2129 std::vector<std::unique_ptr<Stmt> > statements;
2130 std::unique_ptr<Expr> expr;
2131 bool tail_reachable;
2132 Location start_locus;
2133 Location end_locus;
2134
2135 std::string as_string () const override;
2136
2137 // Returns whether the block contains statements.
2138 bool has_statements () const { return !statements.empty (); }
2139
2140 // Returns whether the block contains an expression
2141 bool has_expr () const { return expr != nullptr; }
2142
2143 bool is_tail_reachable () const { return tail_reachable; }
2144
2145 BlockExpr (Analysis::NodeMapping mappings,
2146 std::vector<std::unique_ptr<Stmt> > block_statements,
2147 std::unique_ptr<Expr> block_expr, bool tail_reachable,
2148 AST::AttrVec inner_attribs, AST::AttrVec outer_attribs,
2149 Location start_locus, Location end_locus)
2150 : ExprWithBlock (std::move (mappings), std::move (outer_attribs)),
2151 inner_attrs (std::move (inner_attribs)),
2152 statements (std::move (block_statements)), expr (std::move (block_expr)),
2153 tail_reachable (tail_reachable), start_locus (start_locus),
2154 end_locus (end_locus)
2155 {}
2156
2157 // Copy constructor with clone
2158 BlockExpr (BlockExpr const &other)
2159 : ExprWithBlock (other), /*statements(other.statements),*/
2160 inner_attrs (other.inner_attrs), start_locus (other.start_locus),
2161 end_locus (other.end_locus)
2162 {
2163 // guard to protect from null pointer dereference
2164 if (other.expr != nullptr)
2165 expr = other.expr->clone_expr ();
2166
2167 statements.reserve (other.statements.size ());
2168 for (const auto &e : other.statements)
2169 statements.push_back (e->clone_stmt ());
2170 }
2171
2172 // Overloaded assignment operator to clone pointer
2173 BlockExpr &operator= (BlockExpr const &other)
2174 {
2175 ExprWithBlock::operator= (other);
2176 // statements = other.statements;
2177 expr = other.expr->clone_expr ();
2178 inner_attrs = other.inner_attrs;
2179 start_locus = other.end_locus;
2180 end_locus = other.end_locus;
2181 // outer_attrs = other.outer_attrs;
2182
2183 statements.reserve (other.statements.size ());
2184 for (const auto &e : other.statements)
2185 statements.push_back (e->clone_stmt ());
2186
2187 return *this;
2188 }
2189
2190 // move constructors
2191 BlockExpr (BlockExpr &&other) = default;
2192 BlockExpr &operator= (BlockExpr &&other) = default;
2193
2194 // Unique pointer custom clone function
2195 std::unique_ptr<BlockExpr> clone_block_expr () const
2196 {
2197 return std::unique_ptr<BlockExpr> (clone_block_expr_impl ());
2198 }
2199
2200 Location get_locus () const override final { return start_locus; }
2201
2202 Location get_start_locus () const { return start_locus; }
2203
2204 Location get_end_locus () const { return end_locus; }
2205
2206 void accept_vis (HIRFullVisitor &vis) override;
2207 void accept_vis (HIRExpressionVisitor &vis) override;
2208
2209 bool is_final_stmt (Stmt *stmt) { return statements.back ().get () == stmt; }
2210
2211 std::unique_ptr<Expr> &get_final_expr () { return expr; }
2212
2213 std::vector<std::unique_ptr<Stmt> > &get_statements () { return statements; }
2214
2215 ExprType get_expression_type () const final override
2216 {
2217 return ExprType::Block;
2218 }
2219
2220 protected:
2221 /* Use covariance to implement clone function as returning this object rather
2222 * than base */
2223 BlockExpr *clone_expr_impl () const override
2224 {
2225 return clone_block_expr_impl ();
2226 }
2227
2228 /* Use covariance to implement clone function as returning this object rather
2229 * than base */
2230 BlockExpr *clone_expr_with_block_impl () const override
2231 {
2232 return clone_block_expr_impl ();
2233 }
2234
2235 /* This is the base method as not an abstract class - not virtual but could be
2236 * in future if required. */
2237 /*virtual*/ BlockExpr *clone_block_expr_impl () const
2238 {
2239 return new BlockExpr (*this);
2240 }
2241 };
2242
2243 // Represents a type-specified closure expression HIR node
2244 class ClosureExprInnerTyped : public ClosureExpr
2245 {
2246 std::unique_ptr<Type> return_type;
2247 std::unique_ptr<BlockExpr>
2248 expr; // only used because may be polymorphic in future
2249
2250 public:
2251 std::string as_string () const override;
2252
2253 // Constructor potentially with a move
2254 ClosureExprInnerTyped (Analysis::NodeMapping mappings,
2255 std::unique_ptr<Type> closure_return_type,
2256 std::unique_ptr<BlockExpr> closure_expr,
2257 std::vector<ClosureParam> closure_params,
2258 Location locus, bool is_move = false,
2259 AST::AttrVec outer_attribs = AST::AttrVec ())
2260 : ClosureExpr (std::move (mappings), std::move (closure_params), is_move,
2261 std::move (outer_attribs), locus),
2262 return_type (std::move (closure_return_type)),
2263 expr (std::move (closure_expr))
2264 {}
2265
2266 // Copy constructor requires cloning
2267 ClosureExprInnerTyped (ClosureExprInnerTyped const &other)
2268 : ClosureExpr (other), return_type (other.return_type->clone_type ()),
2269 expr (other.expr->clone_block_expr ())
2270 {}
2271
2272 // Overload assignment operator to clone unique_ptrs
2273 ClosureExprInnerTyped &operator= (ClosureExprInnerTyped const &other)
2274 {
2275 ClosureExpr::operator= (other);
2276 return_type = other.return_type->clone_type ();
2277 expr = other.expr->clone_block_expr ();
2278 // params = other.params;
2279 // has_move = other.has_move;
2280 // outer_attrs = other.outer_attrs;
2281
2282 return *this;
2283 }
2284
2285 // move constructors
2286 ClosureExprInnerTyped (ClosureExprInnerTyped &&other) = default;
2287 ClosureExprInnerTyped &operator= (ClosureExprInnerTyped &&other) = default;
2288
2289 void accept_vis (HIRFullVisitor &vis) override;
2290 void accept_vis (HIRExpressionVisitor &vis) override;
2291
2292 protected:
2293 /* Use covariance to implement clone function as returning this object rather
2294 * than base */
2295 ClosureExprInnerTyped *clone_expr_impl () const override
2296 {
2297 return new ClosureExprInnerTyped (*this);
2298 }
2299
2300 /* Use covariance to implement clone function as returning this object rather
2301 * than base */
2302 ClosureExprInnerTyped *clone_expr_without_block_impl () const override
2303 {
2304 return new ClosureExprInnerTyped (*this);
2305 }
2306 };
2307
2308 // HIR node representing continue expression within loops
2309 class ContinueExpr : public ExprWithoutBlock
2310 {
2311 Lifetime label;
2312 Location locus;
2313
2314 public:
2315 std::string as_string () const override;
2316
2317 // Returns true if the continue expr has a label.
2318 bool has_label () const { return !label.is_error (); }
2319
2320 // Constructor for a ContinueExpr with a label.
2321 ContinueExpr (Analysis::NodeMapping mappings, Location locus, Lifetime label,
2322 AST::AttrVec outer_attribs = AST::AttrVec ())
2323 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
2324 label (std::move (label)), locus (locus)
2325 {}
2326
2327 Location get_locus () const override final { return locus; }
2328
2329 void accept_vis (HIRFullVisitor &vis) override;
2330 void accept_vis (HIRExpressionVisitor &vis) override;
2331
2332 Lifetime &get_label () { return label; }
2333
2334 ExprType get_expression_type () const final override
2335 {
2336 return ExprType::Continue;
2337 }
2338
2339 protected:
2340 /* Use covariance to implement clone function as returning this object rather
2341 * than base */
2342 ContinueExpr *clone_expr_impl () const override
2343 {
2344 return new ContinueExpr (*this);
2345 }
2346
2347 /* Use covariance to implement clone function as returning this object rather
2348 * than base */
2349 ContinueExpr *clone_expr_without_block_impl () const override
2350 {
2351 return new ContinueExpr (*this);
2352 }
2353 };
2354
2355 // HIR node representing break expression within loops
2356 class BreakExpr : public ExprWithoutBlock
2357 {
2358 // bool has_label;
2359 Lifetime label;
2360
2361 // bool has_break_expr;
2362 std::unique_ptr<Expr> break_expr;
2363
2364 Location locus;
2365
2366 public:
2367 std::string as_string () const override;
2368
2369 // Returns whether the break expression has a label or not.
2370 bool has_label () const { return !label.is_error (); }
2371
2372 /* Returns whether the break expression has an expression used in the break or
2373 * not. */
2374 bool has_break_expr () const { return break_expr != nullptr; }
2375
2376 // Constructor for a break expression
2377 BreakExpr (Analysis::NodeMapping mappings, Location locus,
2378 Lifetime break_label,
2379 std::unique_ptr<Expr> expr_in_break = nullptr,
2380 AST::AttrVec outer_attribs = AST::AttrVec ())
2381 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
2382 label (std::move (break_label)), break_expr (std::move (expr_in_break)),
2383 locus (locus)
2384 {}
2385
2386 // Copy constructor defined to use clone for unique pointer
2387 BreakExpr (BreakExpr const &other)
2388 : ExprWithoutBlock (other), label (other.label), locus (other.locus)
2389 {
2390 // guard to protect from null pointer dereference
2391 if (other.break_expr != nullptr)
2392 break_expr = other.break_expr->clone_expr ();
2393 }
2394
2395 // Overload assignment operator to clone unique pointer
2396 BreakExpr &operator= (BreakExpr const &other)
2397 {
2398 ExprWithoutBlock::operator= (other);
2399 label = other.label;
2400 break_expr = other.break_expr->clone_expr ();
2401 locus = other.locus;
2402 // outer_attrs = other.outer_attrs;
2403
2404 return *this;
2405 }
2406
2407 // move constructors
2408 BreakExpr (BreakExpr &&other) = default;
2409 BreakExpr &operator= (BreakExpr &&other) = default;
2410
2411 Location get_locus () const override final { return locus; }
2412
2413 void accept_vis (HIRFullVisitor &vis) override;
2414 void accept_vis (HIRExpressionVisitor &vis) override;
2415
2416 Lifetime &get_label () { return label; }
2417
2418 std::unique_ptr<Expr> &get_expr () { return break_expr; }
2419
2420 ExprType get_expression_type () const override final
2421 {
2422 return ExprType::Break;
2423 }
2424
2425 protected:
2426 /* Use covariance to implement clone function as returning this object rather
2427 * than base */
2428 BreakExpr *clone_expr_impl () const override { return new BreakExpr (*this); }
2429
2430 /* Use covariance to implement clone function as returning this object rather
2431 * than base */
2432 BreakExpr *clone_expr_without_block_impl () const override
2433 {
2434 return new BreakExpr (*this);
2435 }
2436 };
2437
2438 // Base range expression HIR node object - abstract
2439 class RangeExpr : public ExprWithoutBlock
2440 {
2441 Location locus;
2442
2443 protected:
2444 // outer attributes not allowed before range expressions
2445 RangeExpr (Analysis::NodeMapping mappings, Location locus)
2446 : ExprWithoutBlock (std::move (mappings), AST::AttrVec ()), locus (locus)
2447 {}
2448
2449 public:
2450 Location get_locus () const override final { return locus; }
2451
2452 ExprType get_expression_type () const override final
2453 {
2454 return ExprType::Range;
2455 }
2456 };
2457
2458 // Range from (inclusive) and to (exclusive) expression HIR node object
2459 // aka RangeExpr; constructs a std::ops::Range object
2460 class RangeFromToExpr : public RangeExpr
2461 {
2462 std::unique_ptr<Expr> from;
2463 std::unique_ptr<Expr> to;
2464
2465 public:
2466 std::string as_string () const override;
2467
2468 RangeFromToExpr (Analysis::NodeMapping mappings,
2469 std::unique_ptr<Expr> range_from,
2470 std::unique_ptr<Expr> range_to, Location locus)
2471 : RangeExpr (std::move (mappings), locus), from (std::move (range_from)),
2472 to (std::move (range_to))
2473 {}
2474
2475 // Copy constructor with cloning
2476 RangeFromToExpr (RangeFromToExpr const &other)
2477 : RangeExpr (other), from (other.from->clone_expr ()),
2478 to (other.to->clone_expr ())
2479 {}
2480
2481 // Overload assignment operator to clone unique pointers
2482 RangeFromToExpr &operator= (RangeFromToExpr const &other)
2483 {
2484 RangeExpr::operator= (other);
2485 from = other.from->clone_expr ();
2486 to = other.to->clone_expr ();
2487
2488 return *this;
2489 }
2490
2491 // move constructors
2492 RangeFromToExpr (RangeFromToExpr &&other) = default;
2493 RangeFromToExpr &operator= (RangeFromToExpr &&other) = default;
2494
2495 void accept_vis (HIRFullVisitor &vis) override;
2496 void accept_vis (HIRExpressionVisitor &vis) override;
2497
2498 std::unique_ptr<Expr> &get_from_expr () { return from; }
2499 std::unique_ptr<Expr> &get_to_expr () { return to; }
2500
2501 protected:
2502 /* Use covariance to implement clone function as returning this object rather
2503 * than base */
2504 RangeFromToExpr *clone_expr_impl () const override
2505 {
2506 return new RangeFromToExpr (*this);
2507 }
2508
2509 /* Use covariance to implement clone function as returning this object rather
2510 * than base */
2511 RangeFromToExpr *clone_expr_without_block_impl () const override
2512 {
2513 return new RangeFromToExpr (*this);
2514 }
2515 };
2516
2517 // Range from (inclusive) expression HIR node object
2518 // constructs a std::ops::RangeFrom object
2519 class RangeFromExpr : public RangeExpr
2520 {
2521 std::unique_ptr<Expr> from;
2522
2523 public:
2524 std::string as_string () const override;
2525
2526 RangeFromExpr (Analysis::NodeMapping mappings,
2527 std::unique_ptr<Expr> range_from, Location locus)
2528 : RangeExpr (std::move (mappings), locus), from (std::move (range_from))
2529 {}
2530
2531 // Copy constructor with clone
2532 RangeFromExpr (RangeFromExpr const &other)
2533 : RangeExpr (other), from (other.from->clone_expr ())
2534 {}
2535
2536 // Overload assignment operator to clone unique_ptr
2537 RangeFromExpr &operator= (RangeFromExpr const &other)
2538 {
2539 RangeExpr::operator= (other);
2540 from = other.from->clone_expr ();
2541
2542 return *this;
2543 }
2544
2545 // move constructors
2546 RangeFromExpr (RangeFromExpr &&other) = default;
2547 RangeFromExpr &operator= (RangeFromExpr &&other) = default;
2548
2549 void accept_vis (HIRFullVisitor &vis) override;
2550 void accept_vis (HIRExpressionVisitor &vis) override;
2551
2552 std::unique_ptr<Expr> &get_from_expr () { return from; }
2553
2554 protected:
2555 /* Use covariance to implement clone function as returning this object rather
2556 * than base */
2557 RangeFromExpr *clone_expr_impl () const override
2558 {
2559 return new RangeFromExpr (*this);
2560 }
2561
2562 /* Use covariance to implement clone function as returning this object rather
2563 * than base */
2564 RangeFromExpr *clone_expr_without_block_impl () const override
2565 {
2566 return new RangeFromExpr (*this);
2567 }
2568 };
2569
2570 // Range to (exclusive) expression HIR node object
2571 // constructs a std::ops::RangeTo object
2572 class RangeToExpr : public RangeExpr
2573 {
2574 std::unique_ptr<Expr> to;
2575
2576 public:
2577 std::string as_string () const override;
2578
2579 // outer attributes not allowed
2580 RangeToExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> range_to,
2581 Location locus)
2582 : RangeExpr (std::move (mappings), locus), to (std::move (range_to))
2583 {}
2584
2585 // Copy constructor with clone
2586 RangeToExpr (RangeToExpr const &other)
2587 : RangeExpr (other), to (other.to->clone_expr ())
2588 {}
2589
2590 // Overload assignment operator to clone unique_ptr
2591 RangeToExpr &operator= (RangeToExpr const &other)
2592 {
2593 RangeExpr::operator= (other);
2594 to = other.to->clone_expr ();
2595
2596 return *this;
2597 }
2598
2599 // move constructors
2600 RangeToExpr (RangeToExpr &&other) = default;
2601 RangeToExpr &operator= (RangeToExpr &&other) = default;
2602
2603 void accept_vis (HIRFullVisitor &vis) override;
2604 void accept_vis (HIRExpressionVisitor &vis) override;
2605
2606 std::unique_ptr<Expr> &get_to_expr () { return to; }
2607
2608 protected:
2609 /* Use covariance to implement clone function as returning this object rather
2610 * than base */
2611 RangeToExpr *clone_expr_impl () const override
2612 {
2613 return new RangeToExpr (*this);
2614 }
2615
2616 /* Use covariance to implement clone function as returning this object rather
2617 * than base */
2618 RangeToExpr *clone_expr_without_block_impl () const override
2619 {
2620 return new RangeToExpr (*this);
2621 }
2622 };
2623
2624 // Full range expression HIR node object
2625 // constructs a std::ops::RangeFull object
2626 class RangeFullExpr : public RangeExpr
2627 {
2628 public:
2629 std::string as_string () const override;
2630
2631 RangeFullExpr (Analysis::NodeMapping mappings, Location locus)
2632 : RangeExpr (std::move (mappings), locus)
2633 {}
2634 // outer attributes not allowed
2635
2636 void accept_vis (HIRFullVisitor &vis) override;
2637 void accept_vis (HIRExpressionVisitor &vis) override;
2638
2639 protected:
2640 /* Use covariance to implement clone function as returning this object rather
2641 * than base */
2642 RangeFullExpr *clone_expr_impl () const override
2643 {
2644 return new RangeFullExpr (*this);
2645 }
2646
2647 /* Use covariance to implement clone function as returning this object rather
2648 * than base */
2649 RangeFullExpr *clone_expr_without_block_impl () const override
2650 {
2651 return new RangeFullExpr (*this);
2652 }
2653 };
2654
2655 // Range from (inclusive) and to (inclusive) expression HIR node object
2656 // aka RangeInclusiveExpr; constructs a std::ops::RangeInclusive object
2657 class RangeFromToInclExpr : public RangeExpr
2658 {
2659 std::unique_ptr<Expr> from;
2660 std::unique_ptr<Expr> to;
2661
2662 public:
2663 std::string as_string () const override;
2664
2665 RangeFromToInclExpr (Analysis::NodeMapping mappings,
2666 std::unique_ptr<Expr> range_from,
2667 std::unique_ptr<Expr> range_to, Location locus)
2668 : RangeExpr (std::move (mappings), locus), from (std::move (range_from)),
2669 to (std::move (range_to))
2670 {}
2671 // outer attributes not allowed
2672
2673 // Copy constructor with clone
2674 RangeFromToInclExpr (RangeFromToInclExpr const &other)
2675 : RangeExpr (other), from (other.from->clone_expr ()),
2676 to (other.to->clone_expr ())
2677 {}
2678
2679 // Overload assignment operator to use clone
2680 RangeFromToInclExpr &operator= (RangeFromToInclExpr const &other)
2681 {
2682 RangeExpr::operator= (other);
2683 from = other.from->clone_expr ();
2684 to = other.to->clone_expr ();
2685
2686 return *this;
2687 }
2688
2689 // move constructors
2690 RangeFromToInclExpr (RangeFromToInclExpr &&other) = default;
2691 RangeFromToInclExpr &operator= (RangeFromToInclExpr &&other) = default;
2692
2693 void accept_vis (HIRFullVisitor &vis) override;
2694 void accept_vis (HIRExpressionVisitor &vis) override;
2695
2696 std::unique_ptr<Expr> &get_from_expr () { return from; }
2697 std::unique_ptr<Expr> &get_to_expr () { return to; }
2698
2699 protected:
2700 /* Use covariance to implement clone function as returning this object rather
2701 * than base */
2702 RangeFromToInclExpr *clone_expr_impl () const override
2703 {
2704 return new RangeFromToInclExpr (*this);
2705 }
2706
2707 /* Use covariance to implement clone function as returning this object rather
2708 * than base */
2709 RangeFromToInclExpr *clone_expr_without_block_impl () const override
2710 {
2711 return new RangeFromToInclExpr (*this);
2712 }
2713 };
2714
2715 // Range to (inclusive) expression HIR node object
2716 // aka RangeToInclusiveExpr; constructs a std::ops::RangeToInclusive object
2717 class RangeToInclExpr : public RangeExpr
2718 {
2719 std::unique_ptr<Expr> to;
2720
2721 public:
2722 std::string as_string () const override;
2723
2724 RangeToInclExpr (Analysis::NodeMapping mappings,
2725 std::unique_ptr<Expr> range_to, Location locus)
2726 : RangeExpr (std::move (mappings), locus), to (std::move (range_to))
2727 {}
2728 // outer attributes not allowed
2729
2730 // Copy constructor with clone
2731 RangeToInclExpr (RangeToInclExpr const &other)
2732 : RangeExpr (other), to (other.to->clone_expr ())
2733 {}
2734
2735 // Overload assignment operator to clone pointer
2736 RangeToInclExpr &operator= (RangeToInclExpr const &other)
2737 {
2738 RangeExpr::operator= (other);
2739 to = other.to->clone_expr ();
2740
2741 return *this;
2742 }
2743
2744 // move constructors
2745 RangeToInclExpr (RangeToInclExpr &&other) = default;
2746 RangeToInclExpr &operator= (RangeToInclExpr &&other) = default;
2747
2748 void accept_vis (HIRFullVisitor &vis) override;
2749 void accept_vis (HIRExpressionVisitor &vis) override;
2750
2751 std::unique_ptr<Expr> &get_to_expr () { return to; };
2752
2753 protected:
2754 /* Use covariance to implement clone function as returning this object rather
2755 * than base */
2756 RangeToInclExpr *clone_expr_impl () const override
2757 {
2758 return new RangeToInclExpr (*this);
2759 }
2760
2761 /* Use covariance to implement clone function as returning this object rather
2762 * than base */
2763 RangeToInclExpr *clone_expr_without_block_impl () const override
2764 {
2765 return new RangeToInclExpr (*this);
2766 }
2767 };
2768
2769 // Return expression HIR node representation
2770 class ReturnExpr : public ExprWithoutBlock
2771 {
2772 public:
2773 std::unique_ptr<Expr> return_expr;
2774
2775 Location locus;
2776
2777 std::string as_string () const override;
2778
2779 /* Returns whether the object has an expression returned (i.e. not void return
2780 * type). */
2781 bool has_return_expr () const { return return_expr != nullptr; }
2782
2783 // Constructor for ReturnExpr.
2784 ReturnExpr (Analysis::NodeMapping mappings, Location locus,
2785 std::unique_ptr<Expr> returned_expr = nullptr,
2786 AST::AttrVec outer_attribs = AST::AttrVec ())
2787 : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)),
2788 return_expr (std::move (returned_expr)), locus (locus)
2789 {}
2790
2791 // Copy constructor with clone
2792 ReturnExpr (ReturnExpr const &other)
2793 : ExprWithoutBlock (other), locus (other.locus)
2794 {
2795 // guard to protect from null pointer dereference
2796 if (other.return_expr != nullptr)
2797 return_expr = other.return_expr->clone_expr ();
2798 }
2799
2800 // Overloaded assignment operator to clone return_expr pointer
2801 ReturnExpr &operator= (ReturnExpr const &other)
2802 {
2803 ExprWithoutBlock::operator= (other);
2804 return_expr = other.return_expr->clone_expr ();
2805 locus = other.locus;
2806 // outer_attrs = other.outer_attrs;
2807
2808 return *this;
2809 }
2810
2811 // move constructors
2812 ReturnExpr (ReturnExpr &&other) = default;
2813 ReturnExpr &operator= (ReturnExpr &&other) = default;
2814
2815 Location get_locus () const override final { return locus; }
2816
2817 void accept_vis (HIRFullVisitor &vis) override;
2818 void accept_vis (HIRExpressionVisitor &vis) override;
2819
2820 Expr *get_expr () { return return_expr.get (); }
2821
2822 ExprType get_expression_type () const override final
2823 {
2824 return ExprType::Return;
2825 }
2826
2827 protected:
2828 /* Use covariance to implement clone function as returning this object rather
2829 * than base */
2830 ReturnExpr *clone_expr_impl () const override
2831 {
2832 return new ReturnExpr (*this);
2833 }
2834
2835 /* Use covariance to implement clone function as returning this object rather
2836 * than base */
2837 ReturnExpr *clone_expr_without_block_impl () const override
2838 {
2839 return new ReturnExpr (*this);
2840 }
2841 };
2842
2843 // An unsafe block HIR node
2844 class UnsafeBlockExpr : public ExprWithBlock
2845 {
2846 // Or just have it extend BlockExpr
2847 std::unique_ptr<BlockExpr> expr;
2848 Location locus;
2849
2850 public:
2851 std::string as_string () const override;
2852
2853 UnsafeBlockExpr (Analysis::NodeMapping mappings,
2854 std::unique_ptr<BlockExpr> block_expr,
2855 AST::AttrVec outer_attribs, Location locus)
2856 : ExprWithBlock (std::move (mappings), std::move (outer_attribs)),
2857 expr (std::move (block_expr)), locus (locus)
2858 {}
2859
2860 // Copy constructor with clone
2861 UnsafeBlockExpr (UnsafeBlockExpr const &other)
2862 : ExprWithBlock (other), expr (other.expr->clone_block_expr ()),
2863 locus (other.locus)
2864 {}
2865
2866 // Overloaded assignment operator to clone
2867 UnsafeBlockExpr &operator= (UnsafeBlockExpr const &other)
2868 {
2869 ExprWithBlock::operator= (other);
2870 expr = other.expr->clone_block_expr ();
2871 locus = other.locus;
2872 // outer_attrs = other.outer_attrs;
2873
2874 return *this;
2875 }
2876
2877 // move constructors
2878 UnsafeBlockExpr (UnsafeBlockExpr &&other) = default;
2879 UnsafeBlockExpr &operator= (UnsafeBlockExpr &&other) = default;
2880
2881 Location get_locus () const override final { return locus; }
2882
2883 void accept_vis (HIRFullVisitor &vis) override;
2884 void accept_vis (HIRExpressionVisitor &vis) override;
2885
2886 std::unique_ptr<BlockExpr> &get_block_expr () { return expr; }
2887
2888 ExprType get_expression_type () const override final
2889 {
2890 return ExprType::UnsafeBlock;
2891 }
2892
2893 protected:
2894 /* Use covariance to implement clone function as returning this object rather
2895 * than base */
2896 UnsafeBlockExpr *clone_expr_impl () const override
2897 {
2898 return new UnsafeBlockExpr (*this);
2899 }
2900
2901 /* Use covariance to implement clone function as returning this object rather
2902 * than base */
2903 UnsafeBlockExpr *clone_expr_with_block_impl () const override
2904 {
2905 return new UnsafeBlockExpr (*this);
2906 }
2907 };
2908
2909 // Loop label expression HIR node used with break and continue expressions
2910 // TODO: inline?
2911 class LoopLabel /*: public Node*/
2912 {
2913 Lifetime label; // or type LIFETIME_OR_LABEL
2914
2915 Location locus;
2916
2917 Analysis::NodeMapping mappings;
2918
2919 public:
2920 std::string as_string () const;
2921
2922 LoopLabel (Analysis::NodeMapping mapping, Lifetime loop_label, Location locus)
2923 : label (std::move (loop_label)), locus (locus), mappings (mapping)
2924 {}
2925
2926 // Returns whether the LoopLabel is in an error state.
2927 bool is_error () const { return label.is_error (); }
2928
2929 Location get_locus () const { return locus; }
2930
2931 Analysis::NodeMapping &get_mappings () { return mappings; }
2932
2933 Lifetime &get_lifetime () { return label; }
2934 };
2935
2936 // Base loop expression HIR node - aka LoopExpr
2937 class BaseLoopExpr : public ExprWithBlock
2938 {
2939 protected:
2940 LoopLabel loop_label;
2941 std::unique_ptr<BlockExpr> loop_block;
2942
2943 private:
2944 Location locus;
2945
2946 protected:
2947 // Constructor for BaseLoopExpr
2948 BaseLoopExpr (Analysis::NodeMapping mappings,
2949 std::unique_ptr<BlockExpr> loop_block, Location locus,
2950 LoopLabel loop_label,
2951 AST::AttrVec outer_attribs = AST::AttrVec ())
2952 : ExprWithBlock (std::move (mappings), std::move (outer_attribs)),
2953 loop_label (std::move (loop_label)), loop_block (std::move (loop_block)),
2954 locus (locus)
2955 {}
2956
2957 // Copy constructor for BaseLoopExpr with clone
2958 BaseLoopExpr (BaseLoopExpr const &other)
2959 : ExprWithBlock (other), loop_label (other.loop_label),
2960 loop_block (other.loop_block->clone_block_expr ()), locus (other.locus)
2961 {}
2962
2963 // Overloaded assignment operator to clone
2964 BaseLoopExpr &operator= (BaseLoopExpr const &other)
2965 {
2966 ExprWithBlock::operator= (other);
2967 loop_block = other.loop_block->clone_block_expr ();
2968 loop_label = other.loop_label;
2969 locus = other.locus;
2970 // outer_attrs = other.outer_attrs;
2971
2972 return *this;
2973 }
2974
2975 // move constructors
2976 BaseLoopExpr (BaseLoopExpr &&other) = default;
2977 BaseLoopExpr &operator= (BaseLoopExpr &&other) = default;
2978
2979 ExprType get_expression_type () const final override
2980 {
2981 return ExprType::BaseLoop;
2982 }
2983
2984 public:
2985 bool has_loop_label () const { return !loop_label.is_error (); }
2986
2987 Location get_locus () const override final { return locus; }
2988
2989 std::unique_ptr<HIR::BlockExpr> &get_loop_block () { return loop_block; };
2990
2991 LoopLabel &get_loop_label () { return loop_label; }
2992 };
2993
2994 // 'Loop' expression (i.e. the infinite loop) HIR node
2995 class LoopExpr : public BaseLoopExpr
2996 {
2997 public:
2998 std::string as_string () const override;
2999
3000 // Constructor for LoopExpr
3001 LoopExpr (Analysis::NodeMapping mappings,
3002 std::unique_ptr<BlockExpr> loop_block, Location locus,
3003 LoopLabel loop_label, AST::AttrVec outer_attribs = AST::AttrVec ())
3004 : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
3005 std::move (loop_label), std::move (outer_attribs))
3006 {}
3007
3008 void accept_vis (HIRFullVisitor &vis) override;
3009 void accept_vis (HIRExpressionVisitor &vis) override;
3010
3011 protected:
3012 /* Use covariance to implement clone function as returning this object rather
3013 * than base */
3014 LoopExpr *clone_expr_impl () const override { return new LoopExpr (*this); }
3015
3016 /* Use covariance to implement clone function as returning this object rather
3017 * than base */
3018 LoopExpr *clone_expr_with_block_impl () const override
3019 {
3020 return new LoopExpr (*this);
3021 }
3022 };
3023
3024 // While loop expression HIR node (predicate loop)
3025 class WhileLoopExpr : public BaseLoopExpr
3026 {
3027 std::unique_ptr<Expr> condition;
3028
3029 public:
3030 std::string as_string () const override;
3031
3032 // Constructor for while loop with loop label
3033 WhileLoopExpr (Analysis::NodeMapping mappings,
3034 std::unique_ptr<Expr> loop_condition,
3035 std::unique_ptr<BlockExpr> loop_block, Location locus,
3036 LoopLabel loop_label,
3037 AST::AttrVec outer_attribs = AST::AttrVec ())
3038 : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
3039 std::move (loop_label), std::move (outer_attribs)),
3040 condition (std::move (loop_condition))
3041 {}
3042
3043 // Copy constructor with clone
3044 WhileLoopExpr (WhileLoopExpr const &other)
3045 : BaseLoopExpr (other), condition (other.condition->clone_expr ())
3046 {}
3047
3048 // Overloaded assignment operator to clone
3049 WhileLoopExpr &operator= (WhileLoopExpr const &other)
3050 {
3051 BaseLoopExpr::operator= (other);
3052 condition = other.condition->clone_expr ();
3053 // loop_block = other.loop_block->clone_block_expr();
3054 // loop_label = other.loop_label;
3055 // outer_attrs = other.outer_attrs;
3056
3057 return *this;
3058 }
3059
3060 // move constructors
3061 WhileLoopExpr (WhileLoopExpr &&other) = default;
3062 WhileLoopExpr &operator= (WhileLoopExpr &&other) = default;
3063
3064 void accept_vis (HIRFullVisitor &vis) override;
3065 void accept_vis (HIRExpressionVisitor &vis) override;
3066
3067 std::unique_ptr<Expr> &get_predicate_expr () { return condition; }
3068
3069 protected:
3070 /* Use covariance to implement clone function as returning this object rather
3071 * than base */
3072 WhileLoopExpr *clone_expr_impl () const override
3073 {
3074 return new WhileLoopExpr (*this);
3075 }
3076
3077 /* Use covariance to implement clone function as returning this object rather
3078 * than base */
3079 WhileLoopExpr *clone_expr_with_block_impl () const override
3080 {
3081 return new WhileLoopExpr (*this);
3082 }
3083 };
3084
3085 // While let loop expression HIR node (predicate pattern loop)
3086 class WhileLetLoopExpr : public BaseLoopExpr
3087 {
3088 // MatchArmPatterns patterns;
3089 std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined
3090 std::unique_ptr<Expr> condition;
3091
3092 public:
3093 std::string as_string () const override;
3094
3095 // Constructor with a loop label
3096 WhileLetLoopExpr (Analysis::NodeMapping mappings,
3097 std::vector<std::unique_ptr<Pattern> > match_arm_patterns,
3098 std::unique_ptr<Expr> condition,
3099 std::unique_ptr<BlockExpr> loop_block, Location locus,
3100 LoopLabel loop_label,
3101 AST::AttrVec outer_attribs = AST::AttrVec ())
3102 : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
3103 std::move (loop_label), std::move (outer_attribs)),
3104 match_arm_patterns (std::move (match_arm_patterns)),
3105 condition (std::move (condition))
3106 {}
3107
3108 // Copy constructor with clone
3109 WhileLetLoopExpr (WhileLetLoopExpr const &other)
3110 : BaseLoopExpr (other),
3111 /*match_arm_patterns(other.match_arm_patterns),*/ condition (
3112 other.condition->clone_expr ())
3113 {
3114 match_arm_patterns.reserve (other.match_arm_patterns.size ());
3115 for (const auto &e : other.match_arm_patterns)
3116 match_arm_patterns.push_back (e->clone_pattern ());
3117 }
3118
3119 // Overloaded assignment operator to clone pointers
3120 WhileLetLoopExpr &operator= (WhileLetLoopExpr const &other)
3121 {
3122 BaseLoopExpr::operator= (other);
3123 // match_arm_patterns = other.match_arm_patterns;
3124 condition = other.condition->clone_expr ();
3125 // loop_block = other.loop_block->clone_block_expr();
3126 // loop_label = other.loop_label;
3127 // outer_attrs = other.outer_attrs;
3128
3129 match_arm_patterns.reserve (other.match_arm_patterns.size ());
3130 for (const auto &e : other.match_arm_patterns)
3131 match_arm_patterns.push_back (e->clone_pattern ());
3132
3133 return *this;
3134 }
3135
3136 // move constructors
3137 WhileLetLoopExpr (WhileLetLoopExpr &&other) = default;
3138 WhileLetLoopExpr &operator= (WhileLetLoopExpr &&other) = default;
3139
3140 void accept_vis (HIRFullVisitor &vis) override;
3141 void accept_vis (HIRExpressionVisitor &vis) override;
3142
3143 std::unique_ptr<Expr> &get_cond () { return condition; }
3144
3145 protected:
3146 /* Use covariance to implement clone function as returning this object rather
3147 * than base */
3148 WhileLetLoopExpr *clone_expr_impl () const override
3149 {
3150 return new WhileLetLoopExpr (*this);
3151 }
3152
3153 /* Use covariance to implement clone function as returning this object rather
3154 * than base */
3155 WhileLetLoopExpr *clone_expr_with_block_impl () const override
3156 {
3157 return new WhileLetLoopExpr (*this);
3158 }
3159 };
3160
3161 // For loop expression HIR node (iterator loop)
3162 class ForLoopExpr : public BaseLoopExpr
3163 {
3164 std::unique_ptr<Pattern> pattern;
3165 std::unique_ptr<Expr> iterator_expr;
3166
3167 public:
3168 std::string as_string () const override;
3169
3170 // Constructor with loop label
3171 ForLoopExpr (Analysis::NodeMapping mappings,
3172 std::unique_ptr<Pattern> loop_pattern,
3173 std::unique_ptr<Expr> iterator_expr,
3174 std::unique_ptr<BlockExpr> loop_body, Location locus,
3175 LoopLabel loop_label,
3176 AST::AttrVec outer_attribs = AST::AttrVec ())
3177 : BaseLoopExpr (std::move (mappings), std::move (loop_body), locus,
3178 std::move (loop_label), std::move (outer_attribs)),
3179 pattern (std::move (loop_pattern)),
3180 iterator_expr (std::move (iterator_expr))
3181 {}
3182
3183 // Copy constructor with clone
3184 ForLoopExpr (ForLoopExpr const &other)
3185 : BaseLoopExpr (other), pattern (other.pattern->clone_pattern ()),
3186 iterator_expr (other.iterator_expr->clone_expr ())
3187 {}
3188
3189 // Overloaded assignment operator to clone
3190 ForLoopExpr &operator= (ForLoopExpr const &other)
3191 {
3192 BaseLoopExpr::operator= (other);
3193 pattern = other.pattern->clone_pattern ();
3194 iterator_expr = other.iterator_expr->clone_expr ();
3195 /*loop_block = other.loop_block->clone_block_expr();
3196 loop_label = other.loop_label;
3197 outer_attrs = other.outer_attrs;*/
3198
3199 return *this;
3200 }
3201
3202 // move constructors
3203 ForLoopExpr (ForLoopExpr &&other) = default;
3204 ForLoopExpr &operator= (ForLoopExpr &&other) = default;
3205
3206 void accept_vis (HIRFullVisitor &vis) override;
3207 void accept_vis (HIRExpressionVisitor &vis) override;
3208
3209 std::unique_ptr<Expr> &get_iterator_expr () { return iterator_expr; }
3210
3211 protected:
3212 /* Use covariance to implement clone function as returning this object rather
3213 * than base */
3214 ForLoopExpr *clone_expr_impl () const override
3215 {
3216 return new ForLoopExpr (*this);
3217 }
3218
3219 /* Use covariance to implement clone function as returning this object rather
3220 * than base */
3221 ForLoopExpr *clone_expr_with_block_impl () const override
3222 {
3223 return new ForLoopExpr (*this);
3224 }
3225 };
3226
3227 // forward decl for IfExpr
3228 class IfLetExpr;
3229
3230 // Base if expression with no "else" or "if let" HIR node
3231 class IfExpr : public ExprWithBlock
3232 {
3233 std::unique_ptr<Expr> condition;
3234 std::unique_ptr<BlockExpr> if_block;
3235
3236 Location locus;
3237
3238 public:
3239 std::string as_string () const override;
3240
3241 IfExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> condition,
3242 std::unique_ptr<BlockExpr> if_block, Location locus)
3243 : ExprWithBlock (std::move (mappings), AST::AttrVec ()),
3244 condition (std::move (condition)), if_block (std::move (if_block)),
3245 locus (locus)
3246 {}
3247 // outer attributes are never allowed on IfExprs
3248
3249 // Copy constructor with clone
3250 IfExpr (IfExpr const &other)
3251 : ExprWithBlock (other), condition (other.condition->clone_expr ()),
3252 if_block (other.if_block->clone_block_expr ()), locus (other.locus)
3253 {}
3254
3255 // Overloaded assignment operator to clone expressions
3256 IfExpr &operator= (IfExpr const &other)
3257 {
3258 ExprWithBlock::operator= (other);
3259 condition = other.condition->clone_expr ();
3260 if_block = other.if_block->clone_block_expr ();
3261 locus = other.locus;
3262
3263 return *this;
3264 }
3265
3266 // move constructors
3267 IfExpr (IfExpr &&other) = default;
3268 IfExpr &operator= (IfExpr &&other) = default;
3269
3270 // Unique pointer custom clone function
3271 std::unique_ptr<IfExpr> clone_if_expr () const
3272 {
3273 return std::unique_ptr<IfExpr> (clone_if_expr_impl ());
3274 }
3275
3276 /* Note that multiple "else if"s are handled via nested HIRs rather than a
3277 * vector of else ifs - i.e. not like a switch statement. TODO - is this a
3278 * better approach? or does it not parse correctly and have downsides? */
3279
3280 Location get_locus () const override final { return locus; }
3281
3282 void accept_vis (HIRFullVisitor &vis) override;
3283 void accept_vis (HIRExpressionVisitor &vis) override;
3284
3285 void vis_if_condition (HIRFullVisitor &vis) { condition->accept_vis (vis); }
3286 void vis_if_block (HIRFullVisitor &vis) { if_block->accept_vis (vis); }
3287
3288 Expr *get_if_condition () { return condition.get (); }
3289 BlockExpr *get_if_block () { return if_block.get (); }
3290
3291 ExprType get_expression_type () const final override { return ExprType::If; }
3292
3293 protected:
3294 /* Use covariance to implement clone function as returning this object rather
3295 * than base */
3296 IfExpr *clone_expr_impl () const override { return new IfExpr (*this); }
3297
3298 // Base clone function but still concrete as concrete base class
3299 virtual IfExpr *clone_if_expr_impl () const { return new IfExpr (*this); }
3300
3301 /* Use covariance to implement clone function as returning this object rather
3302 * than base */
3303 IfExpr *clone_expr_with_block_impl () const override
3304 {
3305 return new IfExpr (*this);
3306 }
3307 };
3308
3309 // If expression with an ending "else" expression HIR node (trailing)
3310 class IfExprConseqElse : public IfExpr
3311 {
3312 std::unique_ptr<BlockExpr> else_block;
3313
3314 public:
3315 std::string as_string () const override;
3316
3317 IfExprConseqElse (Analysis::NodeMapping mappings,
3318 std::unique_ptr<Expr> condition,
3319 std::unique_ptr<BlockExpr> if_block,
3320 std::unique_ptr<BlockExpr> else_block, Location locus)
3321 : IfExpr (std::move (mappings), std::move (condition), std::move (if_block),
3322 locus),
3323 else_block (std::move (else_block))
3324 {}
3325 // again, outer attributes not allowed
3326
3327 // Copy constructor with clone
3328 IfExprConseqElse (IfExprConseqElse const &other)
3329 : IfExpr (other), else_block (other.else_block->clone_block_expr ())
3330 {}
3331
3332 // Overloaded assignment operator with cloning
3333 IfExprConseqElse &operator= (IfExprConseqElse const &other)
3334 {
3335 IfExpr::operator= (other);
3336 // condition = other.condition->clone_expr();
3337 // if_block = other.if_block->clone_block_expr();
3338 else_block = other.else_block->clone_block_expr ();
3339
3340 return *this;
3341 }
3342
3343 // move constructors
3344 IfExprConseqElse (IfExprConseqElse &&other) = default;
3345 IfExprConseqElse &operator= (IfExprConseqElse &&other) = default;
3346
3347 void accept_vis (HIRFullVisitor &vis) override;
3348 void accept_vis (HIRExpressionVisitor &vis) override;
3349
3350 void vis_else_block (HIRFullVisitor &vis) { else_block->accept_vis (vis); }
3351
3352 BlockExpr *get_else_block () { return else_block.get (); }
3353
3354 protected:
3355 /* Use covariance to implement clone function as returning this object rather
3356 * than base */
3357 IfExprConseqElse *clone_expr_impl () const override
3358 {
3359 return new IfExprConseqElse (*this);
3360 }
3361
3362 /* Use covariance to implement clone function as returning this object rather
3363 * than base */
3364 IfExprConseqElse *clone_expr_with_block_impl () const override
3365 {
3366 return new IfExprConseqElse (*this);
3367 }
3368
3369 /* Use covariance to implement clone function as returning this object rather
3370 * than base */
3371 IfExprConseqElse *clone_if_expr_impl () const override
3372 {
3373 return new IfExprConseqElse (*this);
3374 }
3375 };
3376
3377 // If expression with an ending "else if" expression HIR node
3378 class IfExprConseqIf : public IfExpr
3379 {
3380 std::unique_ptr<IfExpr> conseq_if_expr;
3381
3382 public:
3383 std::string as_string () const override;
3384
3385 IfExprConseqIf (Analysis::NodeMapping mappings,
3386 std::unique_ptr<Expr> condition,
3387 std::unique_ptr<BlockExpr> if_block,
3388 std::unique_ptr<IfExpr> conseq_if_expr, Location locus)
3389 : IfExpr (std::move (mappings), std::move (condition), std::move (if_block),
3390 locus),
3391 conseq_if_expr (std::move (conseq_if_expr))
3392 {}
3393 // outer attributes not allowed
3394
3395 // Copy constructor with clone
3396 IfExprConseqIf (IfExprConseqIf const &other)
3397 : IfExpr (other), conseq_if_expr (other.conseq_if_expr->clone_if_expr ())
3398 {}
3399
3400 // Overloaded assignment operator to use clone
3401 IfExprConseqIf &operator= (IfExprConseqIf const &other)
3402 {
3403 IfExpr::operator= (other);
3404 // condition = other.condition->clone_expr();
3405 // if_block = other.if_block->clone_block_expr();
3406 conseq_if_expr = other.conseq_if_expr->clone_if_expr ();
3407
3408 return *this;
3409 }
3410
3411 // move constructors
3412 IfExprConseqIf (IfExprConseqIf &&other) = default;
3413 IfExprConseqIf &operator= (IfExprConseqIf &&other) = default;
3414
3415 void accept_vis (HIRFullVisitor &vis) override;
3416 void accept_vis (HIRExpressionVisitor &vis) override;
3417
3418 void vis_conseq_if_expr (HIRFullVisitor &vis)
3419 {
3420 conseq_if_expr->accept_vis (vis);
3421 }
3422
3423 IfExpr *get_conseq_if_expr () { return conseq_if_expr.get (); }
3424
3425 protected:
3426 /* Use covariance to implement clone function as returning this object rather
3427 * than base */
3428 IfExprConseqIf *clone_expr_impl () const override
3429 {
3430 return new IfExprConseqIf (*this);
3431 }
3432
3433 /* Use covariance to implement clone function as returning this object rather
3434 * than base */
3435 IfExprConseqIf *clone_expr_with_block_impl () const override
3436 {
3437 return new IfExprConseqIf (*this);
3438 }
3439
3440 /* Use covariance to implement clone function as returning this object rather
3441 * than base */
3442 IfExprConseqIf *clone_if_expr_impl () const override
3443 {
3444 return new IfExprConseqIf (*this);
3445 }
3446 };
3447
3448 // Basic "if let" expression HIR node with no else
3449 class IfLetExpr : public ExprWithBlock
3450 {
3451 // MatchArmPatterns patterns;
3452 std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined
3453 std::unique_ptr<Expr> value;
3454 std::unique_ptr<BlockExpr> if_block;
3455
3456 Location locus;
3457
3458 public:
3459 std::string as_string () const override;
3460
3461 IfLetExpr (Analysis::NodeMapping mappings,
3462 std::vector<std::unique_ptr<Pattern> > match_arm_patterns,
3463 std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block,
3464 Location locus)
3465 : ExprWithBlock (std::move (mappings), AST::AttrVec ()),
3466 match_arm_patterns (std::move (match_arm_patterns)),
3467 value (std::move (value)), if_block (std::move (if_block)), locus (locus)
3468 {}
3469 // outer attributes not allowed on if let exprs either
3470
3471 // copy constructor with clone
3472 IfLetExpr (IfLetExpr const &other)
3473 : ExprWithBlock (other),
3474 /*match_arm_patterns(other.match_arm_patterns),*/ value (
3475 other.value->clone_expr ()),
3476 if_block (other.if_block->clone_block_expr ()), locus (other.locus)
3477 {
3478 match_arm_patterns.reserve (other.match_arm_patterns.size ());
3479 for (const auto &e : other.match_arm_patterns)
3480 match_arm_patterns.push_back (e->clone_pattern ());
3481 }
3482
3483 // overload assignment operator to clone
3484 IfLetExpr &operator= (IfLetExpr const &other)
3485 {
3486 ExprWithBlock::operator= (other);
3487 // match_arm_patterns = other.match_arm_patterns;
3488 value = other.value->clone_expr ();
3489 if_block = other.if_block->clone_block_expr ();
3490 locus = other.locus;
3491
3492 match_arm_patterns.reserve (other.match_arm_patterns.size ());
3493 for (const auto &e : other.match_arm_patterns)
3494 match_arm_patterns.push_back (e->clone_pattern ());
3495
3496 return *this;
3497 }
3498
3499 // move constructors
3500 IfLetExpr (IfLetExpr &&other) = default;
3501 IfLetExpr &operator= (IfLetExpr &&other) = default;
3502
3503 // Unique pointer custom clone function
3504 std::unique_ptr<IfLetExpr> clone_if_let_expr () const
3505 {
3506 return std::unique_ptr<IfLetExpr> (clone_if_let_expr_impl ());
3507 }
3508
3509 Location get_locus () const override final { return locus; }
3510
3511 void accept_vis (HIRFullVisitor &vis) override;
3512 void accept_vis (HIRExpressionVisitor &vis) override;
3513
3514 std::unique_ptr<Expr> &get_scrutinee_expr ()
3515 {
3516 rust_assert (value != nullptr);
3517 return value;
3518 }
3519
3520 std::vector<std::unique_ptr<Pattern> > &get_patterns ()
3521 {
3522 return match_arm_patterns;
3523 }
3524
3525 BlockExpr *get_if_block () { return if_block.get (); }
3526
3527 ExprType get_expression_type () const final override
3528 {
3529 return ExprType::IfLet;
3530 }
3531
3532 protected:
3533 /* Use covariance to implement clone function as returning this object rather
3534 * than base */
3535 IfLetExpr *clone_expr_impl () const override { return new IfLetExpr (*this); }
3536
3537 /* Use covariance to implement clone function as returning this object rather
3538 * than base */
3539 IfLetExpr *clone_expr_with_block_impl () const override
3540 {
3541 return new IfLetExpr (*this);
3542 }
3543
3544 // Base clone function but still concrete as concrete base class
3545 virtual IfLetExpr *clone_if_let_expr_impl () const
3546 {
3547 return new IfLetExpr (*this);
3548 }
3549 };
3550
3551 // If expression with an ending "else if let" expression HIR node
3552 class IfExprConseqIfLet : public IfExpr
3553 {
3554 std::unique_ptr<IfLetExpr> if_let_expr;
3555
3556 public:
3557 std::string as_string () const override;
3558
3559 IfExprConseqIfLet (Analysis::NodeMapping mappings,
3560 std::unique_ptr<Expr> condition,
3561 std::unique_ptr<BlockExpr> if_block,
3562 std::unique_ptr<IfLetExpr> conseq_if_let_expr,
3563 Location locus)
3564 : IfExpr (std::move (mappings), std::move (condition), std::move (if_block),
3565 locus),
3566 if_let_expr (std::move (conseq_if_let_expr))
3567 {}
3568 // outer attributes not allowed
3569
3570 // Copy constructor with clone
3571 IfExprConseqIfLet (IfExprConseqIfLet const &other)
3572 : IfExpr (other), if_let_expr (other.if_let_expr->clone_if_let_expr ())
3573 {}
3574
3575 // Overloaded assignment operator to use clone
3576 IfExprConseqIfLet &operator= (IfExprConseqIfLet const &other)
3577 {
3578 IfExpr::operator= (other);
3579 // condition = other.condition->clone_expr();
3580 // if_block = other.if_block->clone_block_expr();
3581 if_let_expr = other.if_let_expr->clone_if_let_expr ();
3582
3583 return *this;
3584 }
3585
3586 // move constructors
3587 IfExprConseqIfLet (IfExprConseqIfLet &&other) = default;
3588 IfExprConseqIfLet &operator= (IfExprConseqIfLet &&other) = default;
3589
3590 void accept_vis (HIRFullVisitor &vis) override;
3591 void accept_vis (HIRExpressionVisitor &vis) override;
3592
3593 protected:
3594 /* Use covariance to implement clone function as returning this object rather
3595 * than base */
3596 IfExprConseqIfLet *clone_expr_impl () const override
3597 {
3598 return new IfExprConseqIfLet (*this);
3599 }
3600
3601 /* Use covariance to implement clone function as returning this object rather
3602 * than base */
3603 IfExprConseqIfLet *clone_expr_with_block_impl () const override
3604 {
3605 return new IfExprConseqIfLet (*this);
3606 }
3607
3608 /* Use covariance to implement clone function as returning this object rather
3609 * than base */
3610 IfExprConseqIfLet *clone_if_expr_impl () const override
3611 {
3612 return new IfExprConseqIfLet (*this);
3613 }
3614 };
3615
3616 /* HIR node representing "if let" expression with an "else" expression at the
3617 * end */
3618 class IfLetExprConseqElse : public IfLetExpr
3619 {
3620 std::unique_ptr<BlockExpr> else_block;
3621
3622 public:
3623 std::string as_string () const override;
3624
3625 IfLetExprConseqElse (
3626 Analysis::NodeMapping mappings,
3627 std::vector<std::unique_ptr<Pattern> > match_arm_patterns,
3628 std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block,
3629 std::unique_ptr<BlockExpr> else_block, Location locus)
3630 : IfLetExpr (std::move (mappings), std::move (match_arm_patterns),
3631 std::move (value), std::move (if_block), locus),
3632 else_block (std::move (else_block))
3633 {}
3634 // outer attributes not allowed
3635
3636 // copy constructor with clone
3637 IfLetExprConseqElse (IfLetExprConseqElse const &other)
3638 : IfLetExpr (other), else_block (other.else_block->clone_block_expr ())
3639 {}
3640
3641 // overload assignment operator to clone
3642 IfLetExprConseqElse &operator= (IfLetExprConseqElse const &other)
3643 {
3644 IfLetExpr::operator= (other);
3645 // match_arm_patterns = other.match_arm_patterns;
3646 // value = other.value->clone_expr();
3647 // if_block = other.if_block->clone_block_expr();
3648 else_block = other.else_block->clone_block_expr ();
3649 // outer_attrs = other.outer_attrs;
3650
3651 return *this;
3652 }
3653
3654 // move constructors
3655 IfLetExprConseqElse (IfLetExprConseqElse &&other) = default;
3656 IfLetExprConseqElse &operator= (IfLetExprConseqElse &&other) = default;
3657
3658 void accept_vis (HIRFullVisitor &vis) override;
3659 void accept_vis (HIRExpressionVisitor &vis) override;
3660
3661 protected:
3662 /* Use covariance to implement clone function as returning this object rather
3663 * than base */
3664 IfLetExprConseqElse *clone_expr_impl () const override
3665 {
3666 return new IfLetExprConseqElse (*this);
3667 }
3668
3669 /* Use covariance to implement clone function as returning this object rather
3670 * than base */
3671 IfLetExprConseqElse *clone_expr_with_block_impl () const override
3672 {
3673 return new IfLetExprConseqElse (*this);
3674 }
3675
3676 /* Use covariance to implement clone function as returning this object rather
3677 * than base */
3678 IfLetExprConseqElse *clone_if_let_expr_impl () const override
3679 {
3680 return new IfLetExprConseqElse (*this);
3681 }
3682 };
3683
3684 /* HIR node representing "if let" expression with an "else if" expression at the
3685 * end */
3686 class IfLetExprConseqIf : public IfLetExpr
3687 {
3688 std::unique_ptr<IfExpr> if_expr;
3689
3690 public:
3691 std::string as_string () const override;
3692
3693 IfLetExprConseqIf (Analysis::NodeMapping mappings,
3694 std::vector<std::unique_ptr<Pattern> > match_arm_patterns,
3695 std::unique_ptr<Expr> value,
3696 std::unique_ptr<BlockExpr> if_block,
3697 std::unique_ptr<IfExpr> if_expr, Location locus)
3698 : IfLetExpr (std::move (mappings), std::move (match_arm_patterns),
3699 std::move (value), std::move (if_block), locus),
3700 if_expr (std::move (if_expr))
3701 {}
3702 // again, outer attributes not allowed
3703
3704 // copy constructor with clone
3705 IfLetExprConseqIf (IfLetExprConseqIf const &other)
3706 : IfLetExpr (other), if_expr (other.if_expr->clone_if_expr ())
3707 {}
3708
3709 // overload assignment operator to clone
3710 IfLetExprConseqIf &operator= (IfLetExprConseqIf const &other)
3711 {
3712 IfLetExpr::operator= (other);
3713 // match_arm_patterns = other.match_arm_patterns;
3714 // value = other.value->clone_expr();
3715 // if_block = other.if_block->clone_block_expr();
3716 if_expr = other.if_expr->clone_if_expr ();
3717
3718 return *this;
3719 }
3720
3721 // move constructors
3722 IfLetExprConseqIf (IfLetExprConseqIf &&other) = default;
3723 IfLetExprConseqIf &operator= (IfLetExprConseqIf &&other) = default;
3724
3725 void accept_vis (HIRFullVisitor &vis) override;
3726 void accept_vis (HIRExpressionVisitor &vis) override;
3727
3728 protected:
3729 /* Use covariance to implement clone function as returning this object rather
3730 * than base */
3731 IfLetExprConseqIf *clone_expr_impl () const override
3732 {
3733 return new IfLetExprConseqIf (*this);
3734 }
3735
3736 /* Use covariance to implement clone function as returning this object rather
3737 * than base */
3738 IfLetExprConseqIf *clone_expr_with_block_impl () const override
3739 {
3740 return new IfLetExprConseqIf (*this);
3741 }
3742
3743 /* Use covariance to implement clone function as returning this object rather
3744 * than base */
3745 IfLetExprConseqIf *clone_if_let_expr_impl () const override
3746 {
3747 return new IfLetExprConseqIf (*this);
3748 }
3749 };
3750
3751 /* HIR node representing "if let" expression with an "else if let" expression at
3752 * the end */
3753 class IfLetExprConseqIfLet : public IfLetExpr
3754 {
3755 std::unique_ptr<IfLetExpr> if_let_expr;
3756
3757 public:
3758 std::string as_string () const override;
3759
3760 IfLetExprConseqIfLet (
3761 Analysis::NodeMapping mappings,
3762 std::vector<std::unique_ptr<Pattern> > match_arm_patterns,
3763 std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block,
3764 std::unique_ptr<IfLetExpr> if_let_expr, Location locus)
3765 : IfLetExpr (std::move (mappings), std::move (match_arm_patterns),
3766 std::move (value), std::move (if_block), locus),
3767 if_let_expr (std::move (if_let_expr))
3768 {}
3769 // outer attributes not allowed
3770
3771 // copy constructor with clone
3772 IfLetExprConseqIfLet (IfLetExprConseqIfLet const &other)
3773 : IfLetExpr (other), if_let_expr (other.if_let_expr->clone_if_let_expr ())
3774 {}
3775
3776 // overload assignment operator to clone
3777 IfLetExprConseqIfLet &operator= (IfLetExprConseqIfLet const &other)
3778 {
3779 IfLetExpr::operator= (other);
3780 // match_arm_patterns = other.match_arm_patterns;
3781 // value = other.value->clone_expr();
3782 // if_block = other.if_block->clone_block_expr();
3783 if_let_expr = other.if_let_expr->clone_if_let_expr ();
3784
3785 return *this;
3786 }
3787
3788 // move constructors
3789 IfLetExprConseqIfLet (IfLetExprConseqIfLet &&other) = default;
3790 IfLetExprConseqIfLet &operator= (IfLetExprConseqIfLet &&other) = default;
3791
3792 void accept_vis (HIRFullVisitor &vis) override;
3793 void accept_vis (HIRExpressionVisitor &vis) override;
3794
3795 protected:
3796 /* Use covariance to implement clone function as returning this object rather
3797 * than base */
3798 IfLetExprConseqIfLet *clone_expr_impl () const override
3799 {
3800 return new IfLetExprConseqIfLet (*this);
3801 }
3802
3803 /* Use covariance to implement clone function as returning this object rather
3804 * than base */
3805 IfLetExprConseqIfLet *clone_expr_with_block_impl () const override
3806 {
3807 return new IfLetExprConseqIfLet (*this);
3808 }
3809
3810 /* Use covariance to implement clone function as returning this object rather
3811 * than base */
3812 IfLetExprConseqIfLet *clone_if_let_expr_impl () const override
3813 {
3814 return new IfLetExprConseqIfLet (*this);
3815 }
3816 };
3817
3818 // Match arm expression
3819 struct MatchArm
3820 {
3821 private:
3822 AST::AttrVec outer_attrs;
3823 std::vector<std::unique_ptr<Pattern> > match_arm_patterns;
3824 std::unique_ptr<Expr> guard_expr;
3825 Location locus;
3826
3827 public:
3828 // Returns whether the MatchArm has a match arm guard expression
3829 bool has_match_arm_guard () const { return guard_expr != nullptr; }
3830
3831 // Constructor for match arm with a guard expression
3832 MatchArm (std::vector<std::unique_ptr<Pattern> > match_arm_patterns,
3833 Location locus, std::unique_ptr<Expr> guard_expr = nullptr,
3834 AST::AttrVec outer_attrs = AST::AttrVec ())
3835 : outer_attrs (std::move (outer_attrs)),
3836 match_arm_patterns (std::move (match_arm_patterns)),
3837 guard_expr (std::move (guard_expr)), locus (locus)
3838 {}
3839
3840 // Copy constructor with clone
3841 MatchArm (MatchArm const &other) : outer_attrs (other.outer_attrs)
3842 {
3843 // guard to protect from null pointer dereference
3844 if (other.guard_expr != nullptr)
3845 guard_expr = other.guard_expr->clone_expr ();
3846
3847 match_arm_patterns.reserve (other.match_arm_patterns.size ());
3848 for (const auto &e : other.match_arm_patterns)
3849 match_arm_patterns.push_back (e->clone_pattern ());
3850
3851 locus = other.locus;
3852 }
3853
3854 ~MatchArm () = default;
3855
3856 // Overload assignment operator to clone
3857 MatchArm &operator= (MatchArm const &other)
3858 {
3859 outer_attrs = other.outer_attrs;
3860
3861 if (other.guard_expr != nullptr)
3862 guard_expr = other.guard_expr->clone_expr ();
3863
3864 match_arm_patterns.clear ();
3865 match_arm_patterns.reserve (other.match_arm_patterns.size ());
3866 for (const auto &e : other.match_arm_patterns)
3867 match_arm_patterns.push_back (e->clone_pattern ());
3868
3869 return *this;
3870 }
3871
3872 // move constructors
3873 MatchArm (MatchArm &&other) = default;
3874 MatchArm &operator= (MatchArm &&other) = default;
3875
3876 // Returns whether match arm is in an error state.
3877 bool is_error () const { return match_arm_patterns.empty (); }
3878
3879 // Creates a match arm in an error state.
3880 static MatchArm create_error ()
3881 {
3882 Location locus = Location ();
3883 return MatchArm (std::vector<std::unique_ptr<Pattern> > (), locus);
3884 }
3885
3886 std::string as_string () const;
3887
3888 std::vector<std::unique_ptr<Pattern> > &get_patterns ()
3889 {
3890 return match_arm_patterns;
3891 }
3892
3893 std::unique_ptr<Expr> &get_guard_expr ()
3894 {
3895 rust_assert (has_match_arm_guard ());
3896 return guard_expr;
3897 }
3898
3899 Location get_locus () const { return locus; }
3900 };
3901
3902 /* A "match case" - a correlated match arm and resulting expression. Not
3903 * abstract. */
3904 struct MatchCase
3905 {
3906 private:
3907 Analysis::NodeMapping mappings;
3908 MatchArm arm;
3909 std::unique_ptr<Expr> expr;
3910
3911 public:
3912 MatchCase (Analysis::NodeMapping mappings, MatchArm arm,
3913 std::unique_ptr<Expr> expr)
3914 : mappings (mappings), arm (std::move (arm)), expr (std::move (expr))
3915 {}
3916
3917 MatchCase (const MatchCase &other)
3918 : mappings (other.mappings), arm (other.arm),
3919 expr (other.expr->clone_expr ())
3920 {}
3921
3922 MatchCase &operator= (const MatchCase &other)
3923 {
3924 mappings = other.mappings;
3925 arm = other.arm;
3926 expr = other.expr->clone_expr ();
3927
3928 return *this;
3929 }
3930
3931 MatchCase (MatchCase &&other) = default;
3932 MatchCase &operator= (MatchCase &&other) = default;
3933
3934 ~MatchCase () = default;
3935
3936 std::string as_string () const;
3937
3938 Analysis::NodeMapping get_mappings () const { return mappings; }
3939
3940 MatchArm &get_arm () { return arm; }
3941 std::unique_ptr<Expr> &get_expr () { return expr; }
3942 };
3943
3944 // Match expression HIR node
3945 class MatchExpr : public ExprWithBlock
3946 {
3947 std::unique_ptr<Expr> branch_value;
3948 AST::AttrVec inner_attrs;
3949 std::vector<MatchCase> match_arms;
3950 Location locus;
3951
3952 public:
3953 std::string as_string () const override;
3954
3955 bool has_match_arms () const { return !match_arms.empty (); }
3956
3957 MatchExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> branch_value,
3958 std::vector<MatchCase> match_arms, AST::AttrVec inner_attrs,
3959 AST::AttrVec outer_attrs, Location locus)
3960 : ExprWithBlock (std::move (mappings), std::move (outer_attrs)),
3961 branch_value (std::move (branch_value)),
3962 inner_attrs (std::move (inner_attrs)),
3963 match_arms (std::move (match_arms)), locus (locus)
3964 {}
3965
3966 // Copy constructor requires clone due to unique_ptr
3967 MatchExpr (MatchExpr const &other)
3968 : ExprWithBlock (other), branch_value (other.branch_value->clone_expr ()),
3969 inner_attrs (other.inner_attrs), match_arms (other.match_arms),
3970 locus (other.locus)
3971 {
3972 /*match_arms.reserve (other.match_arms.size ());
3973 for (const auto &e : other.match_arms)
3974 match_arms.push_back (e->clone_match_case ());*/
3975 }
3976
3977 // Overloaded assignment operator to clone due to unique_ptr
3978 MatchExpr &operator= (MatchExpr const &other)
3979 {
3980 ExprWithBlock::operator= (other);
3981 branch_value = other.branch_value->clone_expr ();
3982 inner_attrs = other.inner_attrs;
3983 match_arms = other.match_arms;
3984 // outer_attrs = other.outer_attrs;
3985 locus = other.locus;
3986
3987 /*match_arms.reserve (other.match_arms.size ());
3988 for (const auto &e : other.match_arms)
3989 match_arms.push_back (e->clone_match_case ());*/
3990
3991 return *this;
3992 }
3993
3994 // move constructors
3995 MatchExpr (MatchExpr &&other) = default;
3996 MatchExpr &operator= (MatchExpr &&other) = default;
3997
3998 Location get_locus () const override final { return locus; }
3999
4000 void accept_vis (HIRFullVisitor &vis) override;
4001 void accept_vis (HIRExpressionVisitor &vis) override;
4002
4003 std::unique_ptr<Expr> &get_scrutinee_expr ()
4004 {
4005 rust_assert (branch_value != nullptr);
4006 return branch_value;
4007 }
4008
4009 const std::vector<MatchCase> &get_match_cases () const { return match_arms; }
4010 std::vector<MatchCase> &get_match_cases () { return match_arms; }
4011
4012 ExprType get_expression_type () const final override
4013 {
4014 return ExprType::Match;
4015 }
4016
4017 protected:
4018 /* Use covariance to implement clone function as returning this object rather
4019 * than base */
4020 MatchExpr *clone_expr_impl () const override { return new MatchExpr (*this); }
4021
4022 /* Use covariance to implement clone function as returning this object rather
4023 * than base */
4024 MatchExpr *clone_expr_with_block_impl () const override
4025 {
4026 return new MatchExpr (*this);
4027 }
4028 };
4029
4030 // Await expression HIR node (pseudo-member variable access)
4031 class AwaitExpr : public ExprWithoutBlock
4032 {
4033 std::unique_ptr<Expr> awaited_expr;
4034 Location locus;
4035
4036 public:
4037 // TODO: ensure outer attributes are actually allowed
4038 AwaitExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> awaited_expr,
4039 AST::AttrVec outer_attrs, Location locus)
4040 : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
4041 awaited_expr (std::move (awaited_expr)), locus (locus)
4042 {}
4043
4044 // copy constructor with clone
4045 AwaitExpr (AwaitExpr const &other)
4046 : ExprWithoutBlock (other),
4047 awaited_expr (other.awaited_expr->clone_expr ()), locus (other.locus)
4048 {}
4049
4050 // overloaded assignment operator with clone
4051 AwaitExpr &operator= (AwaitExpr const &other)
4052 {
4053 ExprWithoutBlock::operator= (other);
4054 awaited_expr = other.awaited_expr->clone_expr ();
4055 locus = other.locus;
4056
4057 return *this;
4058 }
4059
4060 // move constructors
4061 AwaitExpr (AwaitExpr &&other) = default;
4062 AwaitExpr &operator= (AwaitExpr &&other) = default;
4063
4064 std::string as_string () const override;
4065
4066 Location get_locus () const override final { return locus; }
4067
4068 void accept_vis (HIRFullVisitor &vis) override;
4069 void accept_vis (HIRExpressionVisitor &vis) override;
4070
4071 ExprType get_expression_type () const final override
4072 {
4073 return ExprType::Await;
4074 }
4075
4076 protected:
4077 /* Use covariance to implement clone function as returning this object rather
4078 * than base */
4079 AwaitExpr *clone_expr_without_block_impl () const override
4080 {
4081 return new AwaitExpr (*this);
4082 }
4083 };
4084
4085 // Async block expression HIR node (block expr that evaluates to a future)
4086 class AsyncBlockExpr : public ExprWithBlock
4087 {
4088 bool has_move;
4089 std::unique_ptr<BlockExpr> block_expr;
4090 Location locus;
4091
4092 public:
4093 AsyncBlockExpr (Analysis::NodeMapping mappings,
4094 std::unique_ptr<BlockExpr> block_expr, bool has_move,
4095 AST::AttrVec outer_attrs, Location locus)
4096 : ExprWithBlock (std::move (mappings), std::move (outer_attrs)),
4097 has_move (has_move), block_expr (std::move (block_expr)), locus (locus)
4098 {}
4099
4100 // copy constructor with clone
4101 AsyncBlockExpr (AsyncBlockExpr const &other)
4102 : ExprWithBlock (other), has_move (other.has_move),
4103 block_expr (other.block_expr->clone_block_expr ()), locus (other.locus)
4104 {}
4105
4106 // overloaded assignment operator to clone
4107 AsyncBlockExpr &operator= (AsyncBlockExpr const &other)
4108 {
4109 ExprWithBlock::operator= (other);
4110 has_move = other.has_move;
4111 block_expr = other.block_expr->clone_block_expr ();
4112 locus = other.locus;
4113
4114 return *this;
4115 }
4116
4117 // move constructors
4118 AsyncBlockExpr (AsyncBlockExpr &&other) = default;
4119 AsyncBlockExpr &operator= (AsyncBlockExpr &&other) = default;
4120
4121 std::string as_string () const override;
4122
4123 Location get_locus () const override final { return locus; }
4124
4125 void accept_vis (HIRFullVisitor &vis) override;
4126 void accept_vis (HIRExpressionVisitor &vis) override;
4127
4128 ExprType get_expression_type () const final override
4129 {
4130 return ExprType::AsyncBlock;
4131 }
4132
4133 protected:
4134 /* Use covariance to implement clone function as returning this object rather
4135 * than base */
4136 AsyncBlockExpr *clone_expr_with_block_impl () const override
4137 {
4138 return new AsyncBlockExpr (*this);
4139 }
4140 };
4141
4142 // this is a utility helper class for type-checking and code-generation
4143 class OperatorExprMeta
4144 {
4145 public:
4146 OperatorExprMeta (HIR::CompoundAssignmentExpr &expr)
4147 : node_mappings (expr.get_mappings ()),
4148 lvalue_mappings (expr.get_expr ()->get_mappings ()),
4149 locus (expr.get_locus ())
4150 {}
4151
4152 OperatorExprMeta (HIR::ArithmeticOrLogicalExpr &expr)
4153 : node_mappings (expr.get_mappings ()),
4154 lvalue_mappings (expr.get_expr ()->get_mappings ()),
4155 locus (expr.get_locus ())
4156 {}
4157
4158 OperatorExprMeta (HIR::NegationExpr &expr)
4159 : node_mappings (expr.get_mappings ()),
4160 lvalue_mappings (expr.get_expr ()->get_mappings ()),
4161 locus (expr.get_locus ())
4162 {}
4163
4164 OperatorExprMeta (HIR::DereferenceExpr &expr)
4165 : node_mappings (expr.get_mappings ()),
4166 lvalue_mappings (expr.get_expr ()->get_mappings ()),
4167 locus (expr.get_locus ())
4168 {}
4169
4170 OperatorExprMeta (HIR::ArrayIndexExpr &expr)
4171 : node_mappings (expr.get_mappings ()),
4172 lvalue_mappings (expr.get_array_expr ()->get_mappings ()),
4173 locus (expr.get_locus ())
4174 {}
4175
4176 const Analysis::NodeMapping &get_mappings () const { return node_mappings; }
4177
4178 const Analysis::NodeMapping &get_lvalue_mappings () const
4179 {
4180 return lvalue_mappings;
4181 }
4182
4183 Location get_locus () const { return locus; }
4184
4185 private:
4186 const Analysis::NodeMapping node_mappings;
4187 const Analysis::NodeMapping lvalue_mappings;
4188 Location locus;
4189 };
4190
4191 } // namespace HIR
4192 } // namespace Rust
4193
4194 #endif