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 16571 : TopLevel::TopLevel (NameResolutionContext &resolver)
30 16571 : : DefaultResolver (resolver), dirty (false)
31 16571 : {}
32 :
33 : template <typename T>
34 : void
35 8234 : TopLevel::insert_enum_variant_or_error_out (const Identifier &identifier,
36 : const T &node, bool is_also_value)
37 : {
38 8234 : insert_enum_variant_or_error_out (identifier, node.get_locus (),
39 8234 : node.get_node_id (), is_also_value);
40 8234 : }
41 :
42 : void
43 1321711 : 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 1321711 : if (result)
48 94051 : dirty = true;
49 1227660 : 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 1321711 : }
68 : void
69 8234 : 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 8234 : node_locations.emplace (node_id, locus);
76 :
77 8234 : auto result = ctx.insert_variant (identifier, node_id, is_also_value);
78 14929 : check_multiple_insertion_error (result, identifier, locus, node_id);
79 8234 : }
80 :
81 : template <typename T>
82 : void
83 1304508 : TopLevel::insert_or_error_out (const Identifier &identifier, const T &node,
84 : Namespace ns)
85 : {
86 1304508 : insert_or_error_out (identifier, node.get_locus (), node.get_node_id (), ns);
87 1304508 : }
88 :
89 : void
90 1313477 : 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 1313477 : node_locations.emplace (node_id, locus);
96 :
97 1313477 : auto result = ctx.insert (identifier, node_id, ns);
98 2534442 : check_multiple_insertion_error (result, identifier, locus, node_id);
99 1313477 : }
100 :
101 : void
102 16571 : 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 16571 : visit (crate);
110 :
111 16571 : if (Analysis::Mappings::get ().lookup_glob_container (crate.get_node_id ())
112 16571 : == tl::nullopt)
113 5098 : Analysis::Mappings::get ().insert_glob_container (crate.get_node_id (),
114 : &crate);
115 16571 : }
116 :
117 : void
118 13844 : TopLevel::visit (AST::Module &module)
119 : {
120 13844 : if (Analysis::Mappings::get ().lookup_glob_container (module.get_node_id ())
121 13844 : == tl::nullopt)
122 1732 : Analysis::Mappings::get ().insert_glob_container (module.get_node_id (),
123 : &module);
124 :
125 13844 : insert_or_error_out (module.get_name (), module, Namespace::Types);
126 :
127 13844 : Analysis::Mappings::get ().insert_module_id (module.get_node_id ());
128 :
129 13844 : DefaultResolver::visit (module);
130 13844 : }
131 :
132 : void
133 19586 : TopLevel::visit (AST::Trait &trait)
134 : {
135 19586 : insert_or_error_out (trait.get_identifier (), trait, Namespace::Types);
136 :
137 19586 : DefaultResolver::visit (trait);
138 19586 : }
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 266834 : TopLevel::maybe_insert_big_self (AST::Impl &impl)
153 : {
154 533668 : insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()),
155 266834 : impl.get_type (), Namespace::Types);
156 266834 : }
157 :
158 : void
159 4449 : TopLevel::visit (AST::TraitItemType &trait_item)
160 : {
161 13347 : insert_or_error_out (trait_item.get_identifier ().as_string (), trait_item,
162 : Namespace::Types);
163 :
164 4449 : DefaultResolver::visit (trait_item);
165 4449 : }
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.crate.attributes.lookup (num);
191 :
192 171 : auto bang_macros = mappings.crate.bangs.lookup (num);
193 :
194 171 : auto derive_macros = mappings.crate.derives.lookup (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.pmacro.definitions.derives.insert (macro.get_node_id (),
202 : macro);
203 : }
204 171 : if (attribute_macros.has_value ())
205 : {
206 168 : insert_macros (attribute_macros.value (), ctx);
207 168 : for (auto ¯o : attribute_macros.value ())
208 0 : mappings.pmacro.definitions.attributes.insert (macro.get_node_id (),
209 : macro);
210 : }
211 171 : if (bang_macros.has_value ())
212 : {
213 168 : insert_macros (bang_macros.value (), ctx);
214 168 : for (auto ¯o : bang_macros.value ())
215 0 : mappings.pmacro.definitions.bangs.insert (macro.get_node_id (), macro);
216 : }
217 :
218 : // We do *NOT* visit the crate because loaded crates are resolved
219 : // independently.
220 171 : }
221 :
222 : static bool
223 31105 : is_macro_export (AST::MacroRulesDefinition &def)
224 : {
225 74989 : for (const auto &attr : def.get_outer_attrs ())
226 45222 : if (attr.get_path ().as_string () == Values::Attributes::MACRO_EXPORT)
227 31105 : return true;
228 :
229 : return false;
230 : }
231 :
232 : void
233 31105 : TopLevel::visit (AST::MacroRulesDefinition ¯o)
234 : {
235 : // we do not insert macros in the current rib as that needs to be done in the
236 : // textual scope of the Early pass. we only insert them in the root of the
237 : // crate if they are marked with #[macro_export]. The execption to this is
238 : // macros 2.0, which get resolved and inserted like regular items.
239 :
240 31105 : if (is_macro_export (macro))
241 : {
242 4014 : auto res = ctx.macros.insert_at_root (macro.get_rule_name (),
243 1338 : macro.get_node_id ());
244 1338 : if (!res && res.error ().existing != macro.get_node_id ())
245 : {
246 : // TODO: Factor this
247 0 : rich_location rich_loc (line_table, macro.get_locus ());
248 0 : rich_loc.add_range (node_locations[res.error ().existing]);
249 :
250 0 : rust_error_at (rich_loc, ErrorCode::E0428,
251 : "macro %qs defined multiple times",
252 0 : macro.get_rule_name ().as_string ().c_str ());
253 0 : }
254 1338 : }
255 :
256 31105 : if (macro.get_kind () == AST::MacroRulesDefinition::MacroKind::DeclMacro)
257 882 : insert_or_error_out (macro.get_rule_name (), macro, Namespace::Macros);
258 :
259 31105 : auto &mappings = Analysis::Mappings::get ();
260 31105 : if (mappings.lookup_macro_def (macro.get_node_id ()))
261 : return;
262 :
263 1815 : mappings.insert_macro_def (¯o);
264 : }
265 :
266 : void
267 505760 : TopLevel::visit (AST::Function &function)
268 : {
269 505760 : insert_or_error_out (function.get_function_name (), function,
270 : Namespace::Values);
271 :
272 505760 : Analysis::Mappings::get ().add_function_node (function.get_node_id ());
273 :
274 505760 : DefaultResolver::visit (function);
275 505760 : }
276 :
277 : void
278 1542 : TopLevel::visit (AST::StaticItem &static_item)
279 : {
280 1542 : insert_or_error_out (static_item.get_identifier (), static_item,
281 : Namespace::Values);
282 :
283 1542 : DefaultResolver::visit (static_item);
284 1542 : }
285 :
286 : void
287 3 : TopLevel::visit (AST::ExternalStaticItem &static_item)
288 : {
289 9 : insert_or_error_out (static_item.get_identifier ().as_string (), static_item,
290 : Namespace::Values);
291 :
292 3 : DefaultResolver::visit (static_item);
293 3 : }
294 :
295 : void
296 27443 : TopLevel::visit (AST::StructStruct &struct_item)
297 : {
298 27443 : DefaultResolver::visit (struct_item);
299 :
300 27443 : insert_or_error_out (struct_item.get_struct_name (), struct_item,
301 : Namespace::Types);
302 :
303 : // Do we need to insert the constructor in the value namespace as well?
304 :
305 : // Do we need to do anything if the struct is a unit struct?
306 27443 : if (struct_item.is_unit_struct ())
307 15226 : insert_or_error_out (struct_item.get_struct_name (), struct_item,
308 : Namespace::Values);
309 27443 : }
310 :
311 : void
312 305758 : TopLevel::visit (AST::TypeParam &type_param)
313 : {
314 305758 : insert_or_error_out (type_param.get_type_representation (), type_param,
315 : Namespace::Types);
316 :
317 305758 : DefaultResolver::visit (type_param);
318 305758 : }
319 :
320 : void
321 3105 : TopLevel::visit (AST::ConstGenericParam &const_param)
322 : {
323 3105 : insert_or_error_out (const_param.get_name (), const_param, Namespace::Values);
324 :
325 3105 : DefaultResolver::visit (const_param);
326 3105 : }
327 :
328 : void
329 7020 : TopLevel::visit (AST::TupleStruct &tuple_struct)
330 : {
331 7020 : insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
332 : Namespace::Types);
333 :
334 7020 : insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
335 : Namespace::Values);
336 :
337 7020 : DefaultResolver::visit (tuple_struct);
338 7020 : }
339 :
340 : void
341 3890 : TopLevel::visit (AST::EnumItem &variant)
342 : {
343 3890 : insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
344 :
345 3890 : DefaultResolver::visit (variant);
346 3890 : }
347 :
348 : void
349 2901 : TopLevel::visit (AST::EnumItemTuple &variant)
350 : {
351 2901 : insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
352 :
353 2901 : DefaultResolver::visit (variant);
354 2901 : }
355 :
356 : void
357 328 : TopLevel::visit (AST::EnumItemStruct &variant)
358 : {
359 328 : insert_enum_variant_or_error_out (variant.get_identifier (), variant, false);
360 :
361 328 : DefaultResolver::visit (variant);
362 328 : }
363 :
364 : void
365 1115 : TopLevel::visit (AST::EnumItemDiscriminant &variant)
366 : {
367 1115 : insert_enum_variant_or_error_out (variant.get_identifier (), variant, true);
368 :
369 1115 : DefaultResolver::visit (variant);
370 1115 : }
371 :
372 : void
373 3285 : TopLevel::visit (AST::Enum &enum_item)
374 : {
375 3285 : insert_or_error_out (enum_item.get_identifier (), enum_item,
376 : Namespace::Types);
377 :
378 3285 : DefaultResolver::visit (enum_item);
379 :
380 : // Since enums can be containers for imports, we need to insert them like we
381 : // do for modules
382 6570 : if (Analysis::Mappings::get ().lookup_glob_container (
383 3285 : enum_item.get_node_id ())
384 3285 : == tl::nullopt)
385 665 : Analysis::Mappings::get ().insert_glob_container (enum_item.get_node_id (),
386 : &enum_item);
387 3285 : }
388 :
389 : void
390 421 : TopLevel::visit (AST::Union &union_item)
391 : {
392 421 : insert_or_error_out (union_item.get_identifier (), union_item,
393 : Namespace::Types);
394 :
395 421 : DefaultResolver::visit (union_item);
396 421 : }
397 :
398 : void
399 27110 : TopLevel::visit (AST::ConstantItem &const_item)
400 : {
401 27110 : if (const_item.get_identifier ().as_string () != Values::Keywords::UNDERSCORE)
402 27089 : insert_or_error_out (const_item.get_identifier (), const_item,
403 : Namespace::Values);
404 :
405 27110 : DefaultResolver::visit (const_item);
406 27110 : }
407 :
408 : void
409 95013 : TopLevel::visit (AST::TypeAlias &type_item)
410 : {
411 95013 : insert_or_error_out (type_item.get_new_type_name (), type_item,
412 : Namespace::Types);
413 :
414 95013 : DefaultResolver::visit (type_item);
415 95013 : }
416 :
417 : void
418 6 : TopLevel::visit (AST::TraitAlias &trait_item)
419 : {
420 6 : insert_or_error_out (trait_item.get_alias_name (), trait_item,
421 : Namespace::Types);
422 :
423 6 : DefaultResolver::visit (trait_item);
424 6 : }
425 :
426 : void
427 48 : TopLevel::visit (AST::ExternalTypeItem &type_item)
428 : {
429 48 : insert_or_error_out (type_item.get_identifier (), type_item,
430 : Namespace::Types);
431 :
432 48 : DefaultResolver::visit (type_item);
433 48 : }
434 :
435 : static void flatten_rebind (
436 : const AST::UseTreeRebind &glob,
437 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths);
438 :
439 : static void flatten_list (
440 : const AST::UseTreeList &glob, std::vector<AST::SimplePath> &paths,
441 : std::vector<AST::SimplePath> &glob_paths,
442 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
443 : NameResolutionContext &ctx);
444 : static void flatten_glob (const AST::UseTreeGlob &glob,
445 : std::vector<AST::SimplePath> &glob_paths,
446 : NameResolutionContext &ctx);
447 :
448 : static void
449 59807 : flatten (
450 : const AST::UseTree *tree, std::vector<AST::SimplePath> &paths,
451 : std::vector<AST::SimplePath> &glob_paths,
452 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
453 : NameResolutionContext &ctx)
454 : {
455 59807 : switch (tree->get_kind ())
456 : {
457 45944 : case AST::UseTree::Rebind:
458 45944 : {
459 45944 : auto rebind = static_cast<const AST::UseTreeRebind *> (tree);
460 45944 : flatten_rebind (*rebind, rebind_paths);
461 45944 : break;
462 : }
463 9651 : case AST::UseTree::List:
464 9651 : {
465 9651 : auto list = static_cast<const AST::UseTreeList *> (tree);
466 9651 : flatten_list (*list, paths, glob_paths, rebind_paths, ctx);
467 9651 : break;
468 : }
469 4212 : case AST::UseTree::Glob:
470 4212 : {
471 4212 : auto glob = static_cast<const AST::UseTreeGlob *> (tree);
472 4212 : flatten_glob (*glob, glob_paths, ctx);
473 4212 : break;
474 : }
475 : }
476 59807 : }
477 :
478 : static void
479 45944 : flatten_rebind (
480 : const AST::UseTreeRebind &rebind,
481 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths)
482 : {
483 45944 : rebind_paths.emplace_back (rebind.get_path (), rebind);
484 45944 : }
485 :
486 : /** Prefix a list of subpath
487 : * @param prefix A prefix for all subpath
488 : * @param subs List of subpath to prefix
489 : * @param size List where results should be stored
490 : */
491 : static void
492 60772 : prefix_subpaths (AST::SimplePath prefix, std::vector<AST::SimplePath> subs,
493 : std::vector<AST::SimplePath> &results)
494 : {
495 63817 : for (auto &sub : subs)
496 : {
497 3045 : auto new_path = prefix;
498 3045 : std::copy (sub.get_segments ().begin (), sub.get_segments ().end (),
499 : std::back_inserter (new_path.get_segments ()));
500 3045 : results.emplace_back (new_path);
501 3045 : }
502 60772 : }
503 :
504 : static void
505 30386 : prefix_rebinds (
506 : AST::SimplePath prefix,
507 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> subs,
508 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &results)
509 : {
510 59059 : for (auto &sub : subs)
511 : {
512 28673 : auto new_path = prefix;
513 28673 : std::copy (sub.first.get_segments ().begin (),
514 28673 : sub.first.get_segments ().end (),
515 : std::back_inserter (new_path.get_segments ()));
516 57346 : results.emplace_back (std::make_pair (new_path, sub.second));
517 28673 : }
518 30386 : }
519 :
520 : static void
521 9651 : flatten_list (
522 : const AST::UseTreeList &list, std::vector<AST::SimplePath> &paths,
523 : std::vector<AST::SimplePath> &glob_paths,
524 : std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> &rebind_paths,
525 : NameResolutionContext &ctx)
526 : {
527 9651 : auto prefix = AST::SimplePath::create_empty ();
528 9651 : if (list.has_path ())
529 9647 : prefix = list.get_path ();
530 :
531 40037 : for (const auto &tree : list.get_trees ())
532 : {
533 30386 : auto sub_paths = std::vector<AST::SimplePath> ();
534 30386 : auto sub_globs = std::vector<AST::SimplePath> ();
535 30386 : auto sub_rebinds
536 : = std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> ();
537 30386 : flatten (tree.get (), sub_paths, sub_globs, sub_rebinds, ctx);
538 :
539 30386 : prefix_subpaths (prefix, sub_paths, paths);
540 30386 : prefix_subpaths (prefix, sub_globs, glob_paths);
541 30386 : prefix_rebinds (prefix, sub_rebinds, rebind_paths);
542 30386 : }
543 9651 : }
544 :
545 : static void
546 4212 : flatten_glob (const AST::UseTreeGlob &glob, std::vector<AST::SimplePath> &paths,
547 : NameResolutionContext &ctx)
548 : {
549 4212 : if (glob.has_path ())
550 4198 : paths.emplace_back (glob.get_path ());
551 : else
552 14 : paths.emplace_back (AST::SimplePath (
553 14 : {}, glob.get_glob_type () == AST::UseTreeGlob::PathType::GLOBAL,
554 28 : glob.get_locus ()));
555 4212 : }
556 :
557 : static bool
558 4212 : has_prelude_import (const std::vector<AST::Attribute> &attributes)
559 : {
560 4379 : for (const auto &attr : attributes)
561 206 : if (attr.get_path ().as_string () == "prelude_import")
562 4212 : return true;
563 :
564 : return false;
565 : }
566 :
567 : void
568 29421 : TopLevel::visit (AST::UseDeclaration &use)
569 : {
570 29421 : auto paths = std::vector<AST::SimplePath> ();
571 29421 : auto glob_path = std::vector<AST::SimplePath> ();
572 29421 : auto rebind_path
573 : = std::vector<std::pair<AST::SimplePath, AST::UseTreeRebind>> ();
574 :
575 29421 : auto &values_rib = ctx.values.peek ();
576 29421 : auto &types_rib = ctx.types.peek ();
577 29421 : auto ¯os_rib = ctx.macros.peek ();
578 :
579 : // FIXME: How do we handle `use foo::{self}` imports? Some beforehand cleanup?
580 : // How do we handle module imports in general? Should they get added to all
581 : // namespaces?
582 :
583 29421 : const auto &tree = use.get_tree ();
584 29421 : flatten (tree.get (), paths, glob_path, rebind_path, this->ctx);
585 :
586 29421 : auto imports = std::vector<ImportKind> ();
587 :
588 29421 : for (auto &&path : paths)
589 0 : imports.emplace_back (
590 0 : ImportKind::Simple (std::move (path), values_rib, types_rib, macros_rib));
591 :
592 33633 : for (auto &&glob : glob_path)
593 8424 : imports.emplace_back (
594 4212 : ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib,
595 4212 : has_prelude_import (use.get_outer_attrs ())));
596 :
597 75365 : for (auto &&rebind : rebind_path)
598 45944 : imports.emplace_back (
599 91888 : ImportKind::Rebind (std::move (rebind.first), std::move (rebind.second),
600 : values_rib, types_rib, macros_rib));
601 :
602 29421 : imports_to_resolve.insert ({use.get_node_id (), std::move (imports)});
603 29421 : }
604 :
605 : } // namespace Resolver2_0
606 : } // namespace Rust
|