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-early-name-resolver-2.0.h"
20 : #include "optional.h"
21 : #include "options.h"
22 : #include "rust-ast.h"
23 : #include "rust-diagnostics.h"
24 : #include "rust-hir-map.h"
25 : #include "rust-item.h"
26 : #include "rust-name-resolution-context.h"
27 : #include "rust-rib.h"
28 : #include "rust-toplevel-name-resolver-2.0.h"
29 : #include "rust-attributes.h"
30 : #include "rust-finalize-imports-2.0.h"
31 : #include "rust-attribute-values.h"
32 : #include "rust-identifier-path.h"
33 : #include "rust-session-manager.h"
34 :
35 : namespace Rust {
36 : namespace Resolver2_0 {
37 :
38 11200 : Early::Early (NameResolutionContext &ctx)
39 11200 : : DefaultResolver (ctx), toplevel (TopLevel (ctx)), dirty (false)
40 11200 : {}
41 :
42 : void
43 91069 : Early::try_insert_once (AST::MacroInvocation &invocation, NodeId resolved)
44 : {
45 91069 : auto leaf_macro = ctx.macros.find_leaf_definition (resolved);
46 :
47 : // Sometimes the import itself isn't resolved yet this turn of the fixed-point
48 91069 : if (!leaf_macro)
49 91069 : return;
50 :
51 : // TODO: Should we use `ctx.map_usage()`?
52 :
53 0 : auto definition = ctx.mappings.lookup_macro_def (leaf_macro->id);
54 :
55 0 : if (!ctx.mappings.lookup_macro_invocation (invocation))
56 0 : ctx.mappings.insert_macro_invocation (invocation, definition.value ());
57 : }
58 :
59 : void
60 28897 : Early::insert_once (AST::MacroRulesDefinition &def)
61 : {
62 28897 : if (!ctx.mappings.lookup_macro_def (def.get_node_id ()))
63 1 : ctx.mappings.insert_macro_def (&def);
64 28897 : }
65 :
66 : void
67 11200 : Early::go (AST::Crate &crate)
68 : {
69 : // First we go through TopLevel resolution to get all our declared items
70 11200 : toplevel.go (crate);
71 :
72 : // We start with resolving the list of imports that `TopLevel` has built for
73 : // us
74 :
75 11200 : dirty = toplevel.is_dirty ();
76 :
77 : // We now proceed with resolving macros, which can be nested in almost any
78 : // items
79 11200 : textual_scope.push ();
80 :
81 11200 : visit (crate);
82 :
83 11200 : textual_scope.pop ();
84 :
85 : // handle IdentifierPattern vs PathInExpression disambiguation
86 11200 : IdentifierPathPass::go (crate, ctx, std::move (ident_path_to_convert));
87 11200 : }
88 :
89 : bool
90 3822 : Early::resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&glob)
91 : {
92 3822 : auto resolved = ctx.resolve_path (glob.to_resolve, Namespace::Types);
93 3822 : if (!resolved.has_value ())
94 : return false;
95 :
96 7640 : auto result = Analysis::Mappings::get ().lookup_glob_container (
97 3820 : resolved->definition.get_node_id ());
98 :
99 3820 : if (!result)
100 : return false;
101 :
102 3820 : auto &imports = import_mappings.new_or_access (use_dec_id);
103 :
104 : // here, we insert the module's NodeId into the import_mappings and will look
105 : // up the module proper in `FinalizeImports`
106 : // The namespace does not matter here since we are dealing with a glob
107 : // FIXME: Does the namespace not matter? Is that valid?
108 : // TODO: Ugly
109 7640 : imports.emplace_back (
110 11460 : ImportPair (std::move (glob), ImportData::Glob (resolved->definition)));
111 :
112 3820 : return true;
113 3822 : }
114 :
115 : bool
116 0 : Early::resolve_simple_import (NodeId use_dec_id, TopLevel::ImportKind &&import)
117 : {
118 0 : auto definitions = resolve_path_in_all_ns (import.to_resolve);
119 :
120 : // if we've found at least one definition, then we're good
121 0 : if (definitions.empty ())
122 : return false;
123 :
124 0 : auto &imports = import_mappings.new_or_access (use_dec_id);
125 :
126 0 : imports.emplace_back (
127 0 : ImportPair (std::move (import),
128 0 : ImportData::Simple (std::move (definitions))));
129 :
130 0 : return true;
131 0 : }
132 :
133 : bool
134 39809 : Early::resolve_rebind_import (NodeId use_dec_id,
135 : TopLevel::ImportKind &&rebind_import)
136 : {
137 39809 : NodeId import_id = UNKNOWN_NODEID;
138 39809 : auto &path = rebind_import.to_resolve;
139 39809 : auto &rebind = rebind_import.rebind.value ();
140 :
141 39809 : switch (rebind.get_new_bind_type ())
142 : {
143 568 : case AST::UseTreeRebind::NewBindType::IDENTIFIER:
144 568 : import_id = rebind.get_node_id ();
145 568 : break;
146 39237 : case AST::UseTreeRebind::NewBindType::NONE:
147 39237 : {
148 39237 : const auto &segments = path.get_segments ();
149 : // We don't want to insert `self` with `use module::self`
150 39237 : if (path.get_final_segment ().is_lower_self_seg ())
151 : {
152 : // Erroneous `self` or `{self}` use declaration
153 1646 : if (segments.size () == 1)
154 : break;
155 1641 : import_id = segments[segments.size () - 2].get_node_id ();
156 : }
157 : else
158 : {
159 37591 : import_id = path.get_final_segment ().get_node_id ();
160 : }
161 : break;
162 : }
163 : case AST::UseTreeRebind::NewBindType::WILDCARD:
164 : // nothing
165 : break;
166 : }
167 :
168 39809 : if (ctx.lookup (import_id, Namespace::Types))
169 : return true;
170 :
171 7806 : auto definitions = resolve_path_in_all_ns (rebind_import.to_resolve);
172 :
173 : // if we've found at least one definition, then we're good
174 7806 : if (definitions.empty ())
175 : return false;
176 15297 : for (const auto &def : definitions)
177 : {
178 7788 : if (def.definition.is_ambiguous ())
179 : {
180 1 : rich_location rich_locus (line_table,
181 1 : rebind_import.to_resolve.get_locus ());
182 1 : rust_error_at (rich_locus, ErrorCode::E0659, "%qs is ambiguous",
183 1 : rebind_import.to_resolve.as_string ().c_str ());
184 1 : return true;
185 1 : }
186 : }
187 :
188 7509 : auto &imports = import_mappings.new_or_access (use_dec_id);
189 :
190 7509 : imports.emplace_back (
191 7509 : ImportPair (std::move (rebind_import),
192 15018 : ImportData::Rebind (std::move (definitions))));
193 :
194 7509 : return true;
195 7806 : }
196 :
197 : void
198 25556 : Early::build_import_mapping (
199 : std::pair<NodeId, std::vector<TopLevel::ImportKind>> &&use_import)
200 : {
201 25556 : auto found = false;
202 25556 : auto use_dec_id = use_import.first;
203 :
204 69187 : for (auto &&import : use_import.second)
205 : {
206 : // We create a copy of the path in case of errors, since the `import` will
207 : // be moved into the newly created import mappings
208 43631 : auto path = import.to_resolve;
209 :
210 : // used to skip the "unresolved import" error
211 : // if we output other errors during resolution
212 43631 : size_t old_error_count = macro_resolve_errors.size ();
213 :
214 43631 : switch (import.kind)
215 : {
216 3822 : case TopLevel::ImportKind::Kind::Glob:
217 3822 : found = resolve_glob_import (use_dec_id, std::move (import));
218 3822 : break;
219 0 : case TopLevel::ImportKind::Kind::Simple:
220 0 : found = resolve_simple_import (use_dec_id, std::move (import));
221 0 : break;
222 39809 : case TopLevel::ImportKind::Kind::Rebind:
223 39809 : found = resolve_rebind_import (use_dec_id, std::move (import));
224 39809 : break;
225 : }
226 :
227 43631 : if (!found && old_error_count == macro_resolve_errors.size ())
228 592 : collect_error (Error (path.get_final_segment ().get_locus (),
229 : ErrorCode::E0433, "unresolved import %qs",
230 592 : path.as_string ().c_str ()));
231 43631 : }
232 25556 : }
233 :
234 : void
235 634059 : Early::TextualScope::push ()
236 : {
237 : // push a new empty scope
238 634059 : scopes.emplace_back ();
239 634059 : }
240 :
241 : void
242 634059 : Early::TextualScope::pop ()
243 : {
244 634059 : rust_assert (!scopes.empty ());
245 :
246 634059 : scopes.pop_back ();
247 634059 : }
248 :
249 : void
250 28897 : Early::TextualScope::insert (std::string name, NodeId id)
251 : {
252 28897 : rust_assert (!scopes.empty ());
253 :
254 : // we can ignore the return value as we always want the latest defined macro
255 : // to shadow a previous one - so if two macros have the same name and get
256 : // inserted with the same key, it's not a bug
257 57794 : scopes.back ().insert ({name, id});
258 28897 : }
259 :
260 : tl::optional<NodeId>
261 90954 : Early::TextualScope::get (const std::string &name)
262 : {
263 146685 : for (auto iterator = scopes.rbegin (); iterator != scopes.rend (); iterator++)
264 : {
265 111285 : auto scope = *iterator;
266 111285 : auto found = scope.find (name);
267 111285 : if (found != scope.end ())
268 55554 : return found->second;
269 111285 : }
270 :
271 35400 : return tl::nullopt;
272 : }
273 :
274 : void
275 28897 : Early::visit (AST::MacroRulesDefinition &def)
276 : {
277 28897 : DefaultResolver::visit (def);
278 :
279 57794 : textual_scope.insert (def.get_rule_name ().as_string (), def.get_node_id ());
280 28897 : insert_once (def);
281 28897 : }
282 :
283 : void
284 611720 : Early::visit (AST::BlockExpr &block)
285 : {
286 611720 : textual_scope.push ();
287 :
288 611720 : DefaultResolver::visit (block);
289 :
290 611720 : textual_scope.pop ();
291 611720 : }
292 :
293 : void
294 11486 : Early::visit (AST::Module &module)
295 : {
296 11486 : bool is_macro_use = false;
297 :
298 14494 : for (const auto &attr : module.get_outer_attrs ())
299 : {
300 3355 : if (attr.get_path ().as_string () == Values::Attributes::MACRO_USE)
301 : {
302 : is_macro_use = true;
303 : break;
304 : }
305 : }
306 :
307 11486 : if (!is_macro_use)
308 11139 : textual_scope.push ();
309 :
310 11486 : DefaultResolver::visit (module);
311 :
312 11486 : if (!is_macro_use)
313 11139 : textual_scope.pop ();
314 11486 : }
315 :
316 : void
317 22686 : Early::maybe_prelude_import ()
318 : {
319 : // handle prelude import
320 22686 : if (ctx.prelude)
321 : {
322 16596 : auto container = Analysis::Mappings::get ().lookup_glob_container (
323 8298 : ctx.prelude.value ());
324 8298 : rust_assert (container);
325 :
326 8298 : GlobbingVisitor glob_visit (ctx);
327 8298 : glob_visit.go (container.value ());
328 8298 : dirty |= glob_visit.is_dirty ();
329 : }
330 22686 : }
331 :
332 : void
333 91192 : Early::visit (AST::MacroInvocation &invoc)
334 : {
335 91192 : auto &path = invoc.get_invoc_data ().get_path ();
336 :
337 : // We special case the `offset_of!()` macro if the flag is here, otherwise
338 : // we accept whatever `offset_of!()` definition we resolved to.
339 91192 : auto resolve_offset_of = Session::get_instance ().should_support_offset_of ()
340 91192 : && (path.as_string () == "offset_of");
341 :
342 : // Ditto, but for `cfg_select!()`.
343 91192 : auto resolve_cfg_select
344 91192 : = Session::get_instance ().should_support_cfg_select ()
345 91192 : && (path.as_string () == "cfg_select");
346 :
347 91192 : if (invoc.get_kind () == AST::MacroInvocation::InvocKind::Builtin)
348 1074 : for (auto &pending_invoc : invoc.get_pending_eager_invocations ())
349 728 : pending_invoc->accept_vis (*this);
350 :
351 : // When a macro is invoked by an unqualified identifier (not part of a
352 : // multi-part path), it is first looked up in textual scoping. If this does
353 : // not yield any results, then it is looked up in path-based scoping. If the
354 : // macro's name is qualified with a path, then it is only looked up in
355 : // path-based scoping.
356 :
357 : // https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope
358 :
359 91192 : tl::optional<NameResolutionContext::NamespacedDefinition> ns_def
360 : = tl::nullopt;
361 91192 : if (path.get_segments ().size () == 1)
362 90954 : ns_def = textual_scope.get (path.get_final_segment ().as_string ())
363 181908 : .map ([] (NodeId id) {
364 55554 : return NameResolutionContext::NamespacedDefinition (
365 55554 : Rib::Definition::NonShadowable (id), Namespace::Macros);
366 90954 : });
367 :
368 : // we won't have changed `definition` from `nullopt` if there are more
369 : // than one segments in our path
370 91192 : if (!ns_def.has_value ())
371 71153 : ns_def = ctx.resolve_path (path, Namespace::Macros);
372 :
373 : // if the definition still does not have a value, then it's an error - unless
374 : // we should automatically resolve offset_of!() or cfg_select!() calls
375 91192 : if (!ns_def.has_value ())
376 : {
377 123 : if (!resolve_offset_of && !resolve_cfg_select)
378 76 : collect_error (Error (invoc.get_locus (), ErrorCode::E0433,
379 : "could not resolve macro invocation %qs",
380 152 : path.as_string ().c_str ()));
381 : return;
382 : }
383 :
384 91069 : try_insert_once (invoc, ns_def->definition.get_node_id ());
385 :
386 : // now do we need to keep mappings or something? or insert "uses" into our
387 : // ForeverStack? can we do that? are mappings simpler?
388 91069 : auto &mappings = Analysis::Mappings::get ();
389 91069 : auto rules_def
390 91069 : = mappings.lookup_macro_def (ns_def->definition.get_node_id ());
391 :
392 : // Macro definition not found, maybe it is not expanded yet.
393 91069 : if (!rules_def)
394 : return;
395 :
396 91069 : if (mappings.lookup_macro_invocation (invoc))
397 : return;
398 :
399 58237 : mappings.insert_macro_invocation (invoc, rules_def.value ());
400 91192 : }
401 :
402 : void
403 404 : Early::visit_derive_attribute (AST::Attribute &attr,
404 : Analysis::Mappings &mappings)
405 : {
406 404 : auto traits = attr.get_traits_to_derive ();
407 1468 : for (auto &trait : traits)
408 : {
409 1064 : auto ns_def = ctx.resolve_path (trait.get (), Namespace::Macros);
410 1064 : if (!ns_def.has_value ())
411 : {
412 : // FIXME: Change to proper error message
413 752 : collect_error (Error (trait.get ().get_locus (),
414 : "could not resolve trait %qs",
415 376 : trait.get ().as_string ().c_str ()));
416 376 : continue;
417 : }
418 :
419 688 : auto pm_def = mappings.lookup_derive_proc_macro_def (
420 688 : ns_def->definition.get_node_id ());
421 :
422 688 : if (pm_def.has_value ())
423 0 : mappings.insert_derive_proc_macro_invocation (trait, pm_def.value ());
424 1064 : }
425 404 : }
426 :
427 : void
428 1 : Early::visit_non_builtin_attribute (AST::Attribute &attr,
429 : Analysis::Mappings &mappings,
430 : std::string &name)
431 : {
432 1 : auto ns_def = ctx.resolve_path (attr.get_path (), Namespace::Macros);
433 1 : if (!ns_def.has_value ())
434 : {
435 : // FIXME: Change to proper error message
436 0 : collect_error (Error (attr.get_locus (),
437 : "could not resolve attribute macro invocation %qs",
438 0 : name.c_str ()));
439 0 : return;
440 : }
441 1 : auto pm_def = mappings.lookup_attribute_proc_macro_def (
442 1 : ns_def->definition.get_node_id ());
443 :
444 1 : if (!pm_def.has_value ())
445 : return;
446 :
447 0 : mappings.insert_attribute_proc_macro_invocation (attr.get_path (),
448 0 : pm_def.value ());
449 1 : }
450 :
451 : void
452 2542204 : Early::visit (AST::Attribute &attr)
453 : {
454 2542204 : auto &mappings = Analysis::Mappings::get ();
455 :
456 2542204 : auto name = attr.get_path ().get_segments ().at (0).get_segment_name ();
457 5084004 : auto is_not_builtin = [&name] (AST::Attribute &attr) {
458 2541800 : return Analysis::BuiltinAttributeMappings::get ()
459 2541800 : ->lookup_builtin (name)
460 2541800 : .is_error ();
461 2542204 : };
462 :
463 2542204 : if (attr.is_derive ())
464 : {
465 404 : visit_derive_attribute (attr, mappings);
466 : }
467 2541800 : else if (is_not_builtin (attr)) // Do not resolve builtins
468 : {
469 1 : visit_non_builtin_attribute (attr, mappings, name);
470 : }
471 :
472 2542204 : DefaultResolver::visit (attr);
473 2542204 : }
474 :
475 : void
476 0 : Early::finalize_simple_import (const Early::ImportPair &mapping)
477 : {
478 : // FIXME: We probably need to store namespace information
479 :
480 0 : auto import = mapping.import_kind.to_resolve;
481 0 : auto import_id = import.get_final_segment ().get_node_id ();
482 0 : auto data = mapping.data;
483 0 : auto identifier = import.get_final_segment ().get_segment_name ();
484 :
485 0 : for (auto &&definition : data.definitions ())
486 : {
487 0 : ctx.map_usage (Usage (import_id),
488 0 : Definition (definition.definition.get_node_id ()),
489 : definition.ns);
490 :
491 0 : toplevel.insert_or_error_out (identifier, import.get_locus (),
492 0 : definition.definition.get_node_id (),
493 : definition.ns);
494 :
495 0 : dirty = dirty || toplevel.is_dirty ();
496 0 : }
497 0 : }
498 :
499 : void
500 3820 : Early::finalize_glob_import (NameResolutionContext &ctx,
501 : const Early::ImportPair &mapping)
502 : {
503 7640 : auto container = Analysis::Mappings::get ().lookup_glob_container (
504 7640 : mapping.data.container ().get_node_id ());
505 :
506 3820 : rust_assert (container);
507 :
508 3820 : if (mapping.import_kind.is_prelude)
509 : {
510 37 : rust_assert (container.value ()->get_glob_container_kind ()
511 : == AST::GlobContainer::Kind::Module);
512 :
513 : // TODO: catch multiple attempted prelude imports
514 37 : if (!ctx.prelude)
515 2 : dirty = true;
516 :
517 37 : ctx.prelude = mapping.data.container ().get_node_id ();
518 : }
519 :
520 3820 : GlobbingVisitor glob_visit (ctx);
521 3820 : glob_visit.go (container.value ());
522 3820 : dirty |= glob_visit.is_dirty ();
523 3820 : }
524 :
525 : void
526 7509 : Early::finalize_rebind_import (const Early::ImportPair &mapping)
527 : {
528 : // We can fetch the value here as `resolve_rebind` will only be called on
529 : // imports of the right kind
530 7509 : auto &path = mapping.import_kind.to_resolve;
531 7509 : auto &rebind = mapping.import_kind.rebind.value ();
532 7509 : auto data = mapping.data;
533 :
534 7509 : NodeId import_id = UNKNOWN_NODEID;
535 7509 : std::string declared_name;
536 :
537 : // FIXME: This needs to be done in `FinalizeImports`
538 7509 : switch (rebind.get_new_bind_type ())
539 : {
540 393 : case AST::UseTreeRebind::NewBindType::IDENTIFIER:
541 393 : declared_name = rebind.get_identifier ().as_string ();
542 393 : import_id = rebind.get_node_id ();
543 393 : break;
544 7112 : case AST::UseTreeRebind::NewBindType::NONE:
545 7112 : {
546 7112 : const auto &segments = path.get_segments ();
547 : // We don't want to insert `self` with `use module::self`
548 7112 : if (path.get_final_segment ().is_lower_self_seg ())
549 : {
550 : // Erroneous `self` or `{self}` use declaration
551 100 : if (segments.size () == 1)
552 : return;
553 95 : declared_name = segments[segments.size () - 2].as_string ();
554 95 : import_id = segments[segments.size () - 2].get_node_id ();
555 : }
556 : else
557 : {
558 7012 : declared_name = path.get_final_segment ().as_string ();
559 7012 : import_id = path.get_final_segment ().get_node_id ();
560 : }
561 : break;
562 : }
563 : case AST::UseTreeRebind::NewBindType::WILDCARD:
564 : // We don't want to insert it into the trie
565 : return;
566 : }
567 :
568 15278 : for (auto &&definition : data.definitions ())
569 : {
570 7778 : ctx.map_usage (Usage (import_id),
571 7778 : Definition (definition.definition.get_node_id ()),
572 : definition.ns);
573 :
574 23334 : toplevel.insert_or_error_out (declared_name, path.get_locus (),
575 7778 : definition.definition.get_node_id (),
576 : definition.ns);
577 :
578 7778 : dirty = dirty || toplevel.is_dirty ();
579 :
580 : // Map the import to the glob container if it exists - this is important
581 : // for 2-stepped glob imports which refer to glob containers, e.g.
582 : //
583 : // enum Foo { ... }
584 : // pub use Foo;
585 : // use self::Foo::*;
586 7778 : auto &mappings = Analysis::Mappings::get ();
587 7778 : if (auto container = mappings.lookup_glob_container (
588 7778 : definition.definition.get_node_id ()))
589 545 : mappings.insert_glob_container (import_id, container.value ());
590 7500 : }
591 15018 : }
592 :
593 : void
594 25556 : Early::visit (AST::UseDeclaration &decl)
595 : {
596 : // We do not want to visit the use trees, we're only looking for top level
597 : // rebind. eg. `use something;` or `use something::other;`
598 25556 : if (decl.get_tree ()->get_kind () == AST::UseTree::Kind::Rebind)
599 : {
600 15743 : auto &rebind = static_cast<AST::UseTreeRebind &> (*decl.get_tree ());
601 15743 : if (rebind.get_path ().get_final_segment ().is_lower_self_seg ())
602 : {
603 2 : collect_error (
604 1 : Error (decl.get_locus (), ErrorCode::E0429,
605 1 : "%<self%> imports are only allowed within a { } list"));
606 : }
607 : }
608 :
609 25556 : auto &imports = toplevel.get_imports_to_resolve ();
610 25556 : auto current_import = imports.find (decl.get_node_id ());
611 25556 : if (current_import != imports.end ())
612 : {
613 25556 : build_import_mapping (*current_import);
614 : }
615 :
616 : // Once this is done, we finalize their resolution
617 36885 : for (const auto &mapping : import_mappings.get (decl.get_node_id ()))
618 11329 : switch (mapping.import_kind.kind)
619 : {
620 3820 : case TopLevel::ImportKind::Kind::Glob:
621 3820 : finalize_glob_import (ctx, mapping);
622 3820 : break;
623 0 : case TopLevel::ImportKind::Kind::Simple:
624 0 : finalize_simple_import (mapping);
625 0 : break;
626 7509 : case TopLevel::ImportKind::Kind::Rebind:
627 7509 : finalize_rebind_import (mapping);
628 7509 : break;
629 : }
630 :
631 25556 : DefaultResolver::visit (decl);
632 25556 : }
633 :
634 : void
635 7500 : Early::visit (AST::UseTreeList &use_list)
636 : {
637 7500 : if (!use_list.has_path ())
638 : {
639 10 : for (auto &&tree : use_list.get_trees ())
640 : {
641 6 : if (tree->get_kind () == AST::UseTree::Kind::Rebind)
642 : {
643 6 : auto &rebind = static_cast<AST::UseTreeRebind &> (*tree);
644 6 : auto path_size = rebind.get_path ().get_segments ().size ();
645 6 : if (path_size == 1
646 6 : && rebind.get_path ()
647 6 : .get_final_segment ()
648 6 : .is_lower_self_seg ())
649 : {
650 4 : collect_error (Error (rebind.get_locus (), ErrorCode::E0431,
651 : "%<self%> import can only appear in an "
652 4 : "import list with a non-empty prefix"));
653 : }
654 : }
655 : }
656 : }
657 7500 : DefaultResolver::visit (use_list);
658 7500 : }
659 :
660 : void
661 736411 : Early::visit (AST::IdentifierPattern &identifier)
662 : {
663 : // check if this is *really* a path pattern
664 736411 : if (!identifier.get_is_ref () && !identifier.get_is_mut ()
665 1439923 : && !identifier.has_subpattern ())
666 : {
667 702947 : auto res = ctx.values.get (identifier.get_ident ());
668 702947 : if (res)
669 : {
670 943 : if (res->is_ambiguous ())
671 0 : rust_error_at (identifier.get_locus (), ErrorCode::E0659,
672 : "%qs is ambiguous",
673 0 : identifier.get_ident ().as_string ().c_str ());
674 : else
675 : {
676 : // HACK: bail out if the definition is a function
677 943 : if (!ctx.mappings.is_function_node (res->get_node_id ()))
678 514 : ident_path_to_convert.insert (identifier.get_node_id ());
679 : }
680 : }
681 702947 : }
682 736411 : }
683 :
684 : } // namespace Resolver2_0
685 : } // namespace Rust
|