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