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 11342 : Early::Early (NameResolutionContext &ctx)
39 11342 : : DefaultResolver (ctx), toplevel (TopLevel (ctx)), dirty (false)
40 11342 : {}
41 :
42 : void
43 61411 : Early::try_insert_once (AST::MacroInvocation &invocation, NodeId resolved)
44 : {
45 61411 : 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 61411 : if (!leaf_macro)
49 61411 : 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 28915 : Early::insert_once (AST::MacroRulesDefinition &def)
61 : {
62 28915 : if (!ctx.mappings.lookup_macro_def (def.get_node_id ()))
63 1 : ctx.mappings.insert_macro_def (&def);
64 28915 : }
65 :
66 : void
67 11342 : Early::go (AST::Crate &crate)
68 : {
69 : // First we go through TopLevel resolution to get all our declared items
70 11342 : toplevel.go (crate);
71 :
72 : // We start with resolving the list of imports that `TopLevel` has built for
73 : // us
74 :
75 11342 : dirty = toplevel.is_dirty ();
76 :
77 : // We now proceed with resolving macros, which can be nested in almost any
78 : // items
79 11342 : textual_scope.push ();
80 :
81 11342 : visit (crate);
82 :
83 11342 : textual_scope.pop ();
84 :
85 : // handle IdentifierPattern vs PathInExpression disambiguation
86 11342 : IdentifierPathPass::go (crate, ctx, std::move (ident_path_to_convert));
87 11342 : }
88 :
89 : bool
90 3826 : Early::resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&glob)
91 : {
92 3826 : auto resolved = ctx.resolve_path (glob.to_resolve, Namespace::Types);
93 3826 : if (!resolved.has_value ())
94 : return false;
95 :
96 7648 : auto result = Analysis::Mappings::get ().lookup_glob_container (
97 3824 : resolved->definition.get_node_id ());
98 :
99 3824 : if (!result)
100 : return false;
101 :
102 3824 : 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 7648 : imports.emplace_back (
110 11472 : ImportPair (std::move (glob), ImportData::Glob (resolved->definition)));
111 :
112 3824 : return true;
113 3826 : }
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 39823 : Early::resolve_rebind_import (NodeId use_dec_id,
135 : TopLevel::ImportKind &&rebind_import)
136 : {
137 39823 : NodeId import_id = UNKNOWN_NODEID;
138 39823 : auto &path = rebind_import.to_resolve;
139 39823 : auto &rebind = rebind_import.rebind.value ();
140 :
141 39823 : 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 39251 : case AST::UseTreeRebind::NewBindType::NONE:
147 39251 : import_id = path.get_final_segment ().get_node_id ();
148 39251 : break;
149 : case AST::UseTreeRebind::NewBindType::WILDCARD:
150 : // nothing
151 : break;
152 : }
153 :
154 39823 : if (ctx.lookup (import_id, Namespace::Types))
155 : return true;
156 :
157 7812 : 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 7812 : if (definitions.empty ())
161 : return false;
162 15311 : for (const auto &def : definitions)
163 : {
164 7796 : 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 7515 : auto &imports = import_mappings.new_or_access (use_dec_id);
175 :
176 7515 : imports.emplace_back (
177 7515 : ImportPair (std::move (rebind_import),
178 15030 : ImportData::Rebind (std::move (definitions))));
179 :
180 7515 : return true;
181 7812 : }
182 :
183 : void
184 25564 : Early::build_import_mapping (
185 : std::pair<NodeId, std::vector<TopLevel::ImportKind>> &&use_import)
186 : {
187 25564 : auto found = false;
188 25564 : auto use_dec_id = use_import.first;
189 :
190 69213 : 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 43649 : auto path = import.to_resolve;
195 :
196 : // used to skip the "unresolved import" error
197 : // if we output other errors during resolution
198 43649 : size_t old_error_count = macro_resolve_errors.size ();
199 :
200 43649 : switch (import.kind)
201 : {
202 3826 : case TopLevel::ImportKind::Kind::Glob:
203 3826 : found = resolve_glob_import (use_dec_id, std::move (import));
204 3826 : break;
205 0 : case TopLevel::ImportKind::Kind::Simple:
206 0 : found = resolve_simple_import (use_dec_id, std::move (import));
207 0 : break;
208 39823 : case TopLevel::ImportKind::Kind::Rebind:
209 39823 : found = resolve_rebind_import (use_dec_id, std::move (import));
210 39823 : break;
211 : }
212 :
213 43649 : if (!found && old_error_count == macro_resolve_errors.size ())
214 592 : collect_error (Error (path.get_final_segment ().get_locus (),
215 : ErrorCode::E0433, "unresolved import %qs",
216 592 : path.as_string ().c_str ()));
217 43649 : }
218 25564 : }
219 :
220 : void
221 634590 : Early::TextualScope::push ()
222 : {
223 : // push a new empty scope
224 634590 : scopes.emplace_back ();
225 634590 : }
226 :
227 : void
228 634590 : Early::TextualScope::pop ()
229 : {
230 634590 : rust_assert (!scopes.empty ());
231 :
232 634590 : scopes.pop_back ();
233 634590 : }
234 :
235 : void
236 28915 : Early::TextualScope::insert (std::string name, NodeId id)
237 : {
238 28915 : 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 57830 : scopes.back ().insert ({name, id});
244 28915 : }
245 :
246 : tl::optional<NodeId>
247 61296 : Early::TextualScope::get (const std::string &name)
248 : {
249 82785 : for (auto iterator = scopes.rbegin (); iterator != scopes.rend (); iterator++)
250 : {
251 77061 : auto scope = *iterator;
252 77061 : auto found = scope.find (name);
253 77061 : if (found != scope.end ())
254 55572 : return found->second;
255 77061 : }
256 :
257 5724 : return tl::nullopt;
258 : }
259 :
260 : void
261 28915 : Early::visit (AST::MacroRulesDefinition &def)
262 : {
263 28915 : DefaultResolver::visit (def);
264 :
265 57830 : textual_scope.insert (def.get_rule_name ().as_string (), def.get_node_id ());
266 28915 : insert_once (def);
267 28915 : }
268 :
269 : void
270 612089 : Early::visit (AST::BlockExpr &block)
271 : {
272 612089 : textual_scope.push ();
273 :
274 612089 : DefaultResolver::visit (block);
275 :
276 612089 : textual_scope.pop ();
277 612089 : }
278 :
279 : void
280 11506 : Early::visit (AST::Module &module)
281 : {
282 11506 : bool is_macro_use = false;
283 :
284 14514 : for (const auto &attr : module.get_outer_attrs ())
285 : {
286 3355 : if (attr.get_path ().as_string () == Values::Attributes::MACRO_USE)
287 : {
288 : is_macro_use = true;
289 : break;
290 : }
291 : }
292 :
293 11506 : if (!is_macro_use)
294 11159 : textual_scope.push ();
295 :
296 11506 : DefaultResolver::visit (module);
297 :
298 11506 : if (!is_macro_use)
299 11159 : textual_scope.pop ();
300 11506 : }
301 :
302 : void
303 22848 : Early::maybe_prelude_import ()
304 : {
305 : // handle prelude import
306 22848 : 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 22848 : }
317 :
318 : void
319 61534 : Early::visit (AST::MacroInvocation &invoc)
320 : {
321 61534 : 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 61534 : auto resolve_offset_of = Session::get_instance ().should_support_offset_of ()
326 61534 : && (path.as_string () == "offset_of");
327 :
328 : // Ditto, but for `cfg_select!()`.
329 61534 : auto resolve_cfg_select
330 61534 : = Session::get_instance ().should_support_cfg_select ()
331 61534 : && (path.as_string () == "cfg_select");
332 :
333 61534 : 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 61534 : tl::optional<NameResolutionContext::NamespacedDefinition> ns_def
346 : = tl::nullopt;
347 61534 : if (path.get_segments ().size () == 1)
348 61296 : ns_def = textual_scope.get (path.get_final_segment ().as_string ())
349 122592 : .map ([] (NodeId id) {
350 55572 : return NameResolutionContext::NamespacedDefinition (
351 55572 : Rib::Definition::NonShadowable (id), Namespace::Macros);
352 61296 : });
353 :
354 : // we won't have changed `definition` from `nullopt` if there are more
355 : // than one segments in our path
356 61534 : if (!ns_def.has_value ())
357 11801 : 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 61534 : 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 61411 : 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 61411 : auto &mappings = Analysis::Mappings::get ();
375 61411 : auto rules_def
376 61411 : = mappings.lookup_macro_def (ns_def->definition.get_node_id ());
377 :
378 : // Macro definition not found, maybe it is not expanded yet.
379 61411 : if (!rules_def)
380 : return;
381 :
382 61411 : if (mappings.lookup_macro_invocation (invoc))
383 : return;
384 :
385 61411 : mappings.insert_macro_invocation (invoc, rules_def.value ());
386 61534 : }
387 :
388 : void
389 405 : Early::visit_derive_attribute (AST::Attribute &attr,
390 : Analysis::Mappings &mappings)
391 : {
392 405 : auto traits = attr.get_traits_to_derive ();
393 1470 : for (auto &trait : traits)
394 : {
395 1065 : auto ns_def = ctx.resolve_path (trait.get (), Namespace::Macros);
396 1065 : if (!ns_def.has_value ())
397 : {
398 : // FIXME: Change to proper error message
399 754 : collect_error (Error (trait.get ().get_locus (),
400 : "could not resolve trait %qs",
401 377 : trait.get ().as_string ().c_str ()));
402 377 : continue;
403 : }
404 :
405 688 : auto pm_def = mappings.lookup_derive_proc_macro_def (
406 688 : ns_def->definition.get_node_id ());
407 :
408 688 : if (pm_def.has_value ())
409 0 : mappings.insert_derive_proc_macro_invocation (trait, pm_def.value ());
410 1065 : }
411 405 : }
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 2542703 : Early::visit (AST::Attribute &attr)
439 : {
440 2542703 : auto &mappings = Analysis::Mappings::get ();
441 :
442 2542703 : auto name = attr.get_path ().get_segments ().at (0).get_segment_name ();
443 2542703 : 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 2542703 : if (known_check == Analysis::Attributes::AttributeKnowledge::Tool)
448 0 : return;
449 :
450 2542703 : auto is_builtin
451 : = known_check == Analysis::Attributes::AttributeKnowledge::Known;
452 :
453 2542703 : if (attr.is_derive ())
454 : {
455 405 : visit_derive_attribute (attr, mappings);
456 : }
457 2542298 : else if (!is_builtin) // Do not resolve builtins
458 : {
459 2 : visit_non_builtin_attribute (attr, mappings, name);
460 : }
461 :
462 2542703 : DefaultResolver::visit (attr);
463 2542703 : }
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 3824 : Early::finalize_glob_import (NameResolutionContext &ctx,
491 : const Early::ImportPair &mapping)
492 : {
493 7648 : auto container = Analysis::Mappings::get ().lookup_glob_container (
494 7648 : mapping.data.container ().get_node_id ());
495 :
496 3824 : rust_assert (container);
497 :
498 3824 : 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 3824 : GlobbingVisitor glob_visit (ctx);
511 3824 : glob_visit.go (container.value ());
512 3824 : dirty |= glob_visit.is_dirty ();
513 3824 : }
514 :
515 : void
516 7515 : 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 7515 : auto &path = mapping.import_kind.to_resolve;
521 7515 : auto &rebind = mapping.import_kind.rebind.value ();
522 7515 : auto data = mapping.data;
523 :
524 7515 : NodeId import_id = UNKNOWN_NODEID;
525 7515 : std::string declared_name;
526 :
527 : // FIXME: This needs to be done in `FinalizeImports`
528 7515 : switch (rebind.get_new_bind_type ())
529 : {
530 393 : case AST::UseTreeRebind::NewBindType::IDENTIFIER:
531 393 : declared_name = rebind.get_identifier ().as_string ();
532 393 : import_id = rebind.get_node_id ();
533 393 : break;
534 7118 : case AST::UseTreeRebind::NewBindType::NONE:
535 7118 : {
536 7118 : const auto &segments = path.get_segments ();
537 : // We don't want to insert `self` with `use module::self`
538 7118 : if (path.get_final_segment ().is_lower_self_seg ())
539 : {
540 : // Erroneous `self` or `{self}` use declaration
541 102 : if (segments.size () == 1)
542 : return;
543 99 : declared_name = segments[segments.size () - 2].as_string ();
544 99 : import_id = segments[segments.size () - 2].get_node_id ();
545 : }
546 : else
547 : {
548 7016 : declared_name = path.get_final_segment ().as_string ();
549 7016 : import_id = path.get_final_segment ().get_node_id ();
550 : }
551 : break;
552 : }
553 : case AST::UseTreeRebind::NewBindType::WILDCARD:
554 : // We don't want to insert it into the trie
555 : return;
556 : }
557 :
558 15296 : for (auto &&definition : data.definitions ())
559 : {
560 7788 : ctx.map_usage (Usage (import_id),
561 7788 : Definition (definition.definition.get_node_id ()),
562 : definition.ns);
563 :
564 23364 : toplevel.insert_or_error_out (declared_name, path.get_locus (),
565 7788 : definition.definition.get_node_id (),
566 : definition.ns);
567 :
568 7788 : dirty = dirty || toplevel.is_dirty ();
569 :
570 : // Map the import to the glob container if it exists - this is important
571 : // for 2-stepped glob imports which refer to glob containers, e.g.
572 : //
573 : // enum Foo { ... }
574 : // pub use Foo;
575 : // use self::Foo::*;
576 7788 : auto &mappings = Analysis::Mappings::get ();
577 7788 : if (auto container = mappings.lookup_glob_container (
578 7788 : definition.definition.get_node_id ()))
579 549 : mappings.insert_glob_container (import_id, container.value ());
580 7508 : }
581 15030 : }
582 :
583 : void
584 25564 : Early::visit (AST::UseDeclaration &decl)
585 : {
586 : // We do not want to visit the use trees, we're only looking for top level
587 : // rebind. eg. `use something;` or `use something::other;`
588 25564 : if (decl.get_tree ()->get_kind () == AST::UseTree::Kind::Rebind)
589 : {
590 15743 : auto &rebind = static_cast<AST::UseTreeRebind &> (*decl.get_tree ());
591 15743 : if (rebind.get_path ().get_final_segment ().is_lower_self_seg ())
592 : {
593 2 : collect_error (
594 1 : Error (decl.get_locus (), ErrorCode::E0429,
595 1 : "%<self%> imports are only allowed within a { } list"));
596 : }
597 : }
598 :
599 25564 : auto &imports = toplevel.get_imports_to_resolve ();
600 25564 : auto current_import = imports.find (decl.get_node_id ());
601 25564 : if (current_import != imports.end ())
602 : {
603 25564 : build_import_mapping (*current_import);
604 : }
605 :
606 : // Once this is done, we finalize their resolution
607 36903 : for (const auto &mapping : import_mappings.get (decl.get_node_id ()))
608 11339 : switch (mapping.import_kind.kind)
609 : {
610 3824 : case TopLevel::ImportKind::Kind::Glob:
611 3824 : finalize_glob_import (ctx, mapping);
612 3824 : break;
613 0 : case TopLevel::ImportKind::Kind::Simple:
614 0 : finalize_simple_import (mapping);
615 0 : break;
616 7515 : case TopLevel::ImportKind::Kind::Rebind:
617 7515 : finalize_rebind_import (mapping);
618 7515 : break;
619 : }
620 :
621 25564 : DefaultResolver::visit (decl);
622 25564 : }
623 :
624 : void
625 7508 : Early::visit (AST::UseTreeList &use_list)
626 : {
627 7508 : if (!use_list.has_path ())
628 : {
629 10 : for (auto &&tree : use_list.get_trees ())
630 : {
631 6 : if (tree->get_kind () == AST::UseTree::Kind::Rebind)
632 : {
633 6 : auto &rebind = static_cast<AST::UseTreeRebind &> (*tree);
634 6 : auto path_size = rebind.get_path ().get_segments ().size ();
635 6 : if (path_size == 1
636 6 : && rebind.get_path ()
637 6 : .get_final_segment ()
638 6 : .is_lower_self_seg ())
639 : {
640 4 : collect_error (Error (rebind.get_locus (), ErrorCode::E0431,
641 : "%<self%> import can only appear in an "
642 4 : "import list with a non-empty prefix"));
643 : }
644 : }
645 : }
646 : }
647 7508 : DefaultResolver::visit (use_list);
648 7508 : }
649 :
650 : void
651 736801 : Early::visit (AST::IdentifierPattern &identifier)
652 : {
653 : // check if this is *really* a path pattern
654 736801 : if (!identifier.get_is_ref () && !identifier.get_is_mut ()
655 1440689 : && !identifier.has_subpattern ())
656 : {
657 703321 : auto res = ctx.values.get (identifier.get_ident ());
658 703321 : if (res)
659 : {
660 945 : if (res->is_ambiguous ())
661 0 : rust_error_at (identifier.get_locus (), ErrorCode::E0659,
662 : "%qs is ambiguous",
663 0 : identifier.get_ident ().as_string ().c_str ());
664 : else
665 : {
666 : // HACK: bail out if the definition is a function
667 945 : if (!ctx.mappings.is_function_node (res->get_node_id ()))
668 514 : ident_path_to_convert.insert (identifier.get_node_id ());
669 : }
670 : }
671 703321 : }
672 736801 : }
673 :
674 : } // namespace Resolver2_0
675 : } // namespace Rust
|