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 31502 : 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 31502 : if (!visited_crates.insert (crate.get_node_id ()).second)
37 6 : return;
38 :
39 31496 : auto inner_fn = [this, &crate] () { AST::DefaultASTVisitor::visit (crate); };
40 :
41 31496 : auto &mappings = Analysis::Mappings::get ();
42 :
43 31496 : auto crate_num = mappings.lookup_crate_num (crate.get_node_id ());
44 31496 : rust_assert (crate_num.has_value ());
45 31496 : auto crate_name = mappings.get_crate_name (*crate_num);
46 31496 : rust_assert (crate_name.has_value ());
47 :
48 62992 : ctx.canonical_ctx.scope_crate (crate.get_node_id (), *crate_name, inner_fn);
49 : }
50 :
51 : void
52 158013 : DefaultResolver::visit (AST::BlockExpr &expr)
53 : {
54 : // extracting the lambda from the `scoped` call otherwise the code looks like
55 : // a hot turd thanks to our .clang-format
56 :
57 158013 : auto inner_fn = [this, &expr] () { AST::DefaultASTVisitor::visit (expr); };
58 :
59 158013 : ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), inner_fn);
60 158008 : }
61 :
62 : void
63 9168 : DefaultResolver::visit (AST::Module &module)
64 : {
65 9168 : auto item_fn_1
66 9168 : = [this, &module] () { AST::DefaultASTVisitor::visit (module); };
67 :
68 18336 : auto item_fn_2 = [this, &module, &item_fn_1] () {
69 9168 : ctx.canonical_ctx.scope (module.get_node_id (), module.get_name (),
70 : std::move (item_fn_1));
71 18336 : };
72 :
73 18336 : ctx.scoped (Rib::Kind::Module, module.get_node_id (), item_fn_2,
74 18336 : module.get_name ());
75 9168 : }
76 :
77 : void
78 128633 : DefaultResolver::visit (AST::Function &function)
79 : {
80 128633 : auto def_fn_1
81 128633 : = [this, &function] () { AST::DefaultASTVisitor::visit (function); };
82 :
83 257266 : auto def_fn_2 = [this, &function, &def_fn_1] () {
84 128633 : ctx.canonical_ctx.scope (function.get_node_id (),
85 128633 : function.get_function_name (),
86 : std::move (def_fn_1));
87 257264 : };
88 :
89 257266 : ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn_2,
90 257264 : function.get_function_name ());
91 128631 : }
92 :
93 : void
94 132 : DefaultResolver::visit (AST::ForLoopExpr &expr)
95 : {
96 132 : ctx.scoped (Rib::Kind::Normal, expr.get_node_id (),
97 396 : [this, &expr] () { AST::DefaultASTVisitor::visit (expr); });
98 132 : }
99 :
100 : void
101 180 : DefaultResolver::visit_if_let_patterns (AST::IfLetExpr &expr)
102 : {
103 180 : visit (expr.get_pattern ());
104 180 : }
105 :
106 : void
107 180 : DefaultResolver::visit (AST::IfLetExpr &expr)
108 : {
109 360 : auto inner_vis = [this, &expr] () {
110 180 : visit_if_let_patterns (expr);
111 180 : visit (expr.get_if_block ());
112 360 : };
113 :
114 180 : visit_outer_attrs (expr);
115 :
116 180 : visit (expr.get_value_expr ());
117 :
118 180 : ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), inner_vis);
119 180 : }
120 :
121 : void
122 72 : DefaultResolver::visit (AST::IfLetExprConseqElse &expr)
123 : {
124 72 : DefaultResolver::visit (static_cast<AST::IfLetExpr &> (expr));
125 72 : visit (expr.get_else_block ());
126 72 : }
127 :
128 : void
129 26377 : DefaultResolver::visit (AST::Trait &trait)
130 : {
131 26377 : visit_outer_attrs (trait);
132 26377 : visit (trait.get_visibility ());
133 26377 : visit_inner_attrs (trait);
134 :
135 52754 : auto inner_fn_1 = [this, &trait] () {
136 50357 : for (auto &item : trait.get_trait_items ())
137 23980 : visit (item);
138 52754 : };
139 :
140 52754 : auto inner_fn_2 = [this, &trait, &inner_fn_1] () {
141 26377 : visit (trait.get_implicit_self ());
142 30999 : for (auto &generic : trait.get_generic_params ())
143 4622 : visit (generic);
144 26377 : if (trait.has_where_clause ())
145 56 : visit (trait.get_where_clause ());
146 30979 : for (auto &bound : trait.get_type_param_bounds ())
147 4602 : visit (bound);
148 :
149 26377 : ctx.scoped (Rib::Kind::TraitOrImpl, trait.get_node_id (), inner_fn_1);
150 52754 : };
151 :
152 52754 : auto inner_fn_3 = [this, &trait, &inner_fn_2] () {
153 26377 : ctx.canonical_ctx.scope (trait.get_node_id (), trait.get_identifier (),
154 : std::move (inner_fn_2));
155 52754 : };
156 :
157 52754 : ctx.scoped (Rib::Kind::Generics, trait.get_node_id (), inner_fn_3,
158 52754 : trait.get_identifier () /* FIXME: Is that valid?*/);
159 26377 : }
160 :
161 : static bool
162 6488 : is_lang_impl (std::vector<AST::Attribute> &outer_attrs)
163 : {
164 6497 : for (auto &attr : outer_attrs)
165 1357 : if (attr.get_path ().as_string () == Values::Attributes::LANG)
166 6488 : return true;
167 :
168 : return false;
169 : }
170 :
171 : void
172 6488 : DefaultResolver::visit (AST::InherentImpl &impl)
173 : {
174 6488 : visit_outer_attrs (impl);
175 6488 : visit (impl.get_visibility ());
176 6488 : visit_inner_attrs (impl);
177 :
178 12976 : auto inner_fn_1 = [this, &impl] () {
179 26052 : for (auto &item : impl.get_impl_items ())
180 19564 : visit (item);
181 12976 : };
182 :
183 12976 : auto inner_fn_2 = [this, &impl, &inner_fn_1] () {
184 6488 : maybe_insert_big_self (impl);
185 8737 : for (auto &generic : impl.get_generic_params ())
186 2249 : visit (generic);
187 6488 : if (impl.has_where_clause ())
188 5 : visit (impl.get_where_clause ());
189 6488 : visit_impl_type (impl.get_type ());
190 :
191 6488 : ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_1);
192 12976 : };
193 :
194 12976 : auto inner_fn_3 = [this, &impl, &inner_fn_2] () {
195 6488 : ctx.canonical_ctx.scope_impl (impl, std::move (inner_fn_2));
196 12976 : };
197 :
198 6488 : ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_3);
199 :
200 6488 : if (is_lang_impl (impl.get_outer_attrs ()))
201 : {
202 1348 : if (impl.get_type ().get_type_kind () == AST::Type::Kind::TypePath)
203 : {
204 258 : auto type = static_cast<AST::TypePath &> (impl.get_type ());
205 258 : auto type_name = type.as_string ();
206 :
207 774 : ctx.types.insert_lang_prelude (type_name, impl.get_node_id ());
208 258 : }
209 : }
210 6488 : }
211 :
212 : void
213 32139 : DefaultResolver::visit (AST::TraitImpl &impl)
214 : {
215 32139 : visit_outer_attrs (impl);
216 32139 : visit (impl.get_visibility ());
217 32139 : visit_inner_attrs (impl);
218 :
219 64278 : auto inner_fn_1 = [this, &impl] () {
220 69908 : for (auto &item : impl.get_impl_items ())
221 37769 : visit (item);
222 64278 : };
223 :
224 64278 : auto inner_fn_2 = [this, &impl, &inner_fn_1] () {
225 32139 : maybe_insert_big_self (impl);
226 37545 : for (auto &generic : impl.get_generic_params ())
227 5406 : visit (generic);
228 32139 : if (impl.has_where_clause ())
229 600 : visit (impl.get_where_clause ());
230 32139 : visit_impl_type (impl.get_type ());
231 32139 : visit (impl.get_trait_path ());
232 :
233 32139 : ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_1);
234 64278 : };
235 :
236 64278 : auto inner_fn_3 = [this, &impl, &inner_fn_2] () {
237 32139 : ctx.canonical_ctx.scope_impl (impl, std::move (inner_fn_2));
238 64278 : };
239 :
240 32139 : ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_3);
241 32139 : }
242 :
243 : void
244 10644 : DefaultResolver::visit (AST::StructStruct &type)
245 : {
246 10644 : auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
247 :
248 21288 : auto inner_fn_2 = [this, &type, &inner_fn_1] () {
249 10644 : ctx.canonical_ctx.scope (type.get_node_id (), type.get_struct_name (),
250 : std::move (inner_fn_1));
251 21288 : };
252 :
253 10644 : ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
254 31932 : inner_fn_2, type.get_struct_name ());
255 10644 : }
256 :
257 : void
258 6139 : DefaultResolver::visit (AST::TupleStruct &type)
259 : {
260 6139 : auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
261 :
262 12278 : auto inner_fn_2 = [this, &type, &inner_fn_1] () {
263 6139 : ctx.canonical_ctx.scope (type.get_node_id (), type.get_struct_name (),
264 : std::move (inner_fn_1));
265 12278 : };
266 :
267 6139 : ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
268 18417 : inner_fn_2, type.get_struct_name ());
269 6139 : }
270 :
271 : void
272 3042 : DefaultResolver::visit (AST::EnumItem &item)
273 : {
274 3042 : auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
275 :
276 3042 : ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
277 : inner_fn);
278 3042 : }
279 :
280 : void
281 3123 : DefaultResolver::visit (AST::EnumItemTuple &item)
282 : {
283 3123 : auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
284 :
285 3123 : ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
286 : inner_fn);
287 3123 : }
288 :
289 : void
290 610 : DefaultResolver::visit (AST::EnumItemStruct &item)
291 : {
292 610 : auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
293 :
294 610 : ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
295 : inner_fn);
296 610 : }
297 :
298 : void
299 1947 : DefaultResolver::visit (AST::EnumItemDiscriminant &item)
300 : {
301 1947 : auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
302 :
303 1947 : ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
304 : inner_fn);
305 1947 : }
306 :
307 : void
308 3763 : DefaultResolver::visit (AST::Enum &type)
309 : {
310 3763 : auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
311 :
312 7526 : auto inner_fn_2 = [this, &type, &inner_fn_1] () {
313 3763 : ctx.canonical_ctx.scope (type.get_node_id (), type.get_identifier (),
314 : std::move (inner_fn_1));
315 7526 : };
316 :
317 7526 : ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
318 11289 : inner_fn_2, type.get_identifier ());
319 3763 : }
320 :
321 : void
322 675 : DefaultResolver::visit (AST::Union &type)
323 : {
324 675 : auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
325 :
326 1350 : auto inner_fn_2 = [this, &type, &inner_fn_1] () {
327 675 : ctx.canonical_ctx.scope (type.get_node_id (), type.get_identifier (),
328 : std::move (inner_fn_1));
329 1350 : };
330 :
331 1350 : ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
332 2025 : inner_fn_2, type.get_identifier ());
333 675 : }
334 :
335 : void
336 9040 : DefaultResolver::visit (AST::TypeAlias &type)
337 : {
338 9040 : auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
339 :
340 18080 : auto inner_fn_2 = [this, &type, &inner_fn_1] () {
341 9040 : ctx.canonical_ctx.scope (type.get_node_id (), type.get_new_type_name (),
342 : std::move (inner_fn_1));
343 18080 : };
344 :
345 18080 : ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
346 27120 : inner_fn_2, type.get_new_type_name ());
347 9040 : }
348 :
349 : void
350 402 : DefaultResolver::visit_closure_params (AST::ClosureExpr &expr)
351 : {
352 780 : for (auto ¶m : expr.get_params ())
353 378 : visit (param);
354 402 : }
355 :
356 : void
357 402 : DefaultResolver::visit (AST::ClosureExpr &expr)
358 : {
359 804 : auto expr_fn = [this, &expr] () {
360 402 : visit_closure_params (expr);
361 402 : visit (expr.get_definition_expr ());
362 804 : };
363 :
364 402 : visit_outer_attrs (expr);
365 :
366 402 : ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), expr_fn);
367 402 : }
368 :
369 : void
370 222 : DefaultResolver::visit (AST::ClosureExprInner &expr)
371 : {
372 222 : if (expr.is_marked_for_strip ())
373 : return;
374 :
375 222 : visit (static_cast<AST::ClosureExpr &> (expr));
376 : }
377 :
378 : void
379 180 : DefaultResolver::visit (AST::ClosureExprInnerTyped &expr)
380 : {
381 180 : if (expr.is_marked_for_strip ())
382 : return;
383 :
384 180 : visit (static_cast<AST::ClosureExpr &> (expr));
385 180 : visit (expr.get_return_type ());
386 : }
387 :
388 : void
389 7018 : DefaultResolver::visit (AST::MatchExpr &expr)
390 : {
391 7018 : if (expr.is_marked_for_strip ())
392 : return;
393 :
394 7018 : AST::DefaultASTVisitor::visit (expr);
395 : }
396 :
397 : void
398 16294 : DefaultResolver::visit (AST::MatchCase &cas)
399 : {
400 16294 : auto vis = [this, &cas] () { AST::DefaultASTVisitor::visit (cas); };
401 :
402 16294 : ctx.scoped (Rib::Kind::Normal, cas.get_node_id (), vis);
403 16293 : }
404 :
405 : void
406 3556 : DefaultResolver::visit (AST::ConstantItem &item)
407 : {
408 3556 : auto expr_vis_1 = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
409 :
410 7112 : auto expr_vis_2 = [this, &item, &expr_vis_1] () {
411 3556 : ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
412 : std::move (expr_vis_1));
413 7112 : };
414 :
415 : // FIXME: Why do we need a Rib here?
416 3556 : ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis_2);
417 3556 : }
418 :
419 : void
420 371 : DefaultResolver::visit (AST::StaticItem &item)
421 : {
422 371 : auto expr_vis_1 = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
423 :
424 742 : auto expr_vis_2 = [this, &item, &expr_vis_1] () {
425 371 : ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
426 : std::move (expr_vis_1));
427 742 : };
428 :
429 : // FIXME: Why do we need a Rib here?
430 371 : ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis_2);
431 371 : }
432 :
433 : void
434 58215 : DefaultResolver::visit (AST::TypeParam ¶m)
435 : {
436 58215 : auto expr_vis = [this, ¶m] () { AST::DefaultASTVisitor::visit (param); };
437 :
438 58215 : ctx.scoped (Rib::Kind::ForwardTypeParamBan, param.get_node_id (), expr_vis);
439 58215 : }
440 :
441 : void
442 75 : DefaultResolver::visit_extern_crate (AST::ExternCrate &extern_crate,
443 : AST::Crate &crate, CrateNum num)
444 : {
445 75 : visit (crate);
446 75 : }
447 :
448 : void
449 159 : DefaultResolver::visit (AST::ExternCrate &crate)
450 : {
451 159 : auto &mappings = Analysis::Mappings::get ();
452 159 : tl::optional<CrateNum> num_opt;
453 159 : if (crate.get_referenced_crate () == "self")
454 6 : num_opt = mappings.get_current_crate ();
455 : else
456 153 : num_opt = mappings.lookup_crate_name (crate.get_referenced_crate ());
457 :
458 159 : if (!num_opt)
459 : {
460 9 : rust_error_at (crate.get_locus (), "unknown crate %qs",
461 9 : crate.get_referenced_crate ().c_str ());
462 9 : return;
463 : }
464 :
465 150 : CrateNum num = *num_opt;
466 :
467 150 : AST::Crate &referenced_crate = mappings.get_ast_crate (num);
468 :
469 150 : auto sub_visitor_1
470 150 : = [&, this] () { visit_extern_crate (crate, referenced_crate, num); };
471 :
472 300 : auto sub_visitor_2 = [&] () {
473 150 : ctx.canonical_ctx.scope_crate (referenced_crate.get_node_id (),
474 150 : crate.get_referenced_crate () == "self"
475 6 : ? mappings.get_current_crate_name ()
476 : : crate.get_referenced_crate (),
477 : std::move (sub_visitor_1));
478 300 : };
479 :
480 150 : if (crate.has_as_clause ())
481 12 : ctx.scoped (Rib::Kind::Module, referenced_crate.get_node_id (),
482 18 : sub_visitor_2, crate.get_as_clause ());
483 : else
484 144 : ctx.scoped (Rib::Kind::Module, referenced_crate.get_node_id (),
485 432 : sub_visitor_2, crate.get_referenced_crate ());
486 : }
487 :
488 : } // namespace Resolver2_0
489 : } // namespace Rust
|