Line data Source code
1 : // Copyright (C) 2020-2026 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 25944 : ASTLoweringPattern::ASTLoweringPattern ()
27 25944 : : translated (nullptr), is_let_top_level (false)
28 25944 : {}
29 :
30 : HIR::Pattern *
31 25944 : ASTLoweringPattern::translate (AST::Pattern &pattern, bool is_let_top_level)
32 : {
33 25944 : ASTLoweringPattern resolver;
34 25944 : resolver.is_let_top_level = is_let_top_level;
35 25944 : pattern.accept_vis (resolver);
36 :
37 25944 : rust_assert (resolver.translated != nullptr);
38 :
39 25944 : resolver.mappings.insert_hir_pattern (resolver.translated);
40 25944 : resolver.mappings.insert_location (
41 25944 : resolver.translated->get_mappings ().get_hirid (), pattern.get_locus ());
42 :
43 25944 : return resolver.translated;
44 25944 : }
45 :
46 : void
47 21317 : ASTLoweringPattern::visit (AST::IdentifierPattern &pattern)
48 : {
49 21317 : auto crate_num = mappings.get_current_crate ();
50 42634 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
51 21317 : mappings.get_next_hir_id (crate_num),
52 21317 : UNKNOWN_LOCAL_DEFID);
53 :
54 21317 : std::unique_ptr<Pattern> subpattern;
55 21317 : if (pattern.has_subpattern ())
56 : {
57 18 : subpattern = std::unique_ptr<Pattern> (
58 18 : ASTLoweringPattern::translate (pattern.get_subpattern ()));
59 : }
60 21317 : translated
61 21317 : = new HIR::IdentifierPattern (mapping, pattern.get_ident (),
62 21317 : pattern.get_locus (), pattern.get_is_ref (),
63 21317 : pattern.get_is_mut () ? Mutability::Mut
64 : : Mutability::Imm,
65 63023 : std::move (subpattern));
66 21317 : }
67 :
68 : void
69 1086 : ASTLoweringPattern::visit (AST::PathInExpression &pattern)
70 : {
71 1086 : translated = ASTLowerPathInExpression::translate (pattern);
72 1086 : }
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 165 : ASTLoweringPattern::visit (AST::StructPattern &pattern)
138 : {
139 165 : HIR::PathInExpression *path
140 165 : = ASTLowerPathInExpression::translate (pattern.get_path ());
141 :
142 165 : auto &raw_elems = pattern.get_struct_pattern_elems ();
143 :
144 165 : std::vector<std::unique_ptr<HIR::StructPatternField>> fields;
145 440 : for (auto &field : raw_elems.get_struct_pattern_fields ())
146 : {
147 275 : HIR::StructPatternField *f = nullptr;
148 275 : switch (field->get_item_type ())
149 : {
150 24 : case AST::StructPatternField::ItemType::TUPLE_PAT:
151 24 : {
152 24 : auto &tuple
153 24 : = static_cast<AST::StructPatternFieldTuplePat &> (*field);
154 :
155 24 : auto crate_num = mappings.get_current_crate ();
156 24 : Analysis::NodeMapping mapping (crate_num, tuple.get_node_id (),
157 24 : mappings.get_next_hir_id (crate_num),
158 24 : UNKNOWN_LOCAL_DEFID);
159 :
160 24 : std::unique_ptr<HIR::Pattern> pat (
161 24 : ASTLoweringPattern::translate (tuple.get_index_pattern ()));
162 :
163 48 : f = new HIR::StructPatternFieldTuplePat (mapping,
164 : tuple.get_index (),
165 : std::move (pat),
166 24 : tuple.get_outer_attrs (),
167 24 : tuple.get_locus ());
168 24 : }
169 24 : break;
170 :
171 151 : case AST::StructPatternField::ItemType::IDENT_PAT:
172 151 : {
173 151 : AST::StructPatternFieldIdentPat &ident
174 151 : = static_cast<AST::StructPatternFieldIdentPat &> (*field);
175 :
176 151 : auto crate_num = mappings.get_current_crate ();
177 151 : Analysis::NodeMapping mapping (crate_num, ident.get_node_id (),
178 151 : mappings.get_next_hir_id (crate_num),
179 151 : UNKNOWN_LOCAL_DEFID);
180 :
181 151 : std::unique_ptr<HIR::Pattern> pat (
182 151 : ASTLoweringPattern::translate (ident.get_ident_pattern ()));
183 :
184 151 : f = new HIR::StructPatternFieldIdentPat (mapping,
185 : ident.get_identifier (),
186 : std::move (pat),
187 151 : ident.get_outer_attrs (),
188 302 : ident.get_locus ());
189 151 : }
190 151 : break;
191 :
192 100 : case AST::StructPatternField::ItemType::IDENT:
193 100 : {
194 100 : AST::StructPatternFieldIdent &ident
195 100 : = static_cast<AST::StructPatternFieldIdent &> (*field.get ());
196 :
197 100 : auto crate_num = mappings.get_current_crate ();
198 100 : Analysis::NodeMapping mapping (crate_num, ident.get_node_id (),
199 100 : mappings.get_next_hir_id (crate_num),
200 100 : UNKNOWN_LOCAL_DEFID);
201 :
202 100 : f = new HIR::StructPatternFieldIdent (
203 100 : mapping, ident.get_identifier (), ident.is_ref (),
204 100 : ident.is_mut () ? Mutability::Mut : Mutability::Imm,
205 298 : ident.get_outer_attrs (), ident.get_locus ());
206 : }
207 100 : break;
208 : }
209 :
210 : // insert the reverse mappings and locations
211 275 : auto field_id = f->get_mappings ().get_hirid ();
212 275 : auto field_node_id = f->get_mappings ().get_nodeid ();
213 275 : mappings.insert_location (field_id, f->get_locus ());
214 275 : mappings.insert_node_to_hir (field_node_id, field_id);
215 :
216 : // add it to the lowered fields list
217 275 : fields.emplace_back (f);
218 : }
219 :
220 165 : auto crate_num = mappings.get_current_crate ();
221 330 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
222 165 : mappings.get_next_hir_id (crate_num),
223 165 : UNKNOWN_LOCAL_DEFID);
224 :
225 165 : HIR::StructPatternElements elems (
226 165 : std::move (fields), pattern.get_struct_pattern_elems ().has_rest ());
227 165 : translated = new HIR::StructPattern (mapping, *path, std::move (elems));
228 165 : }
229 :
230 : void
231 1056 : ASTLoweringPattern::visit (AST::WildcardPattern &pattern)
232 : {
233 1056 : auto crate_num = mappings.get_current_crate ();
234 2112 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
235 1056 : mappings.get_next_hir_id (crate_num),
236 1056 : UNKNOWN_LOCAL_DEFID);
237 :
238 1056 : translated = new HIR::WildcardPattern (mapping, pattern.get_locus ());
239 1056 : }
240 :
241 : void
242 424 : ASTLoweringPattern::visit (AST::TuplePattern &pattern)
243 : {
244 424 : std::unique_ptr<HIR::TuplePatternItems> items;
245 424 : switch (pattern.get_items ().get_item_type ())
246 : {
247 397 : case AST::TuplePatternItems::ItemType::NO_REST:
248 397 : {
249 397 : AST::TuplePatternItemsNoRest &ref
250 397 : = static_cast<AST::TuplePatternItemsNoRest &> (pattern.get_items ());
251 397 : items = lower_tuple_pattern_multiple (ref);
252 : }
253 397 : 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 424 : auto crate_num = mappings.get_current_crate ();
265 848 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
266 424 : mappings.get_next_hir_id (crate_num),
267 424 : UNKNOWN_LOCAL_DEFID);
268 :
269 424 : translated
270 424 : = new HIR::TuplePattern (mapping, std::move (items), pattern.get_locus ());
271 424 : }
272 :
273 : void
274 436 : ASTLoweringPattern::visit (AST::LiteralPattern &pattern)
275 : {
276 436 : auto crate_num = mappings.get_current_crate ();
277 872 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
278 436 : mappings.get_next_hir_id (crate_num),
279 436 : UNKNOWN_LOCAL_DEFID);
280 :
281 436 : HIR::Literal l = lower_literal (pattern.get_literal ());
282 436 : translated
283 436 : = new HIR::LiteralPattern (mapping, std::move (l), pattern.get_locus (),
284 872 : pattern.get_has_minus ());
285 436 : }
286 :
287 : void
288 40 : ASTLoweringPattern::visit (AST::RangePattern &pattern)
289 : {
290 40 : auto upper_bound = lower_range_pattern_bound (pattern.get_upper_bound ());
291 40 : auto lower_bound = lower_range_pattern_bound (pattern.get_lower_bound ());
292 :
293 40 : auto crate_num = mappings.get_current_crate ();
294 80 : Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (),
295 40 : mappings.get_next_hir_id (crate_num),
296 40 : UNKNOWN_LOCAL_DEFID);
297 :
298 40 : bool is_inclusive = (pattern.get_range_kind () == AST::RangeKind::INCLUDED);
299 :
300 40 : translated = new HIR::RangePattern (mapping, std::move (lower_bound),
301 : std::move (upper_bound),
302 40 : pattern.get_locus (), is_inclusive);
303 40 : }
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
|