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 : : #ifndef RUST_AST_RESOLVE_STMT_H
20 : : #define RUST_AST_RESOLVE_STMT_H
21 : :
22 : : #include "rust-ast-resolve-base.h"
23 : : #include "rust-ast-resolve-type.h"
24 : : #include "rust-ast-resolve-pattern.h"
25 : : #include "rust-ast-resolve-expr.h"
26 : : #include "rust-item.h"
27 : :
28 : : namespace Rust {
29 : : namespace Resolver {
30 : :
31 : 21253 : class ResolveStmt : public ResolverBase
32 : : {
33 : : using Rust::Resolver::ResolverBase::visit;
34 : :
35 : : public:
36 : 21254 : static void go (AST::Stmt &stmt, const CanonicalPath &prefix,
37 : : const CanonicalPath &canonical_prefix,
38 : : const CanonicalPath &enum_prefix)
39 : : {
40 : 21254 : if (stmt.is_marked_for_strip ())
41 : 0 : return;
42 : :
43 : 42508 : ResolveStmt resolver (prefix, canonical_prefix, enum_prefix);
44 : 21253 : stmt.accept_vis (resolver);
45 : 21253 : }
46 : :
47 : 7909 : void visit (AST::ExprStmt &stmt) override
48 : : {
49 : 7909 : ResolveExpr::go (stmt.get_expr (), prefix, canonical_prefix);
50 : 7908 : }
51 : :
52 : 59 : void visit (AST::ConstantItem &constant) override
53 : : {
54 : 59 : auto decl = CanonicalPath::new_seg (constant.get_node_id (),
55 : 59 : constant.get_identifier ());
56 : 59 : auto path = decl; // this ensures we have the correct relative resolution
57 : 59 : auto cpath = canonical_prefix.append (decl);
58 : 59 : mappings.insert_canonical_path (constant.get_node_id (), cpath);
59 : :
60 : 59 : resolver->get_name_scope ().insert (
61 : : path, constant.get_node_id (), constant.get_locus (), false,
62 : : Rib::ItemType::Const,
63 : 59 : [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
64 : 0 : rich_location r (line_table, constant.get_locus ());
65 : 0 : r.add_range (locus);
66 : 0 : redefined_error (r);
67 : 0 : });
68 : :
69 : 59 : ResolveType::go (constant.get_type ());
70 : 59 : ResolveExpr::go (constant.get_expr (), prefix, canonical_prefix);
71 : 59 : }
72 : :
73 : 12838 : void visit (AST::LetStmt &stmt) override
74 : : {
75 : 12838 : if (stmt.has_init_expr ())
76 : 11563 : ResolveExpr::go (stmt.get_init_expr (), prefix, canonical_prefix);
77 : :
78 : 12838 : if (stmt.has_else_expr ())
79 : 0 : ResolveExpr::go (stmt.get_else_expr (), prefix, canonical_prefix);
80 : :
81 : 12838 : PatternDeclaration::go (stmt.get_pattern (), Rib::ItemType::Var);
82 : 12838 : if (stmt.has_type ())
83 : 2162 : ResolveType::go (stmt.get_type ());
84 : 12838 : }
85 : :
86 : 112 : void visit (AST::TupleStruct &struct_decl) override
87 : : {
88 : 112 : auto decl
89 : : = CanonicalPath::new_seg (struct_decl.get_node_id (),
90 : 112 : struct_decl.get_identifier ().as_string ());
91 : 112 : auto path = decl; // this ensures we have the correct relative resolution
92 : 112 : auto cpath = canonical_prefix.append (decl);
93 : 112 : mappings.insert_canonical_path (struct_decl.get_node_id (), cpath);
94 : :
95 : 112 : resolver->get_type_scope ().insert (
96 : : path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
97 : : Rib::ItemType::Type,
98 : 112 : [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
99 : 0 : rich_location r (line_table, struct_decl.get_locus ());
100 : 0 : r.add_range (locus);
101 : 0 : redefined_error (r);
102 : 0 : });
103 : :
104 : 112 : NodeId scope_node_id = struct_decl.get_node_id ();
105 : 112 : resolver->get_type_scope ().push (scope_node_id);
106 : :
107 : 112 : if (struct_decl.has_generics ())
108 : 0 : ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
109 : : canonical_prefix);
110 : :
111 : 536 : for (AST::TupleField &field : struct_decl.get_fields ())
112 : 424 : ResolveType::go (field.get_field_type ());
113 : :
114 : 112 : resolver->get_type_scope ().pop ();
115 : 112 : }
116 : :
117 : 12 : void visit (AST::Enum &enum_decl) override
118 : : {
119 : 12 : auto decl
120 : : = CanonicalPath::new_seg (enum_decl.get_node_id (),
121 : 12 : enum_decl.get_identifier ().as_string ());
122 : 12 : auto path = decl; // this ensures we have the correct relative resolution
123 : 12 : auto cpath = canonical_prefix.append (decl);
124 : 12 : mappings.insert_canonical_path (enum_decl.get_node_id (), cpath);
125 : :
126 : 12 : resolver->get_type_scope ().insert (
127 : : path, enum_decl.get_node_id (), enum_decl.get_locus (), false,
128 : : Rib::ItemType::Type,
129 : 12 : [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
130 : 1 : rich_location r (line_table, enum_decl.get_locus ());
131 : 1 : r.add_range (locus);
132 : 1 : redefined_error (r);
133 : 1 : });
134 : :
135 : 12 : NodeId scope_node_id = enum_decl.get_node_id ();
136 : 12 : resolver->get_type_scope ().push (scope_node_id);
137 : :
138 : 12 : if (enum_decl.has_generics ())
139 : 0 : ResolveGenericParams::go (enum_decl.get_generic_params (), prefix,
140 : : canonical_prefix);
141 : :
142 : 40 : for (auto &variant : enum_decl.get_variants ())
143 : 28 : ResolveStmt::go (*variant, path, canonical_prefix, path);
144 : :
145 : 12 : resolver->get_type_scope ().pop ();
146 : 12 : }
147 : :
148 : 12 : void visit (AST::EnumItem &item) override
149 : : {
150 : 12 : auto decl = enum_prefix.append (
151 : 24 : CanonicalPath::new_seg (item.get_node_id (),
152 : 12 : item.get_identifier ().as_string ()));
153 : 12 : auto path = decl; // this ensures we have the correct relative resolution
154 : 12 : auto cpath = canonical_prefix.append (decl);
155 : 12 : mappings.insert_canonical_path (item.get_node_id (), cpath);
156 : :
157 : 12 : resolver->get_type_scope ().insert (
158 : 12 : path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
159 : 12 : [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
160 : 0 : rich_location r (line_table, item.get_locus ());
161 : 0 : r.add_range (locus);
162 : 0 : redefined_error (r);
163 : 0 : });
164 : :
165 : : // Done, no fields.
166 : 12 : }
167 : :
168 : 6 : void visit (AST::EnumItemTuple &item) override
169 : : {
170 : 6 : auto decl = enum_prefix.append (
171 : 12 : CanonicalPath::new_seg (item.get_node_id (),
172 : 6 : item.get_identifier ().as_string ()));
173 : 6 : auto path = decl; // this ensures we have the correct relative resolution
174 : 6 : auto cpath = canonical_prefix.append (decl);
175 : 6 : mappings.insert_canonical_path (item.get_node_id (), cpath);
176 : :
177 : 6 : resolver->get_type_scope ().insert (
178 : 6 : path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
179 : 6 : [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
180 : 0 : rich_location r (line_table, item.get_locus ());
181 : 0 : r.add_range (locus);
182 : 0 : redefined_error (r);
183 : 0 : });
184 : :
185 : 14 : for (auto &field : item.get_tuple_fields ())
186 : : {
187 : 8 : if (field.get_field_type ().is_marked_for_strip ())
188 : 0 : continue;
189 : :
190 : 8 : ResolveType::go (field.get_field_type ());
191 : : }
192 : 6 : }
193 : :
194 : 5 : void visit (AST::EnumItemStruct &item) override
195 : : {
196 : 5 : auto decl = enum_prefix.append (
197 : 10 : CanonicalPath::new_seg (item.get_node_id (),
198 : 5 : item.get_identifier ().as_string ()));
199 : 5 : auto path = decl; // this ensures we have the correct relative resolution
200 : 5 : auto cpath = canonical_prefix.append (decl);
201 : 5 : mappings.insert_canonical_path (item.get_node_id (), cpath);
202 : :
203 : 5 : resolver->get_type_scope ().insert (
204 : 5 : path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
205 : 5 : [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
206 : 1 : rich_location r (line_table, item.get_locus ());
207 : 1 : r.add_range (locus);
208 : 1 : redefined_error (r);
209 : 1 : });
210 : :
211 : 11 : for (auto &field : item.get_struct_fields ())
212 : : {
213 : 6 : if (field.get_field_type ().is_marked_for_strip ())
214 : 0 : continue;
215 : :
216 : 6 : ResolveType::go (field.get_field_type ());
217 : : }
218 : 5 : }
219 : :
220 : 5 : void visit (AST::EnumItemDiscriminant &item) override
221 : : {
222 : 5 : auto decl = enum_prefix.append (
223 : 10 : CanonicalPath::new_seg (item.get_node_id (),
224 : 5 : item.get_identifier ().as_string ()));
225 : 5 : auto path = decl; // this ensures we have the correct relative resolution
226 : 5 : auto cpath = canonical_prefix.append (decl);
227 : 5 : mappings.insert_canonical_path (item.get_node_id (), cpath);
228 : :
229 : 5 : resolver->get_type_scope ().insert (
230 : 5 : path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type,
231 : 5 : [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
232 : 1 : rich_location r (line_table, item.get_locus ());
233 : 1 : r.add_range (locus);
234 : 1 : redefined_error (r);
235 : 1 : });
236 : :
237 : : // Done, no fields.
238 : 5 : }
239 : :
240 : 125 : void visit (AST::StructStruct &struct_decl) override
241 : : {
242 : 125 : auto decl
243 : : = CanonicalPath::new_seg (struct_decl.get_node_id (),
244 : 125 : struct_decl.get_identifier ().as_string ());
245 : 125 : auto path = decl; // this ensures we have the correct relative resolution
246 : 125 : auto cpath = canonical_prefix.append (decl);
247 : 125 : mappings.insert_canonical_path (struct_decl.get_node_id (), cpath);
248 : :
249 : 125 : resolver->get_type_scope ().insert (
250 : : path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
251 : : Rib::ItemType::Type,
252 : 125 : [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
253 : 0 : rich_location r (line_table, struct_decl.get_locus ());
254 : 0 : r.add_range (locus);
255 : 0 : redefined_error (r);
256 : 0 : });
257 : :
258 : 125 : NodeId scope_node_id = struct_decl.get_node_id ();
259 : 125 : resolver->get_type_scope ().push (scope_node_id);
260 : :
261 : 125 : if (struct_decl.has_generics ())
262 : 3 : ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
263 : : canonical_prefix);
264 : :
265 : 172 : for (AST::StructField &field : struct_decl.get_fields ())
266 : : {
267 : 47 : if (field.get_field_type ().is_marked_for_strip ())
268 : 0 : continue;
269 : :
270 : 47 : ResolveType::go (field.get_field_type ());
271 : : }
272 : :
273 : 125 : resolver->get_type_scope ().pop ();
274 : 125 : }
275 : :
276 : 1 : void visit (AST::Union &union_decl) override
277 : : {
278 : 1 : auto decl
279 : : = CanonicalPath::new_seg (union_decl.get_node_id (),
280 : 1 : union_decl.get_identifier ().as_string ());
281 : 1 : auto path = decl; // this ensures we have the correct relative resolution
282 : 1 : auto cpath = canonical_prefix.append (decl);
283 : 1 : mappings.insert_canonical_path (union_decl.get_node_id (), cpath);
284 : :
285 : 1 : resolver->get_type_scope ().insert (
286 : : path, union_decl.get_node_id (), union_decl.get_locus (), false,
287 : : Rib::ItemType::Type,
288 : 1 : [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
289 : 0 : rich_location r (line_table, union_decl.get_locus ());
290 : 0 : r.add_range (locus);
291 : 0 : redefined_error (r);
292 : 0 : });
293 : :
294 : 1 : NodeId scope_node_id = union_decl.get_node_id ();
295 : 1 : resolver->get_type_scope ().push (scope_node_id);
296 : :
297 : 1 : if (union_decl.has_generics ())
298 : 0 : ResolveGenericParams::go (union_decl.get_generic_params (), prefix,
299 : : canonical_prefix);
300 : :
301 : 5 : for (AST::StructField &field : union_decl.get_variants ())
302 : : {
303 : 4 : if (field.get_field_type ().is_marked_for_strip ())
304 : 0 : continue;
305 : :
306 : 4 : ResolveType::go (field.get_field_type ());
307 : : }
308 : :
309 : 1 : resolver->get_type_scope ().pop ();
310 : 1 : }
311 : :
312 : 57 : void visit (AST::Function &function) override
313 : : {
314 : 57 : auto decl
315 : 57 : = CanonicalPath::new_seg (function.get_node_id (),
316 : 57 : function.get_function_name ().as_string ());
317 : 57 : auto path = decl; // this ensures we have the correct relative resolution
318 : 57 : auto cpath = canonical_prefix.append (decl);
319 : 57 : mappings.insert_canonical_path (function.get_node_id (), cpath);
320 : :
321 : 57 : resolver->get_name_scope ().insert (
322 : 57 : path, function.get_node_id (), function.get_locus (), false,
323 : : Rib::ItemType::Function,
324 : 57 : [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
325 : 0 : rich_location r (line_table, function.get_locus ());
326 : 0 : r.add_range (locus);
327 : 0 : redefined_error (r);
328 : 0 : });
329 : :
330 : 57 : NodeId scope_node_id = function.get_node_id ();
331 : 57 : resolver->get_name_scope ().push (scope_node_id);
332 : 57 : resolver->get_type_scope ().push (scope_node_id);
333 : 57 : resolver->get_label_scope ().push (scope_node_id);
334 : 57 : resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
335 : 57 : resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
336 : 57 : resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
337 : :
338 : 57 : if (function.has_generics ())
339 : 15 : ResolveGenericParams::go (function.get_generic_params (), prefix,
340 : : canonical_prefix);
341 : :
342 : 57 : if (function.has_return_type ())
343 : 32 : ResolveType::go (function.get_return_type ());
344 : :
345 : 57 : std::vector<PatternBinding> bindings
346 : 114 : = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
347 : :
348 : : // we make a new scope so the names of parameters are resolved and shadowed
349 : : // correctly
350 : 91 : for (auto &p : function.get_function_params ())
351 : : {
352 : 34 : if (p->is_variadic ())
353 : : {
354 : 0 : auto ¶m = static_cast<AST::VariadicParam &> (*p);
355 : 0 : PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
356 : : bindings);
357 : : }
358 : :
359 : 34 : else if (p->is_self ())
360 : : {
361 : 0 : auto ¶m = static_cast<AST::SelfParam &> (*p);
362 : 0 : ResolveType::go (param.get_type ());
363 : : }
364 : : else
365 : : {
366 : 34 : auto ¶m = static_cast<AST::FunctionParam &> (*p);
367 : :
368 : 34 : ResolveType::go (param.get_type ());
369 : 34 : PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
370 : : bindings);
371 : : }
372 : : }
373 : :
374 : : // resolve the function body
375 : 57 : ResolveExpr::go (*function.get_definition ().value (), path, cpath);
376 : :
377 : 57 : resolver->get_name_scope ().pop ();
378 : 57 : resolver->get_type_scope ().pop ();
379 : 57 : resolver->get_label_scope ().pop ();
380 : 57 : }
381 : :
382 : : void visit (AST::ExternBlock &extern_block) override;
383 : : void visit (AST::Trait &trait) override;
384 : : void visit (AST::InherentImpl &impl_block) override;
385 : : void visit (AST::TraitImpl &impl_block) override;
386 : : void visit (AST::StaticItem &var) override;
387 : :
388 : : private:
389 : 21254 : ResolveStmt (const CanonicalPath &prefix,
390 : : const CanonicalPath &canonical_prefix,
391 : : const CanonicalPath &enum_prefix)
392 : 42508 : : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix),
393 : 21254 : enum_prefix (enum_prefix)
394 : : {}
395 : :
396 : : const CanonicalPath &prefix;
397 : : const CanonicalPath &canonical_prefix;
398 : :
399 : : /* item declaration statements are not given a canonical path, but enum items
400 : : * (variants) do inherit the enum path/identifier name. */
401 : : const CanonicalPath &enum_prefix;
402 : : };
403 : :
404 : : } // namespace Resolver
405 : : } // namespace Rust
406 : :
407 : : #endif // RUST_AST_RESOLVE_STMT_H
|