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-toplevel-name-resolver-2.0.h"
20 : #include "input.h"
21 : #include "optional.h"
22 : #include "rust-ast-full.h"
23 : #include "rust-hir-map.h"
24 : #include "rust-attribute-values.h"
25 :
26 : namespace Rust {
27 : namespace Resolver2_0 {
28 :
29 15947 : TopLevel::TopLevel (NameResolutionContext &resolver)
30 15947 : : DefaultResolver (resolver), dirty (false)
31 15947 : {}
32 :
33 : template <typename T>
34 : void
35 7606 : TopLevel::insert_enum_variant_or_error_out (const Identifier &identifier,
36 : const T &node, bool is_also_value)
37 : {
38 7606 : insert_enum_variant_or_error_out (identifier, node.get_locus (),
39 7606 : node.get_node_id (), is_also_value);
40 7606 : }
41 :
42 : void
43 1275860 : TopLevel::check_multiple_insertion_error (
44 : tl::expected<NodeId, DuplicateNameError> result, const Identifier &identifier,
45 : const location_t &locus, const NodeId node_id)
46 : {
47 1275860 : if (result)
48 82804 : dirty = true;
49 1193056 : else if (result.error ().existing != node_id)
50 : {
51 16 : rich_location rich_loc (line_table, locus);
52 16 : rich_loc.add_range (node_locations[result.error ().existing]);
53 :
54 16 : rust_error_at (rich_loc, ErrorCode::E0428, "%qs defined multiple times",
55 16 : identifier.as_string ().c_str ());
56 16 : }
57 1275860 : }
58 : void
59 7606 : TopLevel::insert_enum_variant_or_error_out (const Identifier &identifier,
60 : const location_t &locus,
61 : const NodeId node_id,
62 : bool is_also_value)
63 : {
64 : // keep track of each node's location to provide useful errors
65 7606 : node_locations.emplace (node_id, locus);
66 :
67 7606 : auto result = ctx.insert_variant (identifier, node_id, is_also_value);
68 13818 : check_multiple_insertion_error (result, identifier, locus, node_id);
69 7606 : }
70 :
71 : template <typename T>
72 : void
73 1260476 : TopLevel::insert_or_error_out (const Identifier &identifier, const T &node,
74 : Namespace ns)
75 : {
76 1260476 : insert_or_error_out (identifier, node.get_locus (), node.get_node_id (), ns);
77 1260476 : }
78 :
79 : void
80 1268254 : TopLevel::insert_or_error_out (const Identifier &identifier,
81 : const location_t &locus, const NodeId &node_id,
82 : Namespace ns)
83 : {
84 : // keep track of each node's location to provide useful errors
85 1268254 : node_locations.emplace (node_id, locus);
86 :
87 1268254 : auto result = ctx.insert (identifier, node_id, ns);
88 2455098 : check_multiple_insertion_error (result, identifier, locus, node_id);
89 1268254 : }
90 :
91 : void
92 15947 : TopLevel::go (AST::Crate &crate)
93 : {
94 : // we do not include builtin types in the top-level definition collector, as
95 : // they are not used until `Late`. furthermore, we run this visitor multiple
96 : // times in a row in a fixed-point fashion, so it would make the code
97 : // responsible for this ugly and perfom a lot of error checking.
98 :
99 15947 : visit (crate);
100 :
101 15947 : if (Analysis::Mappings::get ().lookup_glob_container (crate.get_node_id ())
102 15947 : == tl::nullopt)
103 4869 : Analysis::Mappings::get ().insert_glob_container (crate.get_node_id (),
104 : &crate);
105 15947 : }
106 :
107 : void
108 12929 : TopLevel::visit (AST::Module &module)
109 : {
110 12929 : if (Analysis::Mappings::get ().lookup_glob_container (module.get_node_id ())
111 12929 : == tl::nullopt)
112 1537 : Analysis::Mappings::get ().insert_glob_container (module.get_node_id (),
113 : &module);
114 :
115 12929 : insert_or_error_out (module.get_name (), module, Namespace::Types);
116 :
117 12929 : Analysis::Mappings::get ().insert_module_id (module.get_node_id ());
118 :
119 12929 : DefaultResolver::visit (module);
120 12929 : }
121 :
122 : void
123 17978 : TopLevel::visit (AST::Trait &trait)
124 : {
125 17978 : insert_or_error_out (trait.get_identifier (), trait, Namespace::Types);
126 :
127 17978 : DefaultResolver::visit (trait);
128 17978 : }
129 :
130 : void
131 258815 : TopLevel::maybe_insert_big_self (AST::Impl &impl)
132 : {
133 517630 : insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()),
134 258815 : impl.get_type (), Namespace::Types);
135 258815 : }
136 :
137 : void
138 3922 : TopLevel::visit (AST::TraitItemType &trait_item)
139 : {
140 11766 : insert_or_error_out (trait_item.get_identifier ().as_string (), trait_item,
141 : Namespace::Types);
142 :
143 3922 : DefaultResolver::visit (trait_item);
144 3922 : }
145 :
146 : template <typename PROC_MACRO>
147 : static void
148 288 : insert_macros (std::vector<PROC_MACRO> ¯os, NameResolutionContext &ctx)
149 : {
150 288 : for (auto ¯o : macros)
151 : {
152 0 : auto res = ctx.macros.insert (macro.get_name (), macro.get_node_id ());
153 :
154 0 : if (!res && res.error ().existing != macro.get_node_id ())
155 : {
156 0 : rust_error_at (UNKNOWN_LOCATION, ErrorCode::E0428,
157 : "macro %qs defined multiple times",
158 0 : macro.get_name ().c_str ());
159 : }
160 : }
161 288 : }
162 :
163 : void
164 99 : TopLevel::visit_extern_crate (AST::ExternCrate &extern_crate, AST::Crate &crate,
165 : CrateNum num)
166 : {
167 99 : auto &mappings = Analysis::Mappings::get ();
168 :
169 99 : auto attribute_macros = mappings.lookup_attribute_proc_macros (num);
170 :
171 99 : auto bang_macros = mappings.lookup_bang_proc_macros (num);
172 :
173 99 : auto derive_macros = mappings.lookup_derive_proc_macros (num);
174 :
175 : // TODO: Find a way to keep this part clean without the double dispatch.
176 99 : if (derive_macros.has_value ())
177 : {
178 96 : insert_macros (derive_macros.value (), ctx);
179 96 : for (auto ¯o : derive_macros.value ())
180 0 : mappings.insert_derive_proc_macro_def (macro);
181 : }
182 99 : if (attribute_macros.has_value ())
183 : {
184 96 : insert_macros (attribute_macros.value (), ctx);
185 96 : for (auto ¯o : attribute_macros.value ())
186 0 : mappings.insert_attribute_proc_macro_def (macro);
187 : }
188 99 : if (bang_macros.has_value ())
189 : {
190 96 : insert_macros (bang_macros.value (), ctx);
191 96 : for (auto ¯o : bang_macros.value ())
192 0 : mappings.insert_bang_proc_macro_def (macro);
193 : }
194 :
195 : // We do *NOT* visit the crate because loaded crates are resolved
196 : // independently.
197 99 : }
198 :
199 : static bool
200 30535 : is_macro_export (AST::MacroRulesDefinition &def)
201 : {
202 74002 : for (const auto &attr : def.get_outer_attrs ())
203 44742 : if (attr.get_path ().as_string () == Values::Attributes::MACRO_EXPORT)
204 30535 : return true;
205 :
206 : return false;
207 : }
208 :
209 : void
210 30535 : TopLevel::visit (AST::MacroRulesDefinition ¯o)
211 : {
212 : // we do not insert macros in the current rib as that needs to be done in the
213 : // textual scope of the Early pass. we only insert them in the root of the
214 : // crate if they are marked with #[macro_export]. The execption to this is
215 : // macros 2.0, which get resolved and inserted like regular items.
216 :
217 30535 : if (is_macro_export (macro))
218 : {
219 3825 : auto res = ctx.macros.insert_at_root (macro.get_rule_name (),
220 1275 : macro.get_node_id ());
221 1275 : if (!res && res.error ().existing != macro.get_node_id ())
222 : {
223 : // TODO: Factor this
224 0 : rich_location rich_loc (line_table, macro.get_locus ());
225 0 : rich_loc.add_range (node_locations[res.error ().existing]);
226 :
227 0 : rust_error_at (rich_loc, ErrorCode::E0428,
228 : "macro %qs defined multiple times",
229 0 : macro.get_rule_name ().as_string ().c_str ());
230 0 : }
231 1275 : }
232 :
233 30535 : if (macro.get_kind () == AST::MacroRulesDefinition::MacroKind::DeclMacro)
234 837 : insert_or_error_out (macro.get_rule_name (), macro, Namespace::Macros);
235 :
236 30535 : auto &mappings = Analysis::Mappings::get ();
237 30535 : if (mappings.lookup_macro_def (macro.get_node_id ()))
238 : return;
239 :
240 1697 : mappings.insert_macro_def (¯o);
241 : }
242 :
243 : void
244 490167 : TopLevel::visit (AST::Function &function)
245 : {
246 490167 : insert_or_error_out (function.get_function_name (), function,
247 : Namespace::Values);
248 :
249 490167 : Analysis::Mappings::get ().add_function_node (function.get_node_id ());
250 :
251 490167 : DefaultResolver::visit (function);
252 490167 : }
253 :
254 : void
255 1455 : TopLevel::visit (AST::StaticItem &static_item)
256 : {
257 1455 : insert_or_error_out (static_item.get_identifier (), static_item,
258 : Namespace::Values);
259 :
260 1455 : DefaultResolver::visit (static_item);
261 1455 : }
262 :
263 : void
264 3 : TopLevel::visit (AST::ExternalStaticItem &static_item)
265 : {
266 9 : insert_or_error_out (static_item.get_identifier ().as_string (), static_item,
267 : Namespace::Values);
268 :
269 3 : DefaultResolver::visit (static_item);
270 3 : }
271 :
272 : void
273 25946 : TopLevel::visit (AST::StructStruct &struct_item)
274 : {
275 25946 : DefaultResolver::visit (struct_item);
276 :
277 25946 : insert_or_error_out (struct_item.get_struct_name (), struct_item,
278 : Namespace::Types);
279 :
280 : // Do we need to insert the constructor in the value namespace as well?
281 :
282 : // Do we need to do anything if the struct is a unit struct?
283 25946 : if (struct_item.is_unit_struct ())
284 14958 : insert_or_error_out (struct_item.get_struct_name (), struct_item,
285 : Namespace::Values);
286 25946 : }
287 :
288 : void
289 293319 : TopLevel::visit (AST::TypeParam &type_param)
290 : {
291 293319 : insert_or_error_out (type_param.get_type_representation (), type_param,
292 : Namespace::Types);
293 :
294 293319 : DefaultResolver::visit (type_param);
295 293319 : }
296 :
297 : void
298 3014 : TopLevel::visit (AST::ConstGenericParam &const_param)
299 : {
300 3014 : insert_or_error_out (const_param.get_name (), const_param, Namespace::Values);
301 :
302 3014 : DefaultResolver::visit (const_param);
303 3014 : }
304 :
305 : void
306 6664 : TopLevel::visit (AST::TupleStruct &tuple_struct)
307 : {
308 6664 : insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
309 : Namespace::Types);
310 :
311 6664 : insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
312 : Namespace::Values);
313 :
314 6664 : DefaultResolver::visit (tuple_struct);
315 6664 : }
316 :
317 : void
318 3681 : TopLevel::visit (AST::EnumItem &variant)
319 : {
320 3681 : insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
321 :
322 3681 : DefaultResolver::visit (variant);
323 3681 : }
324 :
325 : void
326 2543 : TopLevel::visit (AST::EnumItemTuple &variant)
327 : {
328 2543 : insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
329 :
330 2543 : DefaultResolver::visit (variant);
331 2543 : }
332 :
333 : void
334 303 : TopLevel::visit (AST::EnumItemStruct &variant)
335 : {
336 303 : insert_enum_variant_or_error_out (variant.get_identifier (), variant, false);
337 :
338 303 : DefaultResolver::visit (variant);
339 303 : }
340 :
341 : void
342 1079 : TopLevel::visit (AST::EnumItemDiscriminant &variant)
343 : {
344 1079 : insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
345 :
346 1079 : DefaultResolver::visit (variant);
347 1079 : }
348 :
349 : void
350 2985 : TopLevel::visit (AST::Enum &enum_item)
351 : {
352 2985 : insert_or_error_out (enum_item.get_identifier (), enum_item,
353 : Namespace::Types);
354 :
355 2985 : DefaultResolver::visit (enum_item);
356 :
357 : // Since enums can be containers for imports, we need to insert them like we
358 : // do for modules
359 5970 : if (Analysis::Mappings::get ().lookup_glob_container (
360 2985 : enum_item.get_node_id ())
361 2985 : == tl::nullopt)
362 597 : Analysis::Mappings::get ().insert_glob_container (enum_item.get_node_id (),
363 : &enum_item);
364 2985 : }
365 :
366 : void
367 411 : TopLevel::visit (AST::Union &union_item)
368 : {
369 411 : insert_or_error_out (union_item.get_identifier (), union_item,
370 : Namespace::Types);
371 :
372 411 : DefaultResolver::visit (union_item);
373 411 : }
374 :
375 : void
376 26917 : TopLevel::visit (AST::ConstantItem &const_item)
377 : {
378 26917 : if (const_item.get_identifier ().as_string () != Values::Keywords::UNDERSCORE)
379 26899 : insert_or_error_out (const_item.get_identifier (), const_item,
380 : Namespace::Values);
381 :
382 26917 : DefaultResolver::visit (const_item);
383 26917 : }
384 :
385 : void
386 93468 : TopLevel::visit (AST::TypeAlias &type_item)
387 : {
388 93468 : insert_or_error_out (type_item.get_new_type_name (), type_item,
389 : Namespace::Types);
390 :
391 93468 : DefaultResolver::visit (type_item);
392 93468 : }
393 :
394 : void
395 42 : TopLevel::visit (AST::ExternalTypeItem &type_item)
396 : {
397 42 : insert_or_error_out (type_item.get_identifier (), type_item,
398 : Namespace::Types);
399 :
400 42 : DefaultResolver::visit (type_item);
401 42 : }
402 :
403 : static void flatten_rebind (
404 : const AST::UseTreeRebind &glob,
405 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths);
406 :
407 : static void flatten_list (
408 : const AST::UseTreeList &glob, std::vector<AST::SimplePath> &paths,
409 : std::vector<AST::SimplePath> &glob_paths,
410 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
411 : NameResolutionContext &ctx);
412 : static void flatten_glob (const AST::UseTreeGlob &glob,
413 : std::vector<AST::SimplePath> &glob_paths,
414 : NameResolutionContext &ctx);
415 :
416 : static void
417 54646 : flatten (
418 : const AST::UseTree *tree, std::vector<AST::SimplePath> &paths,
419 : std::vector<AST::SimplePath> &glob_paths,
420 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
421 : NameResolutionContext &ctx)
422 : {
423 54646 : switch (tree->get_kind ())
424 : {
425 41943 : case AST::UseTree::Rebind:
426 41943 : {
427 41943 : auto rebind = static_cast<const AST::UseTreeRebind *> (tree);
428 41943 : flatten_rebind (*rebind, rebind_paths);
429 41943 : break;
430 : }
431 8755 : case AST::UseTree::List:
432 8755 : {
433 8755 : auto list = static_cast<const AST::UseTreeList *> (tree);
434 8755 : flatten_list (*list, paths, glob_paths, rebind_paths, ctx);
435 8755 : break;
436 : }
437 3948 : case AST::UseTree::Glob:
438 3948 : {
439 3948 : auto glob = static_cast<const AST::UseTreeGlob *> (tree);
440 3948 : flatten_glob (*glob, glob_paths, ctx);
441 3948 : break;
442 : }
443 : }
444 54646 : }
445 :
446 : static void
447 41943 : flatten_rebind (
448 : const AST::UseTreeRebind &rebind,
449 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths)
450 : {
451 41943 : rebind_paths.emplace_back (rebind.get_path (), rebind);
452 41943 : }
453 :
454 : /** Prefix a list of subpath
455 : * @param prefix A prefix for all subpath
456 : * @param subs List of subpath to prefix
457 : * @param size List where results should be stored
458 : */
459 : static void
460 55476 : prefix_subpaths (AST::SimplePath prefix, std::vector<AST::SimplePath> subs,
461 : std::vector<AST::SimplePath> &results)
462 : {
463 58470 : for (auto &sub : subs)
464 : {
465 2994 : auto new_path = prefix;
466 2994 : std::copy (sub.get_segments ().begin (), sub.get_segments ().end (),
467 : std::back_inserter (new_path.get_segments ()));
468 2994 : results.emplace_back (new_path);
469 2994 : }
470 55476 : }
471 :
472 : static void
473 27738 : prefix_rebinds (
474 : AST::SimplePath prefix,
475 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> subs,
476 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &results)
477 : {
478 53814 : for (auto &sub : subs)
479 : {
480 26076 : auto new_path = prefix;
481 26076 : std::copy (sub.first.get_segments ().begin (),
482 26076 : sub.first.get_segments ().end (),
483 : std::back_inserter (new_path.get_segments ()));
484 52152 : results.emplace_back (std::make_pair (new_path, sub.second));
485 26076 : }
486 27738 : }
487 :
488 : static void
489 8755 : flatten_list (
490 : const AST::UseTreeList &list, std::vector<AST::SimplePath> &paths,
491 : std::vector<AST::SimplePath> &glob_paths,
492 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
493 : NameResolutionContext &ctx)
494 : {
495 8755 : auto prefix = AST::SimplePath::create_empty ();
496 8755 : if (list.has_path ())
497 8751 : prefix = list.get_path ();
498 :
499 36493 : for (const auto &tree : list.get_trees ())
500 : {
501 27738 : auto sub_paths = std::vector<AST::SimplePath> ();
502 27738 : auto sub_globs = std::vector<AST::SimplePath> ();
503 27738 : auto sub_rebinds
504 : = std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> ();
505 27738 : flatten (tree.get (), sub_paths, sub_globs, sub_rebinds, ctx);
506 :
507 27738 : prefix_subpaths (prefix, sub_paths, paths);
508 27738 : prefix_subpaths (prefix, sub_globs, glob_paths);
509 27738 : prefix_rebinds (prefix, sub_rebinds, rebind_paths);
510 27738 : }
511 8755 : }
512 :
513 : static void
514 3948 : flatten_glob (const AST::UseTreeGlob &glob, std::vector<AST::SimplePath> &paths,
515 : NameResolutionContext &ctx)
516 : {
517 3948 : if (glob.has_path ())
518 3945 : paths.emplace_back (glob.get_path ());
519 : else
520 3 : paths.emplace_back (AST::SimplePath (
521 3 : {}, glob.get_glob_type () == AST::UseTreeGlob::PathType::GLOBAL,
522 6 : glob.get_locus ()));
523 3948 : }
524 :
525 : static bool
526 3948 : has_prelude_import (const std::vector<AST::Attribute> &attributes)
527 : {
528 4095 : for (const auto &attr : attributes)
529 186 : if (attr.get_path ().as_string () == "prelude_import")
530 3948 : return true;
531 :
532 : return false;
533 : }
534 :
535 : void
536 26908 : TopLevel::visit (AST::UseDeclaration &use)
537 : {
538 26908 : auto paths = std::vector<AST::SimplePath> ();
539 26908 : auto glob_path = std::vector<AST::SimplePath> ();
540 26908 : auto rebind_path
541 : = std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> ();
542 :
543 26908 : auto &values_rib = ctx.values.peek ();
544 26908 : auto &types_rib = ctx.types.peek ();
545 26908 : auto ¯os_rib = ctx.macros.peek ();
546 :
547 : // FIXME: How do we handle `use foo::{self}` imports? Some beforehand cleanup?
548 : // How do we handle module imports in general? Should they get added to all
549 : // namespaces?
550 :
551 26908 : const auto &tree = use.get_tree ();
552 26908 : flatten (tree.get (), paths, glob_path, rebind_path, this->ctx);
553 :
554 26908 : auto imports = std::vector<ImportKind> ();
555 :
556 26908 : for (auto &&path : paths)
557 0 : imports.emplace_back (
558 0 : ImportKind::Simple (std::move (path), values_rib, types_rib, macros_rib));
559 :
560 30856 : for (auto &&glob : glob_path)
561 7896 : imports.emplace_back (
562 3948 : ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib,
563 3948 : has_prelude_import (use.get_outer_attrs ())));
564 :
565 68851 : for (auto &&rebind : rebind_path)
566 41943 : imports.emplace_back (
567 83886 : ImportKind::Rebind (std::move (rebind.first), std::move (rebind.second),
568 : values_rib, types_rib, macros_rib));
569 :
570 26908 : imports_to_resolve.insert ({use.get_node_id (), std::move (imports)});
571 26908 : }
572 :
573 : } // namespace Resolver2_0
574 : } // namespace Rust
|