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