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 16355 : TopLevel::TopLevel (NameResolutionContext &resolver)
30 16355 : : DefaultResolver (resolver), dirty (false)
31 16355 : {}
32 :
33 : template <typename T>
34 : void
35 8126 : TopLevel::insert_enum_variant_or_error_out (const Identifier &identifier,
36 : const T &node, bool is_also_value)
37 : {
38 8126 : insert_enum_variant_or_error_out (identifier, node.get_locus (),
39 8126 : node.get_node_id (), is_also_value);
40 8126 : }
41 :
42 : void
43 1319585 : 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 1319585 : if (result)
48 93344 : dirty = true;
49 1226241 : 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 1319585 : }
68 : void
69 8126 : 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 8126 : node_locations.emplace (node_id, locus);
76 :
77 8126 : auto result = ctx.insert_variant (identifier, node_id, is_also_value);
78 14749 : check_multiple_insertion_error (result, identifier, locus, node_id);
79 8126 : }
80 :
81 : template <typename T>
82 : void
83 1302490 : TopLevel::insert_or_error_out (const Identifier &identifier, const T &node,
84 : Namespace ns)
85 : {
86 1302490 : insert_or_error_out (identifier, node.get_locus (), node.get_node_id (), ns);
87 1302490 : }
88 :
89 : void
90 1311459 : 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 1311459 : node_locations.emplace (node_id, locus);
96 :
97 1311459 : auto result = ctx.insert (identifier, node_id, ns);
98 2531077 : check_multiple_insertion_error (result, identifier, locus, node_id);
99 1311459 : }
100 :
101 : void
102 16355 : 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 16355 : visit (crate);
110 :
111 16355 : if (Analysis::Mappings::get ().lookup_glob_container (crate.get_node_id ())
112 16355 : == tl::nullopt)
113 5024 : Analysis::Mappings::get ().insert_glob_container (crate.get_node_id (),
114 : &crate);
115 16355 : }
116 :
117 : void
118 13838 : TopLevel::visit (AST::Module &module)
119 : {
120 13838 : if (Analysis::Mappings::get ().lookup_glob_container (module.get_node_id ())
121 13838 : == tl::nullopt)
122 1730 : Analysis::Mappings::get ().insert_glob_container (module.get_node_id (),
123 : &module);
124 :
125 13838 : insert_or_error_out (module.get_name (), module, Namespace::Types);
126 :
127 13838 : Analysis::Mappings::get ().insert_module_id (module.get_node_id ());
128 :
129 13838 : DefaultResolver::visit (module);
130 13838 : }
131 :
132 : void
133 19343 : TopLevel::visit (AST::Trait &trait)
134 : {
135 19343 : insert_or_error_out (trait.get_identifier (), trait, Namespace::Types);
136 :
137 19343 : DefaultResolver::visit (trait);
138 19343 : }
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 266741 : TopLevel::maybe_insert_big_self (AST::Impl &impl)
153 : {
154 533482 : insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()),
155 266741 : impl.get_type (), Namespace::Types);
156 266741 : }
157 :
158 : void
159 4385 : TopLevel::visit (AST::TraitItemType &trait_item)
160 : {
161 13155 : insert_or_error_out (trait_item.get_identifier ().as_string (), trait_item,
162 : Namespace::Types);
163 :
164 4385 : DefaultResolver::visit (trait_item);
165 4385 : }
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 31125 : is_macro_export (AST::MacroRulesDefinition &def)
222 : {
223 75027 : for (const auto &attr : def.get_outer_attrs ())
224 45237 : if (attr.get_path ().as_string () == Values::Attributes::MACRO_EXPORT)
225 31125 : return true;
226 :
227 : return false;
228 : }
229 :
230 : void
231 31125 : 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 31125 : if (is_macro_export (macro))
239 : {
240 4005 : auto res = ctx.macros.insert_at_root (macro.get_rule_name (),
241 1335 : macro.get_node_id ());
242 1335 : 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 1335 : }
253 :
254 31125 : if (macro.get_kind () == AST::MacroRulesDefinition::MacroKind::DeclMacro)
255 882 : insert_or_error_out (macro.get_rule_name (), macro, Namespace::Macros);
256 :
257 31125 : auto &mappings = Analysis::Mappings::get ();
258 31125 : if (mappings.lookup_macro_def (macro.get_node_id ()))
259 : return;
260 :
261 1819 : mappings.insert_macro_def (¯o);
262 : }
263 :
264 : void
265 505162 : TopLevel::visit (AST::Function &function)
266 : {
267 505162 : insert_or_error_out (function.get_function_name (), function,
268 : Namespace::Values);
269 :
270 505162 : Analysis::Mappings::get ().add_function_node (function.get_node_id ());
271 :
272 505162 : DefaultResolver::visit (function);
273 505162 : }
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 27318 : TopLevel::visit (AST::StructStruct &struct_item)
295 : {
296 27318 : DefaultResolver::visit (struct_item);
297 :
298 27318 : 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 27318 : if (struct_item.is_unit_struct ())
305 15202 : insert_or_error_out (struct_item.get_struct_name (), struct_item,
306 : Namespace::Values);
307 27318 : }
308 :
309 : void
310 305245 : TopLevel::visit (AST::TypeParam &type_param)
311 : {
312 305245 : insert_or_error_out (type_param.get_type_representation (), type_param,
313 : Namespace::Types);
314 :
315 305245 : DefaultResolver::visit (type_param);
316 305245 : }
317 :
318 : void
319 3099 : TopLevel::visit (AST::ConstGenericParam &const_param)
320 : {
321 3099 : insert_or_error_out (const_param.get_name (), const_param, Namespace::Values);
322 :
323 3099 : DefaultResolver::visit (const_param);
324 3099 : }
325 :
326 : void
327 6958 : TopLevel::visit (AST::TupleStruct &tuple_struct)
328 : {
329 6958 : insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
330 : Namespace::Types);
331 :
332 6958 : insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
333 : Namespace::Values);
334 :
335 6958 : DefaultResolver::visit (tuple_struct);
336 6958 : }
337 :
338 : void
339 3851 : TopLevel::visit (AST::EnumItem &variant)
340 : {
341 3851 : insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
342 :
343 3851 : DefaultResolver::visit (variant);
344 3851 : }
345 :
346 : void
347 2832 : TopLevel::visit (AST::EnumItemTuple &variant)
348 : {
349 2832 : insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
350 :
351 2832 : DefaultResolver::visit (variant);
352 2832 : }
353 :
354 : void
355 328 : TopLevel::visit (AST::EnumItemStruct &variant)
356 : {
357 328 : insert_enum_variant_or_error_out (variant.get_identifier (), variant, false);
358 :
359 328 : DefaultResolver::visit (variant);
360 328 : }
361 :
362 : void
363 1115 : TopLevel::visit (AST::EnumItemDiscriminant &variant)
364 : {
365 1115 : insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
366 :
367 1115 : DefaultResolver::visit (variant);
368 1115 : }
369 :
370 : void
371 3243 : TopLevel::visit (AST::Enum &enum_item)
372 : {
373 3243 : insert_or_error_out (enum_item.get_identifier (), enum_item,
374 : Namespace::Types);
375 :
376 3243 : 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 6486 : if (Analysis::Mappings::get ().lookup_glob_container (
381 3243 : enum_item.get_node_id ())
382 3243 : == tl::nullopt)
383 651 : Analysis::Mappings::get ().insert_glob_container (enum_item.get_node_id (),
384 : &enum_item);
385 3243 : }
386 :
387 : void
388 421 : TopLevel::visit (AST::Union &union_item)
389 : {
390 421 : insert_or_error_out (union_item.get_identifier (), union_item,
391 : Namespace::Types);
392 :
393 421 : DefaultResolver::visit (union_item);
394 421 : }
395 :
396 : void
397 27062 : TopLevel::visit (AST::ConstantItem &const_item)
398 : {
399 27062 : if (const_item.get_identifier ().as_string () != Values::Keywords::UNDERSCORE)
400 27044 : insert_or_error_out (const_item.get_identifier (), const_item,
401 : Namespace::Values);
402 :
403 27062 : DefaultResolver::visit (const_item);
404 27062 : }
405 :
406 : void
407 94962 : TopLevel::visit (AST::TypeAlias &type_item)
408 : {
409 94962 : insert_or_error_out (type_item.get_new_type_name (), type_item,
410 : Namespace::Types);
411 :
412 94962 : DefaultResolver::visit (type_item);
413 94962 : }
414 :
415 : void
416 48 : TopLevel::visit (AST::ExternalTypeItem &type_item)
417 : {
418 48 : insert_or_error_out (type_item.get_identifier (), type_item,
419 : Namespace::Types);
420 :
421 48 : DefaultResolver::visit (type_item);
422 48 : }
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 59807 : 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 59807 : switch (tree->get_kind ())
445 : {
446 45944 : case AST::UseTree::Rebind:
447 45944 : {
448 45944 : auto rebind = static_cast<const AST::UseTreeRebind *> (tree);
449 45944 : flatten_rebind (*rebind, rebind_paths);
450 45944 : break;
451 : }
452 9651 : case AST::UseTree::List:
453 9651 : {
454 9651 : auto list = static_cast<const AST::UseTreeList *> (tree);
455 9651 : flatten_list (*list, paths, glob_paths, rebind_paths, ctx);
456 9651 : break;
457 : }
458 4212 : case AST::UseTree::Glob:
459 4212 : {
460 4212 : auto glob = static_cast<const AST::UseTreeGlob *> (tree);
461 4212 : flatten_glob (*glob, glob_paths, ctx);
462 4212 : break;
463 : }
464 : }
465 59807 : }
466 :
467 : static void
468 45944 : flatten_rebind (
469 : const AST::UseTreeRebind &rebind,
470 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths)
471 : {
472 45944 : rebind_paths.emplace_back (rebind.get_path (), rebind);
473 45944 : }
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 60772 : prefix_subpaths (AST::SimplePath prefix, std::vector<AST::SimplePath> subs,
482 : std::vector<AST::SimplePath> &results)
483 : {
484 63817 : for (auto &sub : subs)
485 : {
486 3045 : auto new_path = prefix;
487 3045 : std::copy (sub.get_segments ().begin (), sub.get_segments ().end (),
488 : std::back_inserter (new_path.get_segments ()));
489 3045 : results.emplace_back (new_path);
490 3045 : }
491 60772 : }
492 :
493 : static void
494 30386 : 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 59059 : for (auto &sub : subs)
500 : {
501 28673 : auto new_path = prefix;
502 28673 : std::copy (sub.first.get_segments ().begin (),
503 28673 : sub.first.get_segments ().end (),
504 : std::back_inserter (new_path.get_segments ()));
505 57346 : results.emplace_back (std::make_pair (new_path, sub.second));
506 28673 : }
507 30386 : }
508 :
509 : static void
510 9651 : 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 9651 : auto prefix = AST::SimplePath::create_empty ();
517 9651 : if (list.has_path ())
518 9647 : prefix = list.get_path ();
519 :
520 40037 : for (const auto &tree : list.get_trees ())
521 : {
522 30386 : auto sub_paths = std::vector<AST::SimplePath> ();
523 30386 : auto sub_globs = std::vector<AST::SimplePath> ();
524 30386 : auto sub_rebinds
525 : = std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> ();
526 30386 : flatten (tree.get (), sub_paths, sub_globs, sub_rebinds, ctx);
527 :
528 30386 : prefix_subpaths (prefix, sub_paths, paths);
529 30386 : prefix_subpaths (prefix, sub_globs, glob_paths);
530 30386 : prefix_rebinds (prefix, sub_rebinds, rebind_paths);
531 30386 : }
532 9651 : }
533 :
534 : static void
535 4212 : flatten_glob (const AST::UseTreeGlob &glob, std::vector<AST::SimplePath> &paths,
536 : NameResolutionContext &ctx)
537 : {
538 4212 : if (glob.has_path ())
539 4198 : paths.emplace_back (glob.get_path ());
540 : else
541 14 : paths.emplace_back (AST::SimplePath (
542 14 : {}, glob.get_glob_type () == AST::UseTreeGlob::PathType::GLOBAL,
543 28 : glob.get_locus ()));
544 4212 : }
545 :
546 : static bool
547 4212 : has_prelude_import (const std::vector<AST::Attribute> &attributes)
548 : {
549 4379 : for (const auto &attr : attributes)
550 206 : if (attr.get_path ().as_string () == "prelude_import")
551 4212 : return true;
552 :
553 : return false;
554 : }
555 :
556 : void
557 29421 : TopLevel::visit (AST::UseDeclaration &use)
558 : {
559 29421 : auto paths = std::vector<AST::SimplePath> ();
560 29421 : auto glob_path = std::vector<AST::SimplePath> ();
561 29421 : auto rebind_path
562 : = std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> ();
563 :
564 29421 : auto &values_rib = ctx.values.peek ();
565 29421 : auto &types_rib = ctx.types.peek ();
566 29421 : 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 29421 : const auto &tree = use.get_tree ();
573 29421 : flatten (tree.get (), paths, glob_path, rebind_path, this->ctx);
574 :
575 29421 : auto imports = std::vector<ImportKind> ();
576 :
577 29421 : for (auto &&path : paths)
578 0 : imports.emplace_back (
579 0 : ImportKind::Simple (std::move (path), values_rib, types_rib, macros_rib));
580 :
581 33633 : for (auto &&glob : glob_path)
582 8424 : imports.emplace_back (
583 4212 : ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib,
584 4212 : has_prelude_import (use.get_outer_attrs ())));
585 :
586 75365 : for (auto &&rebind : rebind_path)
587 45944 : imports.emplace_back (
588 91888 : ImportKind::Rebind (std::move (rebind.first), std::move (rebind.second),
589 : values_rib, types_rib, macros_rib));
590 :
591 29421 : imports_to_resolve.insert ({use.get_node_id (), std::move (imports)});
592 29421 : }
593 :
594 : } // namespace Resolver2_0
595 : } // namespace Rust
|