Branch data Line data Source code
1 : : // Copyright (C) 2025 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>.
18 : :
19 : : #ifndef RUST_DESUGAR_FOR_LOOPS_H
20 : : #define RUST_DESUGAR_FOR_LOOPS_H
21 : :
22 : : #include "rust-ast-builder.h"
23 : : #include "rust-expr.h"
24 : :
25 : : namespace Rust {
26 : : namespace AST {
27 : :
28 : : // Desugar for-loops into a set of other AST nodes. The desugar is of the
29 : : // following form:
30 : : //
31 : : // ```
32 : : // for <pat> in <head> <body>
33 : : // ```
34 : : //
35 : : // becomes:
36 : : //
37 : : // ```
38 : : // {
39 : : // let result = match ::std::iter::IntoIterator::into_iter(<head>) {
40 : : // mut iter => {
41 : : // loop {
42 : : // let mut __next;
43 : : // match ::std::iter::Iterator::next(&mut iter) {
44 : : // ::std::option::Option::Some(val) => __next = val,
45 : : // ::std::option::Option::None => break
46 : : // };
47 : : // let <pat> = __next;
48 : : //
49 : : // <body>;
50 : : // }
51 : : // }
52 : : // };
53 : : // result
54 : : // }
55 : : // ```
56 : : //
57 : : // NOTE: In a perfect world, this would be an immutable visitor which would take
58 : : // ownership of the AST node and return a new one, instead of mutating this one
59 : : // in place. Nevertheless, this isn't Rust, and doing immutable visitors in C++
60 : : // sucks, and the world isn't perfect, so we are impure and sad.
61 : : //
62 : : // NOTE: This class could eventually be removed in favor of
63 : : // an HIR desugar. This would avoid mutating the AST and would be cleaner.
64 : : // However, it requires multiple changes in the way we do typechecking and name
65 : : // resolution, as this desugar creates new bindings. Because of this, these new
66 : : // bindings need to be inserted into the name-resolution context outside of the
67 : : // name resolution pass, which is difficult. Those bindings are needed because
68 : : // of the way the typechecker is currently structured, where it will fetch name
69 : : // resolution information in order to typecheck paths - which technically isn't
70 : : // necessary.
71 : : class DesugarForLoops
72 : : {
73 : : public:
74 : : static void go (std::unique_ptr<Expr> &ptr);
75 : :
76 : : private:
77 : : DesugarForLoops ();
78 : :
79 : : struct DesugarCtx
80 : : {
81 : 16 : DesugarCtx (location_t loc) : builder (Builder (loc)), loc (loc) {}
82 : :
83 : : Builder builder;
84 : : location_t loc;
85 : :
86 : : MatchCase make_break_arm ();
87 : : MatchCase make_continue_arm ();
88 : :
89 : : constexpr static const char *continue_pattern_id = "#val";
90 : : constexpr static const char *next_value_id = "#__next";
91 : : constexpr static const char *iter_id = "#iter";
92 : : constexpr static const char *result_id = "#result";
93 : : };
94 : :
95 : : std::unique_ptr<Expr> desugar (ForLoopExpr &expr);
96 : : };
97 : :
98 : : } // namespace AST
99 : : } // namespace Rust
100 : :
101 : : #endif // ! RUST_DESUGAR_FOR_LOOPS_H
|