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