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 : : #include "rust-system.h"
22 : :
23 : : namespace Rust {
24 : : namespace HIR {
25 : :
26 : 25838 : ASTLoweringPattern::ASTLoweringPattern ()
27 : 25838 : : translated (nullptr), is_let_top_level (false)
28 : 25838 : {}
29 : :
30 : : HIR::Pattern *
31 : 25838 : ASTLoweringPattern::translate (AST::Pattern &pattern, bool is_let_top_level)
32 : : {
33 : 25838 : ASTLoweringPattern resolver;
34 : 25838 : resolver.is_let_top_level = is_let_top_level;
35 : 25838 : pattern.accept_vis (resolver);
36 : :
37 : 25838 : rust_assert (resolver.translated != nullptr);
38 : :
39 : 25838 : resolver.mappings.insert_hir_pattern (resolver.translated);
40 : 25838 : resolver.mappings.insert_location (
41 : 25838 : resolver.translated->get_mappings ().get_hirid (), pattern.get_locus ());
42 : :
43 : 25838 : return resolver.translated;
44 : 25838 : }
45 : :
46 : : void
47 : 21264 : ASTLoweringPattern::visit (AST::IdentifierPattern &pattern)
48 : : {
49 : 21264 : auto crate_num = mappings.get_current_crate ();
50 : 42528 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
51 : 21264 : mappings.get_next_hir_id (crate_num),
52 : 21264 : UNKNOWN_LOCAL_DEFID);
53 : :
54 : 21264 : std::unique_ptr<Pattern> subpattern;
55 : 21264 : if (pattern.has_subpattern ())
56 : : {
57 : 18 : subpattern = std::unique_ptr<Pattern> (
58 : 18 : ASTLoweringPattern::translate (pattern.get_subpattern ()));
59 : : }
60 : 21264 : translated
61 : 21264 : = new HIR::IdentifierPattern (mapping, pattern.get_ident (),
62 : 21264 : pattern.get_locus (), pattern.get_is_ref (),
63 : 21264 : pattern.get_is_mut () ? Mutability::Mut
64 : : : Mutability::Imm,
65 : 62874 : std::move (subpattern));
66 : 21264 : }
67 : :
68 : : void
69 : 1084 : ASTLoweringPattern::visit (AST::PathInExpression &pattern)
70 : : {
71 : 1084 : translated = ASTLowerPathInExpression::translate (pattern);
72 : 1084 : }
73 : :
74 : : void
75 : 1006 : ASTLoweringPattern::visit (AST::TupleStructPattern &pattern)
76 : : {
77 : 1006 : HIR::PathInExpression *path
78 : 1006 : = ASTLowerPathInExpression::translate (pattern.get_path ());
79 : :
80 : 1006 : TupleStructItems *lowered = nullptr;
81 : 1006 : auto &items = pattern.get_items ();
82 : 1006 : switch (items.get_item_type ())
83 : : {
84 : 39 : case AST::TupleStructItems::HAS_REST:
85 : 39 : {
86 : 39 : AST::TupleStructItemsHasRest &items_has_rest
87 : : = static_cast<AST::TupleStructItemsHasRest &> (items);
88 : :
89 : 39 : std::vector<std::unique_ptr<HIR::Pattern>> lower_patterns;
90 : 39 : lower_patterns.reserve (items_has_rest.get_lower_patterns ().size ());
91 : 70 : for (auto &pattern_member : items_has_rest.get_lower_patterns ())
92 : : {
93 : 31 : lower_patterns.emplace_back (
94 : 31 : ASTLoweringPattern::translate (*pattern_member));
95 : : }
96 : :
97 : 39 : std::vector<std::unique_ptr<HIR::Pattern>> upper_patterns;
98 : 39 : upper_patterns.reserve (items_has_rest.get_upper_patterns ().size ());
99 : 58 : for (auto &pattern_member : items_has_rest.get_upper_patterns ())
100 : : {
101 : 19 : upper_patterns.emplace_back (
102 : 19 : ASTLoweringPattern::translate (*pattern_member));
103 : : }
104 : :
105 : 39 : lowered = new HIR::TupleStructItemsHasRest (std::move (lower_patterns),
106 : 39 : std::move (upper_patterns));
107 : 39 : }
108 : 39 : break;
109 : :
110 : 967 : case AST::TupleStructItems::NO_REST:
111 : 967 : {
112 : 967 : AST::TupleStructItemsNoRest &items_no_rest
113 : : = static_cast<AST::TupleStructItemsNoRest &> (items);
114 : :
115 : 967 : std::vector<std::unique_ptr<HIR::Pattern>> patterns;
116 : 967 : patterns.reserve (items_no_rest.get_patterns ().size ());
117 : :
118 : 2012 : for (auto &inner_pattern : items_no_rest.get_patterns ())
119 : 1045 : patterns.emplace_back (
120 : 1045 : ASTLoweringPattern::translate (*inner_pattern));
121 : :
122 : 967 : lowered = new HIR::TupleStructItemsNoRest (std::move (patterns));
123 : 967 : }
124 : 967 : break;
125 : : }
126 : :
127 : 1006 : auto crate_num = mappings.get_current_crate ();
128 : 2012 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
129 : 1006 : mappings.get_next_hir_id (crate_num),
130 : 1006 : UNKNOWN_LOCAL_DEFID);
131 : :
132 : 2012 : translated = new HIR::TupleStructPattern (
133 : 1006 : mapping, *path, std::unique_ptr<HIR::TupleStructItems> (lowered));
134 : 1006 : }
135 : :
136 : : void
137 : 150 : ASTLoweringPattern::visit (AST::StructPattern &pattern)
138 : : {
139 : 150 : HIR::PathInExpression *path
140 : 150 : = ASTLowerPathInExpression::translate (pattern.get_path ());
141 : :
142 : 150 : auto &raw_elems = pattern.get_struct_pattern_elems ();
143 : :
144 : 150 : std::vector<std::unique_ptr<HIR::StructPatternField>> fields;
145 : 399 : for (auto &field : raw_elems.get_struct_pattern_fields ())
146 : : {
147 : 249 : HIR::StructPatternField *f = nullptr;
148 : 249 : switch (field->get_item_type ())
149 : : {
150 : 1 : case AST::StructPatternField::ItemType::TUPLE_PAT:
151 : 1 : {
152 : 1 : auto &tuple
153 : 1 : = static_cast<AST::StructPatternFieldTuplePat &> (*field);
154 : :
155 : 1 : auto crate_num = mappings.get_current_crate ();
156 : 1 : Analysis::NodeMapping mapping (crate_num, tuple.get_node_id (),
157 : 1 : mappings.get_next_hir_id (crate_num),
158 : 1 : UNKNOWN_LOCAL_DEFID);
159 : :
160 : 1 : std::unique_ptr<HIR::Pattern> pat (
161 : 1 : ASTLoweringPattern::translate (tuple.get_index_pattern ()));
162 : :
163 : 2 : f = new HIR::StructPatternFieldTuplePat (mapping,
164 : : tuple.get_index (),
165 : : std::move (pat),
166 : 1 : tuple.get_outer_attrs (),
167 : 1 : tuple.get_locus ());
168 : 1 : }
169 : 1 : break;
170 : :
171 : 150 : case AST::StructPatternField::ItemType::IDENT_PAT:
172 : 150 : {
173 : 150 : AST::StructPatternFieldIdentPat &ident
174 : 150 : = static_cast<AST::StructPatternFieldIdentPat &> (*field);
175 : :
176 : 150 : auto crate_num = mappings.get_current_crate ();
177 : 150 : Analysis::NodeMapping mapping (crate_num, ident.get_node_id (),
178 : 150 : mappings.get_next_hir_id (crate_num),
179 : 150 : UNKNOWN_LOCAL_DEFID);
180 : :
181 : 150 : std::unique_ptr<HIR::Pattern> pat (
182 : 150 : ASTLoweringPattern::translate (ident.get_ident_pattern ()));
183 : :
184 : 150 : f = new HIR::StructPatternFieldIdentPat (mapping,
185 : : ident.get_identifier (),
186 : : std::move (pat),
187 : 150 : ident.get_outer_attrs (),
188 : 300 : ident.get_locus ());
189 : 150 : }
190 : 150 : break;
191 : :
192 : 98 : case AST::StructPatternField::ItemType::IDENT:
193 : 98 : {
194 : 98 : AST::StructPatternFieldIdent &ident
195 : 98 : = static_cast<AST::StructPatternFieldIdent &> (*field.get ());
196 : :
197 : 98 : auto crate_num = mappings.get_current_crate ();
198 : 98 : Analysis::NodeMapping mapping (crate_num, ident.get_node_id (),
199 : 98 : mappings.get_next_hir_id (crate_num),
200 : 98 : UNKNOWN_LOCAL_DEFID);
201 : :
202 : 98 : f = new HIR::StructPatternFieldIdent (
203 : 98 : mapping, ident.get_identifier (), ident.is_ref (),
204 : 98 : ident.is_mut () ? Mutability::Mut : Mutability::Imm,
205 : 294 : ident.get_outer_attrs (), ident.get_locus ());
206 : : }
207 : 98 : break;
208 : : }
209 : :
210 : : // insert the reverse mappings and locations
211 : 249 : auto field_id = f->get_mappings ().get_hirid ();
212 : 249 : auto field_node_id = f->get_mappings ().get_nodeid ();
213 : 249 : mappings.insert_location (field_id, f->get_locus ());
214 : 249 : mappings.insert_node_to_hir (field_node_id, field_id);
215 : :
216 : : // add it to the lowered fields list
217 : 249 : fields.emplace_back (f);
218 : : }
219 : :
220 : 150 : auto crate_num = mappings.get_current_crate ();
221 : 300 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
222 : 150 : mappings.get_next_hir_id (crate_num),
223 : 150 : UNKNOWN_LOCAL_DEFID);
224 : :
225 : 150 : HIR::StructPatternElements elems (
226 : 150 : std::move (fields), pattern.get_struct_pattern_elems ().has_rest ());
227 : 150 : translated = new HIR::StructPattern (mapping, *path, std::move (elems));
228 : 150 : }
229 : :
230 : : void
231 : 1045 : ASTLoweringPattern::visit (AST::WildcardPattern &pattern)
232 : : {
233 : 1045 : auto crate_num = mappings.get_current_crate ();
234 : 2090 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
235 : 1045 : mappings.get_next_hir_id (crate_num),
236 : 1045 : UNKNOWN_LOCAL_DEFID);
237 : :
238 : 1045 : translated = new HIR::WildcardPattern (mapping, pattern.get_locus ());
239 : 1045 : }
240 : :
241 : : void
242 : 420 : ASTLoweringPattern::visit (AST::TuplePattern &pattern)
243 : : {
244 : 420 : std::unique_ptr<HIR::TuplePatternItems> items;
245 : 420 : switch (pattern.get_items ().get_item_type ())
246 : : {
247 : 393 : case AST::TuplePatternItems::ItemType::NO_REST:
248 : 393 : {
249 : 393 : AST::TuplePatternItemsNoRest &ref
250 : 393 : = static_cast<AST::TuplePatternItemsNoRest &> (pattern.get_items ());
251 : 393 : items = lower_tuple_pattern_multiple (ref);
252 : : }
253 : 393 : break;
254 : :
255 : 27 : case AST::TuplePatternItems::ItemType::HAS_REST:
256 : 27 : {
257 : 27 : AST::TuplePatternItemsHasRest &ref
258 : 27 : = static_cast<AST::TuplePatternItemsHasRest &> (pattern.get_items ());
259 : 27 : items = lower_tuple_pattern_ranged (ref);
260 : : }
261 : 27 : break;
262 : : }
263 : :
264 : 420 : auto crate_num = mappings.get_current_crate ();
265 : 840 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
266 : 420 : mappings.get_next_hir_id (crate_num),
267 : 420 : UNKNOWN_LOCAL_DEFID);
268 : :
269 : 420 : translated
270 : 420 : = new HIR::TuplePattern (mapping, std::move (items), pattern.get_locus ());
271 : 420 : }
272 : :
273 : : void
274 : 417 : ASTLoweringPattern::visit (AST::LiteralPattern &pattern)
275 : : {
276 : 417 : auto crate_num = mappings.get_current_crate ();
277 : 834 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
278 : 417 : mappings.get_next_hir_id (crate_num),
279 : 417 : UNKNOWN_LOCAL_DEFID);
280 : :
281 : 417 : HIR::Literal l = lower_literal (pattern.get_literal ());
282 : 417 : translated
283 : 417 : = new HIR::LiteralPattern (mapping, std::move (l), pattern.get_locus (),
284 : 834 : pattern.get_has_minus ());
285 : 417 : }
286 : :
287 : : void
288 : 38 : ASTLoweringPattern::visit (AST::RangePattern &pattern)
289 : : {
290 : 38 : auto upper_bound = lower_range_pattern_bound (pattern.get_upper_bound ());
291 : 38 : auto lower_bound = lower_range_pattern_bound (pattern.get_lower_bound ());
292 : :
293 : 38 : auto crate_num = mappings.get_current_crate ();
294 : 76 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
295 : 38 : mappings.get_next_hir_id (crate_num),
296 : 38 : UNKNOWN_LOCAL_DEFID);
297 : :
298 : 38 : bool is_inclusive = (pattern.get_range_kind () == AST::RangeKind::INCLUDED);
299 : :
300 : 38 : translated = new HIR::RangePattern (mapping, std::move (lower_bound),
301 : : std::move (upper_bound),
302 : 38 : pattern.get_locus (), is_inclusive);
303 : 38 : }
304 : :
305 : : void
306 : 2 : ASTLoweringPattern::visit (AST::GroupedPattern &pattern)
307 : : {
308 : 2 : is_let_top_level = false;
309 : 2 : pattern.get_pattern_in_parens ().accept_vis (*this);
310 : 2 : }
311 : :
312 : : void
313 : 191 : ASTLoweringPattern::visit (AST::ReferencePattern &pattern)
314 : : {
315 : 191 : auto crate_num = mappings.get_current_crate ();
316 : 382 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
317 : 191 : mappings.get_next_hir_id (crate_num),
318 : 191 : UNKNOWN_LOCAL_DEFID);
319 : :
320 : 191 : HIR::Pattern *inner
321 : 191 : = ASTLoweringPattern::translate (pattern.get_referenced_pattern ());
322 : :
323 : 191 : translated
324 : 191 : = new HIR::ReferencePattern (mapping, std::unique_ptr<HIR::Pattern> (inner),
325 : 191 : pattern.get_is_mut () ? Mutability::Mut
326 : : : Mutability::Imm,
327 : 382 : pattern.get_locus ());
328 : :
329 : 191 : if (pattern.is_double_reference ())
330 : : {
331 : 16 : Analysis::NodeMapping mapping2 (crate_num, pattern.get_node_id (),
332 : 8 : mappings.get_next_hir_id (crate_num),
333 : 8 : UNKNOWN_LOCAL_DEFID);
334 : 8 : translated
335 : 8 : = new HIR::ReferencePattern (mapping2,
336 : 8 : std::unique_ptr<HIR::Pattern> (translated),
337 : 8 : Mutability::Imm, pattern.get_locus ());
338 : : }
339 : 191 : }
340 : :
341 : : void
342 : 76 : ASTLoweringPattern::visit (AST::SlicePattern &pattern)
343 : : {
344 : 76 : std::unique_ptr<HIR::SlicePatternItems> items;
345 : :
346 : 76 : switch (pattern.get_items ().get_item_type ())
347 : : {
348 : 32 : case AST::SlicePatternItems::ItemType::NO_REST:
349 : 32 : {
350 : 32 : auto &ref
351 : 32 : = static_cast<AST::SlicePatternItemsNoRest &> (pattern.get_items ());
352 : 32 : items = ASTLoweringBase::lower_slice_pattern_no_rest (ref);
353 : : }
354 : 32 : break;
355 : 44 : case AST::SlicePatternItems::ItemType::HAS_REST:
356 : 44 : {
357 : 44 : auto &ref
358 : 44 : = static_cast<AST::SlicePatternItemsHasRest &> (pattern.get_items ());
359 : 44 : items = ASTLoweringBase::lower_slice_pattern_has_rest (ref);
360 : : }
361 : 44 : break;
362 : : }
363 : :
364 : 76 : auto crate_num = mappings.get_current_crate ();
365 : 152 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
366 : 76 : mappings.get_next_hir_id (crate_num),
367 : 76 : UNKNOWN_LOCAL_DEFID);
368 : :
369 : 76 : translated
370 : 76 : = new HIR::SlicePattern (mapping, std::move (items), pattern.get_locus ());
371 : 76 : }
372 : :
373 : : void
374 : 147 : ASTLoweringPattern::visit (AST::AltPattern &pattern)
375 : : {
376 : 147 : auto crate_num = mappings.get_current_crate ();
377 : 294 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
378 : 147 : mappings.get_next_hir_id (crate_num),
379 : 147 : UNKNOWN_LOCAL_DEFID);
380 : :
381 : 147 : std::vector<std::unique_ptr<HIR::Pattern>> alts;
382 : 147 : alts.reserve (pattern.get_alts ().size ());
383 : :
384 : 442 : for (auto &alt : pattern.get_alts ())
385 : 295 : alts.emplace_back (ASTLoweringPattern::translate (*alt));
386 : :
387 : 147 : translated
388 : 147 : = new HIR::AltPattern (mapping, std::move (alts), pattern.get_locus ());
389 : :
390 : 147 : if (is_let_top_level)
391 : : {
392 : 1 : rich_location richloc (line_table, pattern.get_locus ());
393 : 1 : richloc.add_fixit_replace ("use an outer grouped pattern");
394 : 1 : rust_error_at (
395 : : richloc, "top level or-patterns are not allowed for %<let%> bindings");
396 : 1 : }
397 : 147 : }
398 : :
399 : : } // namespace HIR
400 : : } // namespace Rust
|