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