Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>.
18 : :
19 : : #include "rust-ast-lower-pattern.h"
20 : : #include "rust-ast-lower-expr.h"
21 : :
22 : : namespace Rust {
23 : : namespace HIR {
24 : :
25 : 14425 : ASTLoweringPattern::ASTLoweringPattern () : translated (nullptr) {}
26 : :
27 : : HIR::Pattern *
28 : 14425 : ASTLoweringPattern::translate (AST::Pattern &pattern, bool is_let_top_level)
29 : : {
30 : 14425 : ASTLoweringPattern resolver;
31 : 14425 : resolver.is_let_top_level = is_let_top_level;
32 : 14425 : pattern.accept_vis (resolver);
33 : :
34 : 14425 : rust_assert (resolver.translated != nullptr);
35 : :
36 : 14425 : resolver.mappings->insert_hir_pattern (resolver.translated);
37 : 14425 : resolver.mappings->insert_location (
38 : 14425 : resolver.translated->get_mappings ().get_hirid (), pattern.get_locus ());
39 : :
40 : 14425 : return resolver.translated;
41 : 14425 : }
42 : :
43 : : void
44 : 13596 : ASTLoweringPattern::visit (AST::IdentifierPattern &pattern)
45 : : {
46 : 13596 : auto crate_num = mappings->get_current_crate ();
47 : 27192 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
48 : 13596 : mappings->get_next_hir_id (crate_num),
49 : 13596 : UNKNOWN_LOCAL_DEFID);
50 : :
51 : 13596 : std::unique_ptr<Pattern> to_bind;
52 : 13596 : translated
53 : 13596 : = new HIR::IdentifierPattern (mapping, pattern.get_ident (),
54 : 13596 : pattern.get_locus (), pattern.get_is_ref (),
55 : 13596 : pattern.get_is_mut () ? Mutability::Mut
56 : : : Mutability::Imm,
57 : 40214 : std::move (to_bind));
58 : 13596 : }
59 : :
60 : : void
61 : 128 : ASTLoweringPattern::visit (AST::PathInExpression &pattern)
62 : : {
63 : 128 : translated = ASTLowerPathInExpression::translate (pattern);
64 : 128 : }
65 : :
66 : : void
67 : 107 : ASTLoweringPattern::visit (AST::TupleStructPattern &pattern)
68 : : {
69 : 107 : HIR::PathInExpression *path
70 : 107 : = ASTLowerPathInExpression::translate (pattern.get_path ());
71 : :
72 : 107 : TupleStructItems *lowered = nullptr;
73 : 107 : auto &items = pattern.get_items ();
74 : 107 : switch (items.get_item_type ())
75 : : {
76 : 0 : case AST::TupleStructItems::RANGE: {
77 : : // TODO
78 : 0 : rust_unreachable ();
79 : : }
80 : 107 : break;
81 : :
82 : 107 : case AST::TupleStructItems::NO_RANGE: {
83 : 107 : AST::TupleStructItemsNoRange &items_no_range
84 : : = static_cast<AST::TupleStructItemsNoRange &> (items);
85 : :
86 : 107 : std::vector<std::unique_ptr<HIR::Pattern>> patterns;
87 : 222 : for (auto &inner_pattern : items_no_range.get_patterns ())
88 : : {
89 : 115 : HIR::Pattern *p = ASTLoweringPattern::translate (*inner_pattern);
90 : 115 : patterns.push_back (std::unique_ptr<HIR::Pattern> (p));
91 : : }
92 : :
93 : 107 : lowered = new HIR::TupleStructItemsNoRange (std::move (patterns));
94 : 107 : }
95 : 107 : break;
96 : : }
97 : :
98 : 107 : auto crate_num = mappings->get_current_crate ();
99 : 214 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
100 : 107 : mappings->get_next_hir_id (crate_num),
101 : 107 : UNKNOWN_LOCAL_DEFID);
102 : :
103 : 214 : translated = new HIR::TupleStructPattern (
104 : 107 : mapping, *path, std::unique_ptr<HIR::TupleStructItems> (lowered));
105 : 107 : }
106 : :
107 : : void
108 : 35 : ASTLoweringPattern::visit (AST::StructPattern &pattern)
109 : : {
110 : 35 : HIR::PathInExpression *path
111 : 35 : = ASTLowerPathInExpression::translate (pattern.get_path ());
112 : :
113 : 35 : auto &raw_elems = pattern.get_struct_pattern_elems ();
114 : 35 : rust_assert (!raw_elems.has_etc ());
115 : :
116 : 35 : std::vector<std::unique_ptr<HIR::StructPatternField>> fields;
117 : 100 : for (auto &field : raw_elems.get_struct_pattern_fields ())
118 : : {
119 : 65 : HIR::StructPatternField *f = nullptr;
120 : 65 : switch (field->get_item_type ())
121 : : {
122 : 1 : case AST::StructPatternField::ItemType::TUPLE_PAT: {
123 : 1 : auto &tuple
124 : 1 : = static_cast<AST::StructPatternFieldTuplePat &> (*field);
125 : :
126 : 1 : auto crate_num = mappings->get_current_crate ();
127 : 1 : Analysis::NodeMapping mapping (crate_num, tuple.get_node_id (),
128 : 1 : mappings->get_next_hir_id (
129 : : crate_num),
130 : 1 : UNKNOWN_LOCAL_DEFID);
131 : :
132 : 1 : std::unique_ptr<HIR::Pattern> pat (
133 : 1 : ASTLoweringPattern::translate (tuple.get_index_pattern ()));
134 : :
135 : 2 : f = new HIR::StructPatternFieldTuplePat (mapping,
136 : : tuple.get_index (),
137 : : std::move (pat),
138 : 1 : tuple.get_outer_attrs (),
139 : 1 : tuple.get_locus ());
140 : 1 : }
141 : 1 : break;
142 : :
143 : 1 : case AST::StructPatternField::ItemType::IDENT_PAT: {
144 : 1 : AST::StructPatternFieldIdentPat &ident
145 : 1 : = static_cast<AST::StructPatternFieldIdentPat &> (*field);
146 : :
147 : 1 : auto crate_num = mappings->get_current_crate ();
148 : 1 : Analysis::NodeMapping mapping (crate_num, ident.get_node_id (),
149 : 1 : mappings->get_next_hir_id (
150 : : crate_num),
151 : 1 : UNKNOWN_LOCAL_DEFID);
152 : :
153 : 1 : std::unique_ptr<HIR::Pattern> pat (
154 : 1 : ASTLoweringPattern::translate (ident.get_ident_pattern ()));
155 : :
156 : 1 : f = new HIR::StructPatternFieldIdentPat (mapping,
157 : : ident.get_identifier (),
158 : : std::move (pat),
159 : 1 : ident.get_outer_attrs (),
160 : 2 : ident.get_locus ());
161 : 1 : }
162 : 1 : break;
163 : :
164 : 63 : case AST::StructPatternField::ItemType::IDENT: {
165 : 63 : AST::StructPatternFieldIdent &ident
166 : 63 : = static_cast<AST::StructPatternFieldIdent &> (*field.get ());
167 : :
168 : 63 : auto crate_num = mappings->get_current_crate ();
169 : 63 : Analysis::NodeMapping mapping (crate_num, ident.get_node_id (),
170 : 63 : mappings->get_next_hir_id (
171 : : crate_num),
172 : 63 : UNKNOWN_LOCAL_DEFID);
173 : :
174 : 63 : f = new HIR::StructPatternFieldIdent (
175 : 63 : mapping, ident.get_identifier (), ident.is_ref (),
176 : 63 : ident.is_mut () ? Mutability::Mut : Mutability::Imm,
177 : 189 : ident.get_outer_attrs (), ident.get_locus ());
178 : : }
179 : 63 : break;
180 : : }
181 : :
182 : : // insert the reverse mappings and locations
183 : 65 : auto field_id = f->get_mappings ().get_hirid ();
184 : 65 : auto field_node_id = f->get_mappings ().get_nodeid ();
185 : 65 : mappings->insert_location (field_id, f->get_locus ());
186 : 65 : mappings->insert_node_to_hir (field_node_id, field_id);
187 : :
188 : : // add it to the lowered fields list
189 : 65 : fields.push_back (std::unique_ptr<HIR::StructPatternField> (f));
190 : : }
191 : :
192 : 35 : auto crate_num = mappings->get_current_crate ();
193 : 70 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
194 : 35 : mappings->get_next_hir_id (crate_num),
195 : 35 : UNKNOWN_LOCAL_DEFID);
196 : :
197 : 35 : HIR::StructPatternElements elems (std::move (fields));
198 : 35 : translated = new HIR::StructPattern (mapping, *path, std::move (elems));
199 : 35 : }
200 : :
201 : : void
202 : 219 : ASTLoweringPattern::visit (AST::WildcardPattern &pattern)
203 : : {
204 : 219 : auto crate_num = mappings->get_current_crate ();
205 : 438 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
206 : 219 : mappings->get_next_hir_id (crate_num),
207 : 219 : UNKNOWN_LOCAL_DEFID);
208 : :
209 : 219 : translated = new HIR::WildcardPattern (mapping, pattern.get_locus ());
210 : 219 : }
211 : :
212 : : void
213 : 147 : ASTLoweringPattern::visit (AST::TuplePattern &pattern)
214 : : {
215 : 147 : std::unique_ptr<HIR::TuplePatternItems> items;
216 : 147 : switch (pattern.get_items ().get_pattern_type ())
217 : : {
218 : 147 : case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE: {
219 : 147 : AST::TuplePatternItemsMultiple &ref
220 : : = static_cast<AST::TuplePatternItemsMultiple &> (
221 : 147 : pattern.get_items ());
222 : 147 : items = lower_tuple_pattern_multiple (ref);
223 : : }
224 : 147 : break;
225 : :
226 : 0 : case AST::TuplePatternItems::TuplePatternItemType::RANGED: {
227 : 0 : AST::TuplePatternItemsRanged &ref
228 : 0 : = static_cast<AST::TuplePatternItemsRanged &> (pattern.get_items ());
229 : 0 : items = lower_tuple_pattern_ranged (ref);
230 : : }
231 : 0 : break;
232 : : }
233 : :
234 : 147 : auto crate_num = mappings->get_current_crate ();
235 : 294 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
236 : 147 : mappings->get_next_hir_id (crate_num),
237 : 147 : UNKNOWN_LOCAL_DEFID);
238 : :
239 : 147 : translated
240 : 147 : = new HIR::TuplePattern (mapping, std::move (items), pattern.get_locus ());
241 : 147 : }
242 : :
243 : : void
244 : 141 : ASTLoweringPattern::visit (AST::LiteralPattern &pattern)
245 : : {
246 : 141 : auto crate_num = mappings->get_current_crate ();
247 : 282 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
248 : 141 : mappings->get_next_hir_id (crate_num),
249 : 141 : UNKNOWN_LOCAL_DEFID);
250 : :
251 : 141 : HIR::Literal l = lower_literal (pattern.get_literal ());
252 : 141 : translated
253 : 141 : = new HIR::LiteralPattern (mapping, std::move (l), pattern.get_locus ());
254 : 141 : }
255 : :
256 : : void
257 : 21 : ASTLoweringPattern::visit (AST::RangePattern &pattern)
258 : : {
259 : 21 : auto upper_bound = lower_range_pattern_bound (pattern.get_upper_bound ());
260 : 21 : auto lower_bound = lower_range_pattern_bound (pattern.get_lower_bound ());
261 : :
262 : 21 : auto crate_num = mappings->get_current_crate ();
263 : 42 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
264 : 21 : mappings->get_next_hir_id (crate_num),
265 : 21 : UNKNOWN_LOCAL_DEFID);
266 : :
267 : 21 : translated
268 : 21 : = new HIR::RangePattern (mapping, std::move (lower_bound),
269 : 21 : std::move (upper_bound), pattern.get_locus ());
270 : 21 : }
271 : :
272 : : void
273 : 1 : ASTLoweringPattern::visit (AST::GroupedPattern &pattern)
274 : : {
275 : 1 : is_let_top_level = false;
276 : 1 : pattern.get_pattern_in_parens ().accept_vis (*this);
277 : 1 : }
278 : :
279 : : void
280 : 28 : ASTLoweringPattern::visit (AST::ReferencePattern &pattern)
281 : : {
282 : 28 : auto crate_num = mappings->get_current_crate ();
283 : 56 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
284 : 28 : mappings->get_next_hir_id (crate_num),
285 : 28 : UNKNOWN_LOCAL_DEFID);
286 : :
287 : 28 : HIR::Pattern *inner
288 : 28 : = ASTLoweringPattern::translate (pattern.get_referenced_pattern ());
289 : :
290 : 28 : translated
291 : 28 : = new HIR::ReferencePattern (mapping, std::unique_ptr<HIR::Pattern> (inner),
292 : 28 : pattern.get_is_mut () ? Mutability::Mut
293 : : : Mutability::Imm,
294 : 56 : pattern.get_locus ());
295 : :
296 : 28 : if (pattern.is_double_reference ())
297 : : {
298 : 16 : Analysis::NodeMapping mapping2 (crate_num, pattern.get_node_id (),
299 : 8 : mappings->get_next_hir_id (crate_num),
300 : 8 : UNKNOWN_LOCAL_DEFID);
301 : 8 : translated
302 : 8 : = new HIR::ReferencePattern (mapping2,
303 : 8 : std::unique_ptr<HIR::Pattern> (translated),
304 : 8 : Mutability::Imm, pattern.get_locus ());
305 : : }
306 : 28 : }
307 : :
308 : : void
309 : 0 : ASTLoweringPattern::visit (AST::SlicePattern &pattern)
310 : : {
311 : 0 : std::vector<std::unique_ptr<HIR::Pattern>> items;
312 : 0 : for (auto &p : pattern.get_items ())
313 : : {
314 : 0 : HIR::Pattern *item = ASTLoweringPattern::translate (*p);
315 : 0 : items.push_back (std::unique_ptr<HIR::Pattern> (item));
316 : : }
317 : :
318 : 0 : auto crate_num = mappings->get_current_crate ();
319 : 0 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
320 : 0 : mappings->get_next_hir_id (crate_num),
321 : 0 : UNKNOWN_LOCAL_DEFID);
322 : :
323 : 0 : translated
324 : 0 : = new HIR::SlicePattern (mapping, std::move (items), pattern.get_locus ());
325 : 0 : }
326 : :
327 : : void
328 : 3 : ASTLoweringPattern::visit (AST::AltPattern &pattern)
329 : : {
330 : 3 : auto crate_num = mappings->get_current_crate ();
331 : 6 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
332 : 3 : mappings->get_next_hir_id (crate_num),
333 : 3 : UNKNOWN_LOCAL_DEFID);
334 : :
335 : 3 : std::vector<std::unique_ptr<HIR::Pattern>> alts;
336 : :
337 : 10 : for (auto &alt : pattern.get_alts ())
338 : : {
339 : 7 : alts.push_back (
340 : 7 : std::unique_ptr<HIR::Pattern> (ASTLoweringPattern::translate (*alt)));
341 : : }
342 : :
343 : 3 : translated
344 : 3 : = new HIR::AltPattern (mapping, std::move (alts), pattern.get_locus ());
345 : :
346 : 3 : if (is_let_top_level)
347 : : {
348 : 1 : rich_location richloc (line_table, pattern.get_locus ());
349 : 1 : richloc.add_fixit_replace ("use an outer grouped pattern");
350 : 1 : rust_error_at (
351 : : richloc, "top level or-patterns are not allowed for %<let%> bindings");
352 : 1 : }
353 : 3 : }
354 : :
355 : : } // namespace HIR
356 : : } // namespace Rust
|