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-default-resolver.h"
20 : #include "optional.h"
21 : #include "rust-ast-full.h"
22 : #include "rust-ast-visitor.h"
23 : #include "rust-ast.h"
24 : #include "rust-attribute-values.h"
25 : #include "rust-item.h"
26 : #include "rust-path.h"
27 :
28 : namespace Rust {
29 : namespace Resolver2_0 {
30 :
31 : void
32 32012 : DefaultResolver::visit (AST::Crate &crate)
33 : {
34 : // Guard against infinite recursion: `extern crate self;` resolves to the
35 : // current crate, causing visit(AST::Crate) to call itself infinitely.
36 32012 : if (!visited_crates.insert (crate.get_node_id ()).second)
37 0 : return;
38 :
39 64024 : auto inner_fn = [this, &crate] () {
40 32012 : maybe_prelude_import ();
41 32012 : AST::DefaultASTVisitor::visit (crate);
42 64022 : };
43 :
44 32012 : auto &mappings = Analysis::Mappings::get ();
45 :
46 32012 : auto crate_num = mappings.lookup_crate_num (crate.get_node_id ());
47 32012 : rust_assert (crate_num.has_value ());
48 32012 : auto crate_name = mappings.get_crate_name (*crate_num);
49 32012 : rust_assert (crate_name.has_value ());
50 :
51 64024 : ctx.canonical_ctx.scope_crate (crate.get_node_id (), *crate_name, inner_fn);
52 : }
53 :
54 : void
55 1304573 : DefaultResolver::visit (AST::BlockExpr &expr)
56 : {
57 : // extracting the lambda from the `scoped` call otherwise the code looks like
58 : // a hot turd thanks to our .clang-format
59 :
60 1304573 : auto inner_fn = [this, &expr] () { AST::DefaultASTVisitor::visit (expr); };
61 :
62 1304573 : ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), inner_fn);
63 1304568 : }
64 :
65 : void
66 25952 : DefaultResolver::visit (AST::Module &module)
67 : {
68 51904 : auto item_fn_1 = [this, &module] () {
69 25952 : maybe_prelude_import ();
70 25952 : AST::DefaultASTVisitor::visit (module);
71 51904 : };
72 :
73 51904 : auto item_fn_2 = [this, &module, &item_fn_1] () {
74 25952 : ctx.canonical_ctx.scope (module.get_node_id (), module.get_name (),
75 : std::move (item_fn_1));
76 51904 : };
77 :
78 51904 : ctx.scoped (Rib::Kind::Module, module.get_node_id (), item_fn_2,
79 51904 : module.get_name ());
80 25952 : }
81 :
82 : void
83 980431 : DefaultResolver::visit (AST::Function &function)
84 : {
85 980431 : auto def_fn_1
86 980431 : = [this, &function] () { AST::DefaultASTVisitor::visit (function); };
87 :
88 1960862 : auto def_fn_2 = [this, &function, &def_fn_1] () {
89 980431 : ctx.canonical_ctx.scope (function.get_node_id (),
90 980431 : function.get_function_name (),
91 : std::move (def_fn_1));
92 1960860 : };
93 :
94 1960862 : ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn_2,
95 1960860 : function.get_function_name ());
96 980429 : }
97 :
98 : void
99 3741 : DefaultResolver::visit (AST::LoopExpr &expr)
100 : {
101 3741 : ctx.scoped (Rib::Kind::Normal, expr.get_node_id (),
102 11222 : [this, &expr] () { AST::DefaultASTVisitor::visit (expr); });
103 3740 : }
104 :
105 : void
106 7760 : DefaultResolver::visit (AST::WhileLoopExpr &expr)
107 : {
108 7760 : ctx.scoped (Rib::Kind::Normal, expr.get_node_id (),
109 23280 : [this, &expr] () { AST::DefaultASTVisitor::visit (expr); });
110 7760 : }
111 :
112 : void
113 1594 : DefaultResolver::visit (AST::WhileLetLoopExpr &expr)
114 : {
115 1594 : ctx.scoped (Rib::Kind::Normal, expr.get_node_id (),
116 4782 : [this, &expr] () { AST::DefaultASTVisitor::visit (expr); });
117 1594 : }
118 : void
119 7208 : DefaultResolver::visit (AST::ForLoopExpr &expr)
120 : {
121 7208 : ctx.scoped (Rib::Kind::Normal, expr.get_node_id (),
122 21624 : [this, &expr] () { AST::DefaultASTVisitor::visit (expr); });
123 7208 : }
124 :
125 : void
126 6728 : DefaultResolver::visit_if_let_patterns (AST::IfLetExpr &expr)
127 : {
128 6728 : visit (expr.get_pattern ());
129 6728 : }
130 :
131 : void
132 6728 : DefaultResolver::visit (AST::IfLetExpr &expr)
133 : {
134 13456 : auto inner_vis = [this, &expr] () {
135 6728 : visit_if_let_patterns (expr);
136 6728 : visit (expr.get_if_block ());
137 13456 : };
138 :
139 6728 : visit_outer_attrs (expr);
140 :
141 6728 : visit (expr.get_value_expr ());
142 :
143 6728 : ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), inner_vis);
144 6728 : }
145 :
146 : void
147 2232 : DefaultResolver::visit (AST::IfLetExprConseqElse &expr)
148 : {
149 2232 : DefaultResolver::visit (static_cast<AST::IfLetExpr &> (expr));
150 2232 : visit (expr.get_else_block ());
151 2232 : }
152 :
153 : void
154 35991 : DefaultResolver::visit (AST::Trait &trait)
155 : {
156 35991 : visit_outer_attrs (trait);
157 35991 : visit (trait.get_visibility ());
158 35991 : visit_inner_attrs (trait);
159 :
160 71982 : auto inner_fn_1 = [this, &trait] () {
161 86757 : for (auto &item : trait.get_trait_items ())
162 50766 : visit (item);
163 71982 : };
164 :
165 71982 : auto inner_fn_2 = [this, &trait, &inner_fn_1] () {
166 35991 : visit (trait.get_implicit_self ());
167 44843 : for (auto &generic : trait.get_generic_params ())
168 8852 : visit (generic);
169 35991 : if (trait.has_where_clause ())
170 56 : visit (trait.get_where_clause ());
171 45705 : for (auto &bound : trait.get_type_param_bounds ())
172 9714 : visit (bound);
173 :
174 35991 : ctx.scoped (Rib::Kind::TraitOrImpl, trait.get_node_id (), inner_fn_1);
175 71982 : };
176 :
177 71982 : auto inner_fn_3 = [this, &trait, &inner_fn_2] () {
178 35991 : ctx.canonical_ctx.scope (trait.get_node_id (), trait.get_identifier (),
179 : std::move (inner_fn_2));
180 71982 : };
181 :
182 71982 : ctx.scoped (Rib::Kind::Generics, trait.get_node_id (), inner_fn_3,
183 71982 : trait.get_identifier () /* FIXME: Is that valid?*/);
184 35991 : }
185 :
186 : static bool
187 27298 : is_lang_impl (std::vector<AST::Attribute> &outer_attrs)
188 : {
189 30963 : for (auto &attr : outer_attrs)
190 6761 : if (attr.get_path ().as_string () == Values::Attributes::LANG)
191 27298 : return true;
192 :
193 : return false;
194 : }
195 :
196 : void
197 27298 : DefaultResolver::visit (AST::InherentImpl &impl)
198 : {
199 27298 : visit_outer_attrs (impl);
200 27298 : visit (impl.get_visibility ());
201 27298 : visit_inner_attrs (impl);
202 :
203 54596 : auto inner_fn_1 = [this, &impl] () {
204 201348 : for (auto &item : impl.get_impl_items ())
205 174050 : visit (item);
206 54596 : };
207 :
208 54596 : auto inner_fn_2 = [this, &impl, &inner_fn_1] () {
209 27298 : maybe_insert_big_self (impl);
210 48465 : for (auto &generic : impl.get_generic_params ())
211 21167 : visit (generic);
212 27298 : if (impl.has_where_clause ())
213 221 : visit (impl.get_where_clause ());
214 27298 : visit_impl_type (impl.get_type ());
215 :
216 27298 : ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_1);
217 54596 : };
218 :
219 54596 : auto inner_fn_3 = [this, &impl, &inner_fn_2] () {
220 27298 : ctx.canonical_ctx.scope_impl (impl, std::move (inner_fn_2));
221 54596 : };
222 :
223 27298 : ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_3);
224 :
225 27298 : if (is_lang_impl (impl.get_outer_attrs ()))
226 : {
227 3096 : if (impl.get_type ().get_type_kind () == AST::Type::Kind::TypePath)
228 : {
229 1482 : auto type = static_cast<AST::TypePath &> (impl.get_type ());
230 1482 : auto type_name = type.as_string ();
231 :
232 4446 : ctx.types.insert_lang_prelude (type_name, impl.get_node_id ());
233 1482 : }
234 : }
235 27298 : }
236 :
237 : void
238 490291 : DefaultResolver::visit (AST::TraitImpl &impl)
239 : {
240 490291 : visit_outer_attrs (impl);
241 490291 : visit (impl.get_visibility ());
242 490291 : visit_inner_attrs (impl);
243 :
244 980582 : auto inner_fn_1 = [this, &impl] () {
245 1184528 : for (auto &item : impl.get_impl_items ())
246 694237 : visit (item);
247 980582 : };
248 :
249 980582 : auto inner_fn_2 = [this, &impl, &inner_fn_1] () {
250 490291 : maybe_insert_big_self (impl);
251 950719 : for (auto &generic : impl.get_generic_params ())
252 460428 : visit (generic);
253 490291 : if (impl.has_where_clause ())
254 25732 : visit (impl.get_where_clause ());
255 490291 : visit_impl_type (impl.get_type ());
256 490291 : visit (impl.get_trait_path ());
257 :
258 490291 : ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_1);
259 980582 : };
260 :
261 980582 : auto inner_fn_3 = [this, &impl, &inner_fn_2] () {
262 490291 : ctx.canonical_ctx.scope_impl (impl, std::move (inner_fn_2));
263 980582 : };
264 :
265 490291 : ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_3);
266 490291 : }
267 :
268 : void
269 51924 : DefaultResolver::visit (AST::StructStruct &type)
270 : {
271 51924 : auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
272 :
273 103848 : auto inner_fn_2 = [this, &type, &inner_fn_1] () {
274 51924 : ctx.canonical_ctx.scope (type.get_node_id (), type.get_struct_name (),
275 : std::move (inner_fn_1));
276 103848 : };
277 :
278 51924 : ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
279 155772 : inner_fn_2, type.get_struct_name ());
280 51924 : }
281 :
282 : void
283 13343 : DefaultResolver::visit (AST::TupleStruct &type)
284 : {
285 13343 : auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
286 :
287 26686 : auto inner_fn_2 = [this, &type, &inner_fn_1] () {
288 13343 : ctx.canonical_ctx.scope (type.get_node_id (), type.get_struct_name (),
289 : std::move (inner_fn_1));
290 26686 : };
291 :
292 13343 : ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
293 40029 : inner_fn_2, type.get_struct_name ());
294 13343 : }
295 :
296 : void
297 7374 : DefaultResolver::visit (AST::EnumItem &item)
298 : {
299 7374 : auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
300 :
301 7374 : ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
302 : inner_fn);
303 7374 : }
304 :
305 : void
306 5091 : DefaultResolver::visit (AST::EnumItemTuple &item)
307 : {
308 5091 : auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
309 :
310 5091 : ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
311 : inner_fn);
312 5091 : }
313 :
314 : void
315 610 : DefaultResolver::visit (AST::EnumItemStruct &item)
316 : {
317 610 : auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
318 :
319 610 : ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
320 : inner_fn);
321 610 : }
322 :
323 : void
324 2163 : DefaultResolver::visit (AST::EnumItemDiscriminant &item)
325 : {
326 2163 : auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
327 :
328 2163 : ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
329 : inner_fn);
330 2163 : }
331 :
332 : void
333 5983 : DefaultResolver::visit (AST::Enum &type)
334 : {
335 5983 : auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
336 :
337 11966 : auto inner_fn_2 = [this, &type, &inner_fn_1] () {
338 5983 : ctx.canonical_ctx.scope (type.get_node_id (), type.get_identifier (),
339 : std::move (inner_fn_1));
340 11966 : };
341 :
342 11966 : ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
343 17949 : inner_fn_2, type.get_identifier ());
344 5983 : }
345 :
346 : void
347 825 : DefaultResolver::visit (AST::Union &type)
348 : {
349 825 : auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
350 :
351 1650 : auto inner_fn_2 = [this, &type, &inner_fn_1] () {
352 825 : ctx.canonical_ctx.scope (type.get_node_id (), type.get_identifier (),
353 : std::move (inner_fn_1));
354 1650 : };
355 :
356 1650 : ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
357 2475 : inner_fn_2, type.get_identifier ());
358 825 : }
359 :
360 : void
361 186882 : DefaultResolver::visit (AST::TypeAlias &type)
362 : {
363 186882 : auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
364 :
365 373764 : auto inner_fn_2 = [this, &type, &inner_fn_1] () {
366 186882 : ctx.canonical_ctx.scope (type.get_node_id (), type.get_new_type_name (),
367 : std::move (inner_fn_1));
368 373764 : };
369 :
370 373764 : ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
371 560646 : inner_fn_2, type.get_new_type_name ());
372 186882 : }
373 :
374 : void
375 21654 : DefaultResolver::visit_closure_params (AST::ClosureExpr &expr)
376 : {
377 47532 : for (auto ¶m : expr.get_params ())
378 25878 : visit (param);
379 21654 : }
380 :
381 : void
382 21654 : DefaultResolver::visit (AST::ClosureExpr &expr)
383 : {
384 43308 : auto expr_fn = [this, &expr] () {
385 21654 : visit_closure_params (expr);
386 21654 : visit (expr.get_definition_expr ());
387 43308 : };
388 :
389 21654 : visit_outer_attrs (expr);
390 :
391 21654 : ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), expr_fn);
392 21654 : }
393 :
394 : void
395 21402 : DefaultResolver::visit (AST::ClosureExprInner &expr)
396 : {
397 21402 : if (expr.is_marked_for_strip ())
398 : return;
399 :
400 21402 : visit (static_cast<AST::ClosureExpr &> (expr));
401 : }
402 :
403 : void
404 252 : DefaultResolver::visit (AST::ClosureExprInnerTyped &expr)
405 : {
406 252 : if (expr.is_marked_for_strip ())
407 : return;
408 :
409 252 : visit (static_cast<AST::ClosureExpr &> (expr));
410 252 : visit (expr.get_return_type ());
411 : }
412 :
413 : void
414 318092 : DefaultResolver::visit (AST::MatchExpr &expr)
415 : {
416 318092 : if (expr.is_marked_for_strip ())
417 : return;
418 :
419 318092 : AST::DefaultASTVisitor::visit (expr);
420 : }
421 :
422 : void
423 3312206 : DefaultResolver::visit (AST::MatchCase &cas)
424 : {
425 3312206 : auto vis = [this, &cas] () { AST::DefaultASTVisitor::visit (cas); };
426 :
427 3312206 : ctx.scoped (Rib::Kind::Normal, cas.get_node_id (), vis);
428 3312205 : }
429 :
430 : void
431 53844 : DefaultResolver::visit (AST::ConstantItem &item)
432 : {
433 53844 : auto expr_vis_1 = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
434 :
435 107688 : auto expr_vis_2 = [this, &item, &expr_vis_1] () {
436 53844 : ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
437 : std::move (expr_vis_1));
438 107688 : };
439 :
440 : // FIXME: Why do we need a Rib here?
441 53844 : ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis_2);
442 53844 : }
443 :
444 : void
445 2915 : DefaultResolver::visit (AST::StaticItem &item)
446 : {
447 2915 : auto expr_vis_1 = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
448 :
449 5830 : auto expr_vis_2 = [this, &item, &expr_vis_1] () {
450 2915 : ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
451 : std::move (expr_vis_1));
452 5830 : };
453 :
454 : // FIXME: Why do we need a Rib here?
455 2915 : ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis_2);
456 2915 : }
457 :
458 : void
459 586687 : DefaultResolver::visit (AST::TypeParam ¶m)
460 : {
461 1173374 : auto param_ban_vis = [this, ¶m] () {
462 586687 : visit_outer_attrs (param);
463 586687 : if (param.has_type ())
464 4877 : visit (param.get_type ());
465 1173374 : };
466 :
467 586687 : ctx.scoped (Rib::Kind::ForwardTypeParamBan, param.get_node_id (),
468 1173374 : param_ban_vis);
469 :
470 746191 : for (auto &bound : param.get_type_param_bounds ())
471 159504 : visit (bound);
472 586687 : }
473 :
474 : void
475 99 : DefaultResolver::visit_extern_crate (AST::ExternCrate &extern_crate,
476 : AST::Crate &crate, CrateNum num)
477 : {
478 : // We do *NOT* visit the crate because loaded crates are resolved
479 : // independently.
480 99 : }
481 :
482 : void
483 207 : DefaultResolver::visit (AST::ExternCrate &crate)
484 : {
485 207 : auto &mappings = Analysis::Mappings::get ();
486 207 : tl::optional<CrateNum> num_opt;
487 207 : if (crate.get_referenced_crate () == "self")
488 6 : num_opt = mappings.get_current_crate ();
489 : else
490 201 : num_opt = mappings.lookup_crate_name (crate.get_referenced_crate ());
491 :
492 207 : if (!num_opt)
493 : {
494 9 : rust_error_at (crate.get_locus (), "unknown crate %qs",
495 9 : crate.get_referenced_crate ().c_str ());
496 9 : return;
497 : }
498 :
499 198 : CrateNum num = *num_opt;
500 :
501 198 : AST::Crate &referenced_crate = mappings.get_ast_crate (num);
502 :
503 198 : auto sub_visitor_1
504 198 : = [&, this] () { visit_extern_crate (crate, referenced_crate, num); };
505 :
506 396 : auto sub_visitor_2 = [&] () {
507 198 : ctx.canonical_ctx.scope_crate (referenced_crate.get_node_id (),
508 198 : crate.get_referenced_crate () == "self"
509 6 : ? mappings.get_current_crate_name ()
510 : : crate.get_referenced_crate (),
511 : std::move (sub_visitor_1));
512 396 : };
513 :
514 198 : if (crate.has_as_clause ())
515 12 : ctx.scoped (Rib::Kind::Module, referenced_crate.get_node_id (),
516 18 : sub_visitor_2, crate.get_as_clause ());
517 : else
518 192 : ctx.scoped (Rib::Kind::Module, referenced_crate.get_node_id (),
519 576 : sub_visitor_2, crate.get_referenced_crate ());
520 : }
521 :
522 : } // namespace Resolver2_0
523 : } // namespace Rust
|