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