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