]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_resolve/src/imports.rs
New upstream version 1.75.0+dfsg1
[rustc.git] / compiler / rustc_resolve / src / imports.rs
1 //! A bunch of methods and structures more or less related to resolving imports.
2
3 use crate::diagnostics::{import_candidates, DiagnosticMode, Suggestion};
4 use crate::errors::{
5 CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate,
6 CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates,
7 ConsiderAddingMacroExport, ConsiderMarkingAsPub, IsNotDirectlyImportable,
8 ItemsInTraitsAreNotImportable,
9 };
10 use crate::Determinacy::{self, *};
11 use crate::{fluent_generated as fluent, Namespace::*};
12 use crate::{module_to_string, names_to_string, ImportSuggestion};
13 use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
14 use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
15 use crate::{NameBinding, NameBindingData, NameBindingKind, PathResult};
16
17 use rustc_ast::NodeId;
18 use rustc_data_structures::fx::FxHashSet;
19 use rustc_data_structures::intern::Interned;
20 use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
21 use rustc_hir::def::{self, DefKind, PartialRes};
22 use rustc_middle::metadata::ModChild;
23 use rustc_middle::metadata::Reexport;
24 use rustc_middle::span_bug;
25 use rustc_middle::ty;
26 use rustc_session::lint::builtin::{
27 AMBIGUOUS_GLOB_REEXPORTS, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE,
28 UNUSED_IMPORTS,
29 };
30 use rustc_session::lint::BuiltinLintDiagnostics;
31 use rustc_span::edit_distance::find_best_match_for_name;
32 use rustc_span::hygiene::LocalExpnId;
33 use rustc_span::symbol::{kw, Ident, Symbol};
34 use rustc_span::Span;
35 use smallvec::SmallVec;
36
37 use std::cell::Cell;
38 use std::mem;
39
40 type Res = def::Res<NodeId>;
41
42 /// Contains data for specific kinds of imports.
43 #[derive(Clone)]
44 pub(crate) enum ImportKind<'a> {
45 Single {
46 /// `source` in `use prefix::source as target`.
47 source: Ident,
48 /// `target` in `use prefix::source as target`.
49 target: Ident,
50 /// Bindings to which `source` refers to.
51 source_bindings: PerNS<Cell<Result<NameBinding<'a>, Determinacy>>>,
52 /// Bindings introduced by `target`.
53 target_bindings: PerNS<Cell<Option<NameBinding<'a>>>>,
54 /// `true` for `...::{self [as target]}` imports, `false` otherwise.
55 type_ns_only: bool,
56 /// Did this import result from a nested import? ie. `use foo::{bar, baz};`
57 nested: bool,
58 /// The ID of the `UseTree` that imported this `Import`.
59 ///
60 /// In the case where the `Import` was expanded from a "nested" use tree,
61 /// this id is the ID of the leaf tree. For example:
62 ///
63 /// ```ignore (pacify the merciless tidy)
64 /// use foo::bar::{a, b}
65 /// ```
66 ///
67 /// If this is the import for `foo::bar::a`, we would have the ID of the `UseTree`
68 /// for `a` in this field.
69 id: NodeId,
70 },
71 Glob {
72 is_prelude: bool,
73 // The visibility of the greatest re-export.
74 // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors.
75 max_vis: Cell<Option<ty::Visibility>>,
76 id: NodeId,
77 },
78 ExternCrate {
79 source: Option<Symbol>,
80 target: Ident,
81 id: NodeId,
82 },
83 MacroUse,
84 MacroExport,
85 }
86
87 /// Manually implement `Debug` for `ImportKind` because the `source/target_bindings`
88 /// contain `Cell`s which can introduce infinite loops while printing.
89 impl<'a> std::fmt::Debug for ImportKind<'a> {
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 use ImportKind::*;
92 match self {
93 Single {
94 ref source,
95 ref target,
96 ref source_bindings,
97 ref target_bindings,
98 ref type_ns_only,
99 ref nested,
100 ref id,
101 } => f
102 .debug_struct("Single")
103 .field("source", source)
104 .field("target", target)
105 // Ignore the nested bindings to avoid an infinite loop while printing.
106 .field(
107 "source_bindings",
108 &source_bindings.clone().map(|b| b.into_inner().map(|_| format_args!(".."))),
109 )
110 .field(
111 "target_bindings",
112 &target_bindings.clone().map(|b| b.into_inner().map(|_| format_args!(".."))),
113 )
114 .field("type_ns_only", type_ns_only)
115 .field("nested", nested)
116 .field("id", id)
117 .finish(),
118 Glob { ref is_prelude, ref max_vis, ref id } => f
119 .debug_struct("Glob")
120 .field("is_prelude", is_prelude)
121 .field("max_vis", max_vis)
122 .field("id", id)
123 .finish(),
124 ExternCrate { ref source, ref target, ref id } => f
125 .debug_struct("ExternCrate")
126 .field("source", source)
127 .field("target", target)
128 .field("id", id)
129 .finish(),
130 MacroUse => f.debug_struct("MacroUse").finish(),
131 MacroExport => f.debug_struct("MacroExport").finish(),
132 }
133 }
134 }
135
136 /// One import.
137 #[derive(Debug, Clone)]
138 pub(crate) struct ImportData<'a> {
139 pub kind: ImportKind<'a>,
140
141 /// Node ID of the "root" use item -- this is always the same as `ImportKind`'s `id`
142 /// (if it exists) except in the case of "nested" use trees, in which case
143 /// it will be the ID of the root use tree. e.g., in the example
144 /// ```ignore (incomplete code)
145 /// use foo::bar::{a, b}
146 /// ```
147 /// this would be the ID of the `use foo::bar` `UseTree` node.
148 /// In case of imports without their own node ID it's the closest node that can be used,
149 /// for example, for reporting lints.
150 pub root_id: NodeId,
151
152 /// Span of the entire use statement.
153 pub use_span: Span,
154
155 /// Span of the entire use statement with attributes.
156 pub use_span_with_attributes: Span,
157
158 /// Did the use statement have any attributes?
159 pub has_attributes: bool,
160
161 /// Span of this use tree.
162 pub span: Span,
163
164 /// Span of the *root* use tree (see `root_id`).
165 pub root_span: Span,
166
167 pub parent_scope: ParentScope<'a>,
168 pub module_path: Vec<Segment>,
169 /// The resolution of `module_path`.
170 pub imported_module: Cell<Option<ModuleOrUniformRoot<'a>>>,
171 pub vis: Cell<Option<ty::Visibility>>,
172 pub used: Cell<bool>,
173 }
174
175 /// All imports are unique and allocated on a same arena,
176 /// so we can use referential equality to compare them.
177 pub(crate) type Import<'a> = Interned<'a, ImportData<'a>>;
178
179 impl<'a> ImportData<'a> {
180 pub(crate) fn is_glob(&self) -> bool {
181 matches!(self.kind, ImportKind::Glob { .. })
182 }
183
184 pub(crate) fn is_nested(&self) -> bool {
185 match self.kind {
186 ImportKind::Single { nested, .. } => nested,
187 _ => false,
188 }
189 }
190
191 pub(crate) fn expect_vis(&self) -> ty::Visibility {
192 self.vis.get().expect("encountered cleared import visibility")
193 }
194
195 pub(crate) fn id(&self) -> Option<NodeId> {
196 match self.kind {
197 ImportKind::Single { id, .. }
198 | ImportKind::Glob { id, .. }
199 | ImportKind::ExternCrate { id, .. } => Some(id),
200 ImportKind::MacroUse | ImportKind::MacroExport => None,
201 }
202 }
203
204 fn simplify(&self, r: &Resolver<'_, '_>) -> Reexport {
205 let to_def_id = |id| r.local_def_id(id).to_def_id();
206 match self.kind {
207 ImportKind::Single { id, .. } => Reexport::Single(to_def_id(id)),
208 ImportKind::Glob { id, .. } => Reexport::Glob(to_def_id(id)),
209 ImportKind::ExternCrate { id, .. } => Reexport::ExternCrate(to_def_id(id)),
210 ImportKind::MacroUse => Reexport::MacroUse,
211 ImportKind::MacroExport => Reexport::MacroExport,
212 }
213 }
214 }
215
216 /// Records information about the resolution of a name in a namespace of a module.
217 #[derive(Clone, Default, Debug)]
218 pub(crate) struct NameResolution<'a> {
219 /// Single imports that may define the name in the namespace.
220 /// Imports are arena-allocated, so it's ok to use pointers as keys.
221 pub single_imports: FxHashSet<Import<'a>>,
222 /// The least shadowable known binding for this name, or None if there are no known bindings.
223 pub binding: Option<NameBinding<'a>>,
224 pub shadowed_glob: Option<NameBinding<'a>>,
225 }
226
227 impl<'a> NameResolution<'a> {
228 /// Returns the binding for the name if it is known or None if it not known.
229 pub(crate) fn binding(&self) -> Option<NameBinding<'a>> {
230 self.binding.and_then(|binding| {
231 if !binding.is_glob_import() || self.single_imports.is_empty() {
232 Some(binding)
233 } else {
234 None
235 }
236 })
237 }
238 }
239
240 /// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved
241 /// import errors within the same use tree into a single diagnostic.
242 #[derive(Debug, Clone)]
243 struct UnresolvedImportError {
244 span: Span,
245 label: Option<String>,
246 note: Option<String>,
247 suggestion: Option<Suggestion>,
248 candidates: Option<Vec<ImportSuggestion>>,
249 }
250
251 // Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;`
252 // are permitted for backward-compatibility under a deprecation lint.
253 fn pub_use_of_private_extern_crate_hack(import: Import<'_>, binding: NameBinding<'_>) -> bool {
254 match (&import.kind, &binding.kind) {
255 (ImportKind::Single { .. }, NameBindingKind::Import { import: binding_import, .. }) => {
256 matches!(binding_import.kind, ImportKind::ExternCrate { .. })
257 && import.expect_vis().is_public()
258 }
259 _ => false,
260 }
261 }
262
263 impl<'a, 'tcx> Resolver<'a, 'tcx> {
264 /// Given a binding and an import that resolves to it,
265 /// return the corresponding binding defined by the import.
266 pub(crate) fn import(&self, binding: NameBinding<'a>, import: Import<'a>) -> NameBinding<'a> {
267 let import_vis = import.expect_vis().to_def_id();
268 let vis = if binding.vis.is_at_least(import_vis, self.tcx)
269 || pub_use_of_private_extern_crate_hack(import, binding)
270 {
271 import_vis
272 } else {
273 binding.vis
274 };
275
276 if let ImportKind::Glob { ref max_vis, .. } = import.kind {
277 if vis == import_vis
278 || max_vis.get().map_or(true, |max_vis| vis.is_at_least(max_vis, self.tcx))
279 {
280 max_vis.set(Some(vis.expect_local()))
281 }
282 }
283
284 self.arenas.alloc_name_binding(NameBindingData {
285 kind: NameBindingKind::Import { binding, import, used: Cell::new(false) },
286 ambiguity: None,
287 warn_ambiguity: false,
288 span: import.span,
289 vis,
290 expansion: import.parent_scope.expansion,
291 })
292 }
293
294 /// Define the name or return the existing binding if there is a collision.
295 /// `update` indicates if the definition is a redefinition of an existing binding.
296 pub(crate) fn try_define(
297 &mut self,
298 module: Module<'a>,
299 key: BindingKey,
300 binding: NameBinding<'a>,
301 warn_ambiguity: bool,
302 ) -> Result<(), NameBinding<'a>> {
303 let res = binding.res();
304 self.check_reserved_macro_name(key.ident, res);
305 self.set_binding_parent_module(binding, module);
306 self.update_resolution(module, key, warn_ambiguity, |this, resolution| {
307 if let Some(old_binding) = resolution.binding {
308 if res == Res::Err && old_binding.res() != Res::Err {
309 // Do not override real bindings with `Res::Err`s from error recovery.
310 return Ok(());
311 }
312 match (old_binding.is_glob_import(), binding.is_glob_import()) {
313 (true, true) => {
314 // FIXME: remove `!binding.is_ambiguity()` after delete the warning ambiguity.
315 if !binding.is_ambiguity()
316 && let NameBindingKind::Import { import: old_import, .. } =
317 old_binding.kind
318 && let NameBindingKind::Import { import, .. } = binding.kind
319 && old_import == import
320 {
321 // We should replace the `old_binding` with `binding` regardless
322 // of whether they has same resolution or not when they are
323 // imported from the same glob-import statement.
324 resolution.binding = Some(binding);
325 } else if res != old_binding.res() {
326 let binding = if warn_ambiguity {
327 this.warn_ambiguity(AmbiguityKind::GlobVsGlob, old_binding, binding)
328 } else {
329 this.ambiguity(AmbiguityKind::GlobVsGlob, old_binding, binding)
330 };
331 resolution.binding = Some(binding);
332 } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
333 // We are glob-importing the same item but with greater visibility.
334 resolution.binding = Some(binding);
335 } else if binding.is_ambiguity() {
336 resolution.binding =
337 Some(self.arenas.alloc_name_binding(NameBindingData {
338 warn_ambiguity: true,
339 ..(*binding).clone()
340 }));
341 }
342 }
343 (old_glob @ true, false) | (old_glob @ false, true) => {
344 let (glob_binding, nonglob_binding) =
345 if old_glob { (old_binding, binding) } else { (binding, old_binding) };
346 if glob_binding.res() != nonglob_binding.res()
347 && key.ns == MacroNS
348 && nonglob_binding.expansion != LocalExpnId::ROOT
349 {
350 resolution.binding = Some(this.ambiguity(
351 AmbiguityKind::GlobVsExpanded,
352 nonglob_binding,
353 glob_binding,
354 ));
355 } else {
356 resolution.binding = Some(nonglob_binding);
357 }
358
359 if let Some(old_binding) = resolution.shadowed_glob {
360 assert!(old_binding.is_glob_import());
361 if glob_binding.res() != old_binding.res() {
362 resolution.shadowed_glob = Some(this.ambiguity(
363 AmbiguityKind::GlobVsGlob,
364 old_binding,
365 glob_binding,
366 ));
367 } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
368 resolution.shadowed_glob = Some(glob_binding);
369 }
370 } else {
371 resolution.shadowed_glob = Some(glob_binding);
372 }
373 }
374 (false, false) => {
375 return Err(old_binding);
376 }
377 }
378 } else {
379 resolution.binding = Some(binding);
380 }
381
382 Ok(())
383 })
384 }
385
386 fn ambiguity(
387 &self,
388 kind: AmbiguityKind,
389 primary_binding: NameBinding<'a>,
390 secondary_binding: NameBinding<'a>,
391 ) -> NameBinding<'a> {
392 self.arenas.alloc_name_binding(NameBindingData {
393 ambiguity: Some((secondary_binding, kind)),
394 ..(*primary_binding).clone()
395 })
396 }
397
398 fn warn_ambiguity(
399 &self,
400 kind: AmbiguityKind,
401 primary_binding: NameBinding<'a>,
402 secondary_binding: NameBinding<'a>,
403 ) -> NameBinding<'a> {
404 self.arenas.alloc_name_binding(NameBindingData {
405 ambiguity: Some((secondary_binding, kind)),
406 warn_ambiguity: true,
407 ..(*primary_binding).clone()
408 })
409 }
410
411 // Use `f` to mutate the resolution of the name in the module.
412 // If the resolution becomes a success, define it in the module's glob importers.
413 fn update_resolution<T, F>(
414 &mut self,
415 module: Module<'a>,
416 key: BindingKey,
417 warn_ambiguity: bool,
418 f: F,
419 ) -> T
420 where
421 F: FnOnce(&mut Resolver<'a, 'tcx>, &mut NameResolution<'a>) -> T,
422 {
423 // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
424 // during which the resolution might end up getting re-defined via a glob cycle.
425 let (binding, t, warn_ambiguity) = {
426 let resolution = &mut *self.resolution(module, key).borrow_mut();
427 let old_binding = resolution.binding();
428
429 let t = f(self, resolution);
430
431 if let Some(binding) = resolution.binding()
432 && old_binding != Some(binding)
433 {
434 (binding, t, warn_ambiguity || old_binding.is_some())
435 } else {
436 return t;
437 }
438 };
439
440 let Ok(glob_importers) = module.glob_importers.try_borrow_mut() else {
441 return t;
442 };
443
444 // Define or update `binding` in `module`s glob importers.
445 for import in glob_importers.iter() {
446 let mut ident = key.ident;
447 let scope = match ident.span.reverse_glob_adjust(module.expansion, import.span) {
448 Some(Some(def)) => self.expn_def_scope(def),
449 Some(None) => import.parent_scope.module,
450 None => continue,
451 };
452 if self.is_accessible_from(binding.vis, scope) {
453 let imported_binding = self.import(binding, *import);
454 let key = BindingKey { ident, ..key };
455 let _ = self.try_define(
456 import.parent_scope.module,
457 key,
458 imported_binding,
459 warn_ambiguity,
460 );
461 }
462 }
463
464 t
465 }
466
467 // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
468 // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
469 fn import_dummy_binding(&mut self, import: Import<'a>, is_indeterminate: bool) {
470 if let ImportKind::Single { target, ref target_bindings, .. } = import.kind {
471 if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().is_none()))
472 {
473 return; // Has resolution, do not create the dummy binding
474 }
475 let dummy_binding = self.dummy_binding;
476 let dummy_binding = self.import(dummy_binding, import);
477 self.per_ns(|this, ns| {
478 let key = BindingKey::new(target, ns);
479 let _ = this.try_define(import.parent_scope.module, key, dummy_binding, false);
480 });
481 self.record_use(target, dummy_binding, false);
482 } else if import.imported_module.get().is_none() {
483 import.used.set(true);
484 if let Some(id) = import.id() {
485 self.used_imports.insert(id);
486 }
487 }
488 }
489
490 // Import resolution
491 //
492 // This is a fixed-point algorithm. We resolve imports until our efforts
493 // are stymied by an unresolved import; then we bail out of the current
494 // module and continue. We terminate successfully once no more imports
495 // remain or unsuccessfully when no forward progress in resolving imports
496 // is made.
497
498 /// Resolves all imports for the crate. This method performs the fixed-
499 /// point iteration.
500 pub(crate) fn resolve_imports(&mut self) {
501 let mut prev_indeterminate_count = usize::MAX;
502 let mut indeterminate_count = self.indeterminate_imports.len() * 3;
503 while indeterminate_count < prev_indeterminate_count {
504 prev_indeterminate_count = indeterminate_count;
505 indeterminate_count = 0;
506 for import in mem::take(&mut self.indeterminate_imports) {
507 let import_indeterminate_count = self.resolve_import(import);
508 indeterminate_count += import_indeterminate_count;
509 match import_indeterminate_count {
510 0 => self.determined_imports.push(import),
511 _ => self.indeterminate_imports.push(import),
512 }
513 }
514 }
515 }
516
517 pub(crate) fn finalize_imports(&mut self) {
518 for module in self.arenas.local_modules().iter() {
519 self.finalize_resolutions_in(*module);
520 }
521
522 let mut seen_spans = FxHashSet::default();
523 let mut errors = vec![];
524 let mut prev_root_id: NodeId = NodeId::from_u32(0);
525 let determined_imports = mem::take(&mut self.determined_imports);
526 let indeterminate_imports = mem::take(&mut self.indeterminate_imports);
527
528 for (is_indeterminate, import) in determined_imports
529 .iter()
530 .map(|i| (false, i))
531 .chain(indeterminate_imports.iter().map(|i| (true, i)))
532 {
533 let unresolved_import_error = self.finalize_import(*import);
534
535 // If this import is unresolved then create a dummy import
536 // resolution for it so that later resolve stages won't complain.
537 self.import_dummy_binding(*import, is_indeterminate);
538
539 if let Some(err) = unresolved_import_error {
540 if let ImportKind::Single { source, ref source_bindings, .. } = import.kind {
541 if source.name == kw::SelfLower {
542 // Silence `unresolved import` error if E0429 is already emitted
543 if let Err(Determined) = source_bindings.value_ns.get() {
544 continue;
545 }
546 }
547 }
548
549 if prev_root_id.as_u32() != 0
550 && prev_root_id.as_u32() != import.root_id.as_u32()
551 && !errors.is_empty()
552 {
553 // In the case of a new import line, throw a diagnostic message
554 // for the previous line.
555 self.throw_unresolved_import_error(errors);
556 errors = vec![];
557 }
558 if seen_spans.insert(err.span) {
559 errors.push((*import, err));
560 prev_root_id = import.root_id;
561 }
562 }
563 }
564
565 if !errors.is_empty() {
566 self.throw_unresolved_import_error(errors);
567 return;
568 }
569
570 for import in &indeterminate_imports {
571 let path = import_path_to_string(
572 &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
573 &import.kind,
574 import.span,
575 );
576 let err = UnresolvedImportError {
577 span: import.span,
578 label: None,
579 note: None,
580 suggestion: None,
581 candidates: None,
582 };
583 // FIXME: there should be a better way of doing this than
584 // formatting this as a string then checking for `::`
585 if path.contains("::") {
586 errors.push((*import, err))
587 }
588 }
589
590 if !errors.is_empty() {
591 self.throw_unresolved_import_error(errors);
592 }
593 }
594
595 pub(crate) fn check_hidden_glob_reexports(
596 &mut self,
597 exported_ambiguities: FxHashSet<NameBinding<'a>>,
598 ) {
599 for module in self.arenas.local_modules().iter() {
600 for (key, resolution) in self.resolutions(*module).borrow().iter() {
601 let resolution = resolution.borrow();
602
603 if let Some(binding) = resolution.binding {
604 if let NameBindingKind::Import { import, .. } = binding.kind
605 && let Some((amb_binding, _)) = binding.ambiguity
606 && binding.res() != Res::Err
607 && exported_ambiguities.contains(&binding)
608 {
609 self.lint_buffer.buffer_lint_with_diagnostic(
610 AMBIGUOUS_GLOB_REEXPORTS,
611 import.root_id,
612 import.root_span,
613 "ambiguous glob re-exports",
614 BuiltinLintDiagnostics::AmbiguousGlobReexports {
615 name: key.ident.to_string(),
616 namespace: key.ns.descr().to_string(),
617 first_reexport_span: import.root_span,
618 duplicate_reexport_span: amb_binding.span,
619 },
620 );
621 }
622
623 if let Some(glob_binding) = resolution.shadowed_glob {
624 let binding_id = match binding.kind {
625 NameBindingKind::Res(res) => {
626 Some(self.def_id_to_node_id[res.def_id().expect_local()])
627 }
628 NameBindingKind::Module(module) => {
629 Some(self.def_id_to_node_id[module.def_id().expect_local()])
630 }
631 NameBindingKind::Import { import, .. } => import.id(),
632 };
633
634 if binding.res() != Res::Err
635 && glob_binding.res() != Res::Err
636 && let NameBindingKind::Import { import: glob_import, .. } =
637 glob_binding.kind
638 && let Some(binding_id) = binding_id
639 && let Some(glob_import_id) = glob_import.id()
640 && let glob_import_def_id = self.local_def_id(glob_import_id)
641 && self.effective_visibilities.is_exported(glob_import_def_id)
642 && glob_binding.vis.is_public()
643 && !binding.vis.is_public()
644 {
645 self.lint_buffer.buffer_lint_with_diagnostic(
646 HIDDEN_GLOB_REEXPORTS,
647 binding_id,
648 binding.span,
649 "private item shadows public glob re-export",
650 BuiltinLintDiagnostics::HiddenGlobReexports {
651 name: key.ident.name.to_string(),
652 namespace: key.ns.descr().to_owned(),
653 glob_reexport_span: glob_binding.span,
654 private_item_span: binding.span,
655 },
656 );
657 }
658 }
659 }
660 }
661 }
662 }
663
664 fn throw_unresolved_import_error(&mut self, errors: Vec<(Import<'_>, UnresolvedImportError)>) {
665 if errors.is_empty() {
666 return;
667 }
668
669 /// Upper limit on the number of `span_label` messages.
670 const MAX_LABEL_COUNT: usize = 10;
671
672 let span = MultiSpan::from_spans(errors.iter().map(|(_, err)| err.span).collect());
673 let paths = errors
674 .iter()
675 .map(|(import, err)| {
676 let path = import_path_to_string(
677 &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
678 &import.kind,
679 err.span,
680 );
681 format!("`{path}`")
682 })
683 .collect::<Vec<_>>();
684 let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),);
685
686 let mut diag = struct_span_err!(self.tcx.sess, span, E0432, "{}", &msg);
687
688 if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() {
689 diag.note(note.clone());
690 }
691
692 for (import, err) in errors.into_iter().take(MAX_LABEL_COUNT) {
693 if let Some(label) = err.label {
694 diag.span_label(err.span, label);
695 }
696
697 if let Some((suggestions, msg, applicability)) = err.suggestion {
698 if suggestions.is_empty() {
699 diag.help(msg);
700 continue;
701 }
702 diag.multipart_suggestion(msg, suggestions, applicability);
703 }
704
705 if let Some(candidates) = &err.candidates {
706 match &import.kind {
707 ImportKind::Single { nested: false, source, target, .. } => import_candidates(
708 self.tcx,
709 &mut diag,
710 Some(err.span),
711 &candidates,
712 DiagnosticMode::Import,
713 (source != target)
714 .then(|| format!(" as {target}"))
715 .as_deref()
716 .unwrap_or(""),
717 ),
718 ImportKind::Single { nested: true, source, target, .. } => {
719 import_candidates(
720 self.tcx,
721 &mut diag,
722 None,
723 &candidates,
724 DiagnosticMode::Normal,
725 (source != target)
726 .then(|| format!(" as {target}"))
727 .as_deref()
728 .unwrap_or(""),
729 );
730 }
731 _ => {}
732 }
733 }
734
735 match &import.kind {
736 ImportKind::Single { source, .. } => {
737 if let Some(ModuleOrUniformRoot::Module(module)) = import.imported_module.get()
738 && let Some(module) = module.opt_def_id()
739 {
740 self.find_cfg_stripped(&mut diag, &source.name, module)
741 }
742 }
743 _ => {}
744 }
745 }
746
747 diag.emit();
748 }
749
750 /// Attempts to resolve the given import, returning:
751 /// - `0` means its resolution is determined.
752 /// - Other values mean that indeterminate exists under certain namespaces.
753 ///
754 /// Meanwhile, if resolve successful, the resolved bindings are written
755 /// into the module.
756 fn resolve_import(&mut self, import: Import<'a>) -> usize {
757 debug!(
758 "(resolving import for module) resolving import `{}::...` in `{}`",
759 Segment::names_to_string(&import.module_path),
760 module_to_string(import.parent_scope.module).unwrap_or_else(|| "???".to_string()),
761 );
762 let module = if let Some(module) = import.imported_module.get() {
763 module
764 } else {
765 // For better failure detection, pretend that the import will
766 // not define any names while resolving its module path.
767 let orig_vis = import.vis.take();
768 let path_res = self.maybe_resolve_path(&import.module_path, None, &import.parent_scope);
769 import.vis.set(orig_vis);
770
771 match path_res {
772 PathResult::Module(module) => module,
773 PathResult::Indeterminate => return 3,
774 PathResult::NonModule(..) | PathResult::Failed { .. } => return 0,
775 }
776 };
777
778 import.imported_module.set(Some(module));
779 let (source, target, source_bindings, target_bindings, type_ns_only) = match import.kind {
780 ImportKind::Single {
781 source,
782 target,
783 ref source_bindings,
784 ref target_bindings,
785 type_ns_only,
786 ..
787 } => (source, target, source_bindings, target_bindings, type_ns_only),
788 ImportKind::Glob { .. } => {
789 self.resolve_glob_import(import);
790 return 0;
791 }
792 _ => unreachable!(),
793 };
794
795 let mut indeterminate_count = 0;
796 self.per_ns(|this, ns| {
797 if !type_ns_only || ns == TypeNS {
798 if let Err(Undetermined) = source_bindings[ns].get() {
799 // For better failure detection, pretend that the import will
800 // not define any names while resolving its module path.
801 let orig_vis = import.vis.take();
802 let binding = this.maybe_resolve_ident_in_module(
803 module,
804 source,
805 ns,
806 &import.parent_scope,
807 );
808 import.vis.set(orig_vis);
809 source_bindings[ns].set(binding);
810 } else {
811 return;
812 };
813
814 let parent = import.parent_scope.module;
815 match source_bindings[ns].get() {
816 Err(Undetermined) => indeterminate_count += 1,
817 // Don't update the resolution, because it was never added.
818 Err(Determined) if target.name == kw::Underscore => {}
819 Ok(binding) if binding.is_importable() => {
820 let imported_binding = this.import(binding, import);
821 target_bindings[ns].set(Some(imported_binding));
822 this.define(parent, target, ns, imported_binding);
823 }
824 source_binding @ (Ok(..) | Err(Determined)) => {
825 if source_binding.is_ok() {
826 this.tcx
827 .sess
828 .create_err(IsNotDirectlyImportable { span: import.span, target })
829 .emit();
830 }
831 let key = BindingKey::new(target, ns);
832 this.update_resolution(parent, key, false, |_, resolution| {
833 resolution.single_imports.remove(&import);
834 });
835 }
836 }
837 }
838 });
839
840 indeterminate_count
841 }
842
843 /// Performs final import resolution, consistency checks and error reporting.
844 ///
845 /// Optionally returns an unresolved import error. This error is buffered and used to
846 /// consolidate multiple unresolved import errors into a single diagnostic.
847 fn finalize_import(&mut self, import: Import<'a>) -> Option<UnresolvedImportError> {
848 let orig_vis = import.vis.take();
849 let ignore_binding = match &import.kind {
850 ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(),
851 _ => None,
852 };
853 let prev_ambiguity_errors_len = self.ambiguity_errors.len();
854 let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span);
855
856 // We'll provide more context to the privacy errors later, up to `len`.
857 let privacy_errors_len = self.privacy_errors.len();
858
859 let path_res = self.resolve_path(
860 &import.module_path,
861 None,
862 &import.parent_scope,
863 Some(finalize),
864 ignore_binding,
865 );
866
867 let no_ambiguity = self.ambiguity_errors.len() == prev_ambiguity_errors_len;
868 import.vis.set(orig_vis);
869 let module = match path_res {
870 PathResult::Module(module) => {
871 // Consistency checks, analogous to `finalize_macro_resolutions`.
872 if let Some(initial_module) = import.imported_module.get() {
873 if module != initial_module && no_ambiguity {
874 span_bug!(import.span, "inconsistent resolution for an import");
875 }
876 } else if self.privacy_errors.is_empty() {
877 self.tcx
878 .sess
879 .create_err(CannotDetermineImportResolution { span: import.span })
880 .emit();
881 }
882
883 module
884 }
885 PathResult::Failed {
886 is_error_from_last_segment: false,
887 span,
888 label,
889 suggestion,
890 module,
891 } => {
892 if no_ambiguity {
893 assert!(import.imported_module.get().is_none());
894 self.report_error(
895 span,
896 ResolutionError::FailedToResolve {
897 last_segment: None,
898 label,
899 suggestion,
900 module,
901 },
902 );
903 }
904 return None;
905 }
906 PathResult::Failed {
907 is_error_from_last_segment: true,
908 span,
909 label,
910 suggestion,
911 ..
912 } => {
913 if no_ambiguity {
914 assert!(import.imported_module.get().is_none());
915 let err = match self.make_path_suggestion(
916 span,
917 import.module_path.clone(),
918 &import.parent_scope,
919 ) {
920 Some((suggestion, note)) => UnresolvedImportError {
921 span,
922 label: None,
923 note,
924 suggestion: Some((
925 vec![(span, Segment::names_to_string(&suggestion))],
926 String::from("a similar path exists"),
927 Applicability::MaybeIncorrect,
928 )),
929 candidates: None,
930 },
931 None => UnresolvedImportError {
932 span,
933 label: Some(label),
934 note: None,
935 suggestion,
936 candidates: None,
937 },
938 };
939 return Some(err);
940 }
941 return None;
942 }
943 PathResult::NonModule(partial_res) => {
944 if no_ambiguity && partial_res.full_res() != Some(Res::Err) {
945 // Check if there are no ambiguities and the result is not dummy.
946 assert!(import.imported_module.get().is_none());
947 }
948 // The error was already reported earlier.
949 return None;
950 }
951 PathResult::Indeterminate => unreachable!(),
952 };
953
954 let (ident, target, source_bindings, target_bindings, type_ns_only, import_id) =
955 match import.kind {
956 ImportKind::Single {
957 source,
958 target,
959 ref source_bindings,
960 ref target_bindings,
961 type_ns_only,
962 id,
963 ..
964 } => (source, target, source_bindings, target_bindings, type_ns_only, id),
965 ImportKind::Glob { is_prelude, ref max_vis, id } => {
966 if import.module_path.len() <= 1 {
967 // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
968 // 2 segments, so the `resolve_path` above won't trigger it.
969 let mut full_path = import.module_path.clone();
970 full_path.push(Segment::from_ident(Ident::empty()));
971 self.lint_if_path_starts_with_module(Some(finalize), &full_path, None);
972 }
973
974 if let ModuleOrUniformRoot::Module(module) = module {
975 if module == import.parent_scope.module {
976 // Importing a module into itself is not allowed.
977 return Some(UnresolvedImportError {
978 span: import.span,
979 label: Some(String::from(
980 "cannot glob-import a module into itself",
981 )),
982 note: None,
983 suggestion: None,
984 candidates: None,
985 });
986 }
987 }
988 if !is_prelude
989 && let Some(max_vis) = max_vis.get()
990 && !max_vis.is_at_least(import.expect_vis(), self.tcx)
991 {
992 self.lint_buffer.buffer_lint(
993 UNUSED_IMPORTS,
994 id,
995 import.span,
996 fluent::resolve_glob_import_doesnt_reexport,
997 );
998 }
999 return None;
1000 }
1001 _ => unreachable!(),
1002 };
1003
1004 if self.privacy_errors.len() != privacy_errors_len {
1005 // Get the Res for the last element, so that we can point to alternative ways of
1006 // importing it if available.
1007 let mut path = import.module_path.clone();
1008 path.push(Segment::from_ident(ident));
1009 if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
1010 self.resolve_path(&path, None, &import.parent_scope, Some(finalize), ignore_binding)
1011 {
1012 let res = module.res().map(|r| (r, ident));
1013 for error in &mut self.privacy_errors[privacy_errors_len..] {
1014 error.outermost_res = res;
1015 }
1016 }
1017 }
1018
1019 let mut all_ns_err = true;
1020 self.per_ns(|this, ns| {
1021 if !type_ns_only || ns == TypeNS {
1022 let orig_vis = import.vis.take();
1023 let binding = this.resolve_ident_in_module(
1024 module,
1025 ident,
1026 ns,
1027 &import.parent_scope,
1028 Some(Finalize { report_private: false, ..finalize }),
1029 target_bindings[ns].get(),
1030 );
1031 import.vis.set(orig_vis);
1032
1033 match binding {
1034 Ok(binding) => {
1035 // Consistency checks, analogous to `finalize_macro_resolutions`.
1036 let initial_res = source_bindings[ns].get().map(|initial_binding| {
1037 all_ns_err = false;
1038 if let Some(target_binding) = target_bindings[ns].get() {
1039 if target.name == kw::Underscore
1040 && initial_binding.is_extern_crate()
1041 && !initial_binding.is_import()
1042 {
1043 this.record_use(
1044 ident,
1045 target_binding,
1046 import.module_path.is_empty(),
1047 );
1048 }
1049 }
1050 initial_binding.res()
1051 });
1052 let res = binding.res();
1053 let has_ambiguity_error = this
1054 .ambiguity_errors
1055 .iter()
1056 .filter(|error| !error.warning)
1057 .next()
1058 .is_some();
1059 if res == Res::Err || has_ambiguity_error {
1060 this.tcx
1061 .sess
1062 .delay_span_bug(import.span, "some error happened for an import");
1063 return;
1064 }
1065 if let Ok(initial_res) = initial_res {
1066 if res != initial_res {
1067 span_bug!(import.span, "inconsistent resolution for an import");
1068 }
1069 } else if this.privacy_errors.is_empty() {
1070 this.tcx
1071 .sess
1072 .create_err(CannotDetermineImportResolution { span: import.span })
1073 .emit();
1074 }
1075 }
1076 Err(..) => {
1077 // FIXME: This assert may fire if public glob is later shadowed by a private
1078 // single import (see test `issue-55884-2.rs`). In theory single imports should
1079 // always block globs, even if they are not yet resolved, so that this kind of
1080 // self-inconsistent resolution never happens.
1081 // Re-enable the assert when the issue is fixed.
1082 // assert!(result[ns].get().is_err());
1083 }
1084 }
1085 }
1086 });
1087
1088 if all_ns_err {
1089 let mut all_ns_failed = true;
1090 self.per_ns(|this, ns| {
1091 if !type_ns_only || ns == TypeNS {
1092 let binding = this.resolve_ident_in_module(
1093 module,
1094 ident,
1095 ns,
1096 &import.parent_scope,
1097 Some(finalize),
1098 None,
1099 );
1100 if binding.is_ok() {
1101 all_ns_failed = false;
1102 }
1103 }
1104 });
1105
1106 return if all_ns_failed {
1107 let resolutions = match module {
1108 ModuleOrUniformRoot::Module(module) => Some(self.resolutions(module).borrow()),
1109 _ => None,
1110 };
1111 let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
1112 let names = resolutions
1113 .filter_map(|(BindingKey { ident: i, .. }, resolution)| {
1114 if i.name == ident.name {
1115 return None;
1116 } // Never suggest the same name
1117 match *resolution.borrow() {
1118 NameResolution { binding: Some(name_binding), .. } => {
1119 match name_binding.kind {
1120 NameBindingKind::Import { binding, .. } => {
1121 match binding.kind {
1122 // Never suggest the name that has binding error
1123 // i.e., the name that cannot be previously resolved
1124 NameBindingKind::Res(Res::Err) => None,
1125 _ => Some(i.name),
1126 }
1127 }
1128 _ => Some(i.name),
1129 }
1130 }
1131 NameResolution { ref single_imports, .. }
1132 if single_imports.is_empty() =>
1133 {
1134 None
1135 }
1136 _ => Some(i.name),
1137 }
1138 })
1139 .collect::<Vec<Symbol>>();
1140
1141 let lev_suggestion =
1142 find_best_match_for_name(&names, ident.name, None).map(|suggestion| {
1143 (
1144 vec![(ident.span, suggestion.to_string())],
1145 String::from("a similar name exists in the module"),
1146 Applicability::MaybeIncorrect,
1147 )
1148 });
1149
1150 let (suggestion, note) =
1151 match self.check_for_module_export_macro(import, module, ident) {
1152 Some((suggestion, note)) => (suggestion.or(lev_suggestion), note),
1153 _ => (lev_suggestion, None),
1154 };
1155
1156 let label = match module {
1157 ModuleOrUniformRoot::Module(module) => {
1158 let module_str = module_to_string(module);
1159 if let Some(module_str) = module_str {
1160 format!("no `{ident}` in `{module_str}`")
1161 } else {
1162 format!("no `{ident}` in the root")
1163 }
1164 }
1165 _ => {
1166 if !ident.is_path_segment_keyword() {
1167 format!("no external crate `{ident}`")
1168 } else {
1169 // HACK(eddyb) this shows up for `self` & `super`, which
1170 // should work instead - for now keep the same error message.
1171 format!("no `{ident}` in the root")
1172 }
1173 }
1174 };
1175
1176 let parent_suggestion =
1177 self.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true);
1178
1179 Some(UnresolvedImportError {
1180 span: import.span,
1181 label: Some(label),
1182 note,
1183 suggestion,
1184 candidates: if !parent_suggestion.is_empty() {
1185 Some(parent_suggestion)
1186 } else {
1187 None
1188 },
1189 })
1190 } else {
1191 // `resolve_ident_in_module` reported a privacy error.
1192 None
1193 };
1194 }
1195
1196 let mut reexport_error = None;
1197 let mut any_successful_reexport = false;
1198 let mut crate_private_reexport = false;
1199 self.per_ns(|this, ns| {
1200 if let Ok(binding) = source_bindings[ns].get() {
1201 if !binding.vis.is_at_least(import.expect_vis(), this.tcx) {
1202 reexport_error = Some((ns, binding));
1203 if let ty::Visibility::Restricted(binding_def_id) = binding.vis {
1204 if binding_def_id.is_top_level_module() {
1205 crate_private_reexport = true;
1206 }
1207 }
1208 } else {
1209 any_successful_reexport = true;
1210 }
1211 }
1212 });
1213
1214 // All namespaces must be re-exported with extra visibility for an error to occur.
1215 if !any_successful_reexport {
1216 let (ns, binding) = reexport_error.unwrap();
1217 if pub_use_of_private_extern_crate_hack(import, binding) {
1218 let msg = format!(
1219 "extern crate `{ident}` is private, and cannot be \
1220 re-exported (error E0365), consider declaring with \
1221 `pub`"
1222 );
1223 self.lint_buffer.buffer_lint(
1224 PUB_USE_OF_PRIVATE_EXTERN_CRATE,
1225 import_id,
1226 import.span,
1227 msg,
1228 );
1229 } else {
1230 if ns == TypeNS {
1231 let mut err = if crate_private_reexport {
1232 self.tcx.sess.create_err(CannotBeReexportedCratePublicNS {
1233 span: import.span,
1234 ident,
1235 })
1236 } else {
1237 self.tcx
1238 .sess
1239 .create_err(CannotBeReexportedPrivateNS { span: import.span, ident })
1240 };
1241 err.emit();
1242 } else {
1243 let mut err = if crate_private_reexport {
1244 self.tcx
1245 .sess
1246 .create_err(CannotBeReexportedCratePublic { span: import.span, ident })
1247 } else {
1248 self.tcx
1249 .sess
1250 .create_err(CannotBeReexportedPrivate { span: import.span, ident })
1251 };
1252
1253 match binding.kind {
1254 NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id))
1255 // exclude decl_macro
1256 if self.get_macro_by_def_id(def_id).macro_rules =>
1257 {
1258 err.subdiagnostic(ConsiderAddingMacroExport {
1259 span: binding.span,
1260 });
1261 }
1262 _ => {
1263 err.subdiagnostic(ConsiderMarkingAsPub {
1264 span: import.span,
1265 ident,
1266 });
1267 }
1268 }
1269 err.emit();
1270 }
1271 }
1272 }
1273
1274 if import.module_path.len() <= 1 {
1275 // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
1276 // 2 segments, so the `resolve_path` above won't trigger it.
1277 let mut full_path = import.module_path.clone();
1278 full_path.push(Segment::from_ident(ident));
1279 self.per_ns(|this, ns| {
1280 if let Ok(binding) = source_bindings[ns].get() {
1281 this.lint_if_path_starts_with_module(Some(finalize), &full_path, Some(binding));
1282 }
1283 });
1284 }
1285
1286 // Record what this import resolves to for later uses in documentation,
1287 // this may resolve to either a value or a type, but for documentation
1288 // purposes it's good enough to just favor one over the other.
1289 self.per_ns(|this, ns| {
1290 if let Ok(binding) = source_bindings[ns].get() {
1291 this.import_res_map.entry(import_id).or_default()[ns] = Some(binding.res());
1292 }
1293 });
1294
1295 self.check_for_redundant_imports(ident, import, source_bindings, target_bindings, target);
1296
1297 debug!("(resolving single import) successfully resolved import");
1298 None
1299 }
1300
1301 fn check_for_redundant_imports(
1302 &mut self,
1303 ident: Ident,
1304 import: Import<'a>,
1305 source_bindings: &PerNS<Cell<Result<NameBinding<'a>, Determinacy>>>,
1306 target_bindings: &PerNS<Cell<Option<NameBinding<'a>>>>,
1307 target: Ident,
1308 ) {
1309 // This function is only called for single imports.
1310 let ImportKind::Single { id, .. } = import.kind else { unreachable!() };
1311
1312 // Skip if the import was produced by a macro.
1313 if import.parent_scope.expansion != LocalExpnId::ROOT {
1314 return;
1315 }
1316
1317 // Skip if we are inside a named module (in contrast to an anonymous
1318 // module defined by a block).
1319 if let ModuleKind::Def(..) = import.parent_scope.module.kind {
1320 return;
1321 }
1322
1323 let mut is_redundant = PerNS { value_ns: None, type_ns: None, macro_ns: None };
1324
1325 let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None };
1326
1327 self.per_ns(|this, ns| {
1328 if let Ok(binding) = source_bindings[ns].get() {
1329 if binding.res() == Res::Err {
1330 return;
1331 }
1332
1333 match this.early_resolve_ident_in_lexical_scope(
1334 target,
1335 ScopeSet::All(ns),
1336 &import.parent_scope,
1337 None,
1338 false,
1339 target_bindings[ns].get(),
1340 ) {
1341 Ok(other_binding) => {
1342 is_redundant[ns] = Some(
1343 binding.res() == other_binding.res() && !other_binding.is_ambiguity(),
1344 );
1345 redundant_span[ns] = Some((other_binding.span, other_binding.is_import()));
1346 }
1347 Err(_) => is_redundant[ns] = Some(false),
1348 }
1349 }
1350 });
1351
1352 if !is_redundant.is_empty() && is_redundant.present_items().all(|is_redundant| is_redundant)
1353 {
1354 let mut redundant_spans: Vec<_> = redundant_span.present_items().collect();
1355 redundant_spans.sort();
1356 redundant_spans.dedup();
1357 self.lint_buffer.buffer_lint_with_diagnostic(
1358 UNUSED_IMPORTS,
1359 id,
1360 import.span,
1361 format!("the item `{ident}` is imported redundantly"),
1362 BuiltinLintDiagnostics::RedundantImport(redundant_spans, ident),
1363 );
1364 }
1365 }
1366
1367 fn resolve_glob_import(&mut self, import: Import<'a>) {
1368 // This function is only called for glob imports.
1369 let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() };
1370
1371 let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else {
1372 self.tcx.sess.create_err(CannotGlobImportAllCrates { span: import.span }).emit();
1373 return;
1374 };
1375
1376 if module.is_trait() {
1377 self.tcx.sess.create_err(ItemsInTraitsAreNotImportable { span: import.span }).emit();
1378 return;
1379 } else if module == import.parent_scope.module {
1380 return;
1381 } else if is_prelude {
1382 self.prelude = Some(module);
1383 return;
1384 }
1385
1386 // Add to module's glob_importers
1387 module.glob_importers.borrow_mut().push(import);
1388
1389 // Ensure that `resolutions` isn't borrowed during `try_define`,
1390 // since it might get updated via a glob cycle.
1391 let bindings = self
1392 .resolutions(module)
1393 .borrow()
1394 .iter()
1395 .filter_map(|(key, resolution)| {
1396 resolution.borrow().binding().map(|binding| (*key, binding))
1397 })
1398 .collect::<Vec<_>>();
1399 for (mut key, binding) in bindings {
1400 let scope = match key.ident.span.reverse_glob_adjust(module.expansion, import.span) {
1401 Some(Some(def)) => self.expn_def_scope(def),
1402 Some(None) => import.parent_scope.module,
1403 None => continue,
1404 };
1405 if self.is_accessible_from(binding.vis, scope) {
1406 let imported_binding = self.import(binding, import);
1407 let warn_ambiguity = self
1408 .resolution(import.parent_scope.module, key)
1409 .borrow()
1410 .binding()
1411 .is_some_and(|binding| binding.is_warn_ambiguity());
1412 let _ = self.try_define(
1413 import.parent_scope.module,
1414 key,
1415 imported_binding,
1416 warn_ambiguity,
1417 );
1418 }
1419 }
1420
1421 // Record the destination of this import
1422 self.record_partial_res(id, PartialRes::new(module.res().unwrap()));
1423 }
1424
1425 // Miscellaneous post-processing, including recording re-exports,
1426 // reporting conflicts, and reporting unresolved imports.
1427 fn finalize_resolutions_in(&mut self, module: Module<'a>) {
1428 // Since import resolution is finished, globs will not define any more names.
1429 *module.globs.borrow_mut() = Vec::new();
1430
1431 if let Some(def_id) = module.opt_def_id() {
1432 let mut children = Vec::new();
1433
1434 module.for_each_child(self, |this, ident, _, binding| {
1435 let res = binding.res().expect_non_local();
1436 let error_ambiguity = binding.is_ambiguity() && !binding.warn_ambiguity;
1437 if res != def::Res::Err && !error_ambiguity {
1438 let mut reexport_chain = SmallVec::new();
1439 let mut next_binding = binding;
1440 while let NameBindingKind::Import { binding, import, .. } = next_binding.kind {
1441 reexport_chain.push(import.simplify(this));
1442 next_binding = binding;
1443 }
1444
1445 children.push(ModChild { ident, res, vis: binding.vis, reexport_chain });
1446 }
1447 });
1448
1449 if !children.is_empty() {
1450 // Should be fine because this code is only called for local modules.
1451 self.module_children.insert(def_id.expect_local(), children);
1452 }
1453 }
1454 }
1455 }
1456
1457 fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Span) -> String {
1458 let pos = names.iter().position(|p| span == p.span && p.name != kw::PathRoot);
1459 let global = !names.is_empty() && names[0].name == kw::PathRoot;
1460 if let Some(pos) = pos {
1461 let names = if global { &names[1..pos + 1] } else { &names[..pos + 1] };
1462 names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>())
1463 } else {
1464 let names = if global { &names[1..] } else { names };
1465 if names.is_empty() {
1466 import_kind_to_string(import_kind)
1467 } else {
1468 format!(
1469 "{}::{}",
1470 names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>()),
1471 import_kind_to_string(import_kind),
1472 )
1473 }
1474 }
1475 }
1476
1477 fn import_kind_to_string(import_kind: &ImportKind<'_>) -> String {
1478 match import_kind {
1479 ImportKind::Single { source, .. } => source.to_string(),
1480 ImportKind::Glob { .. } => "*".to_string(),
1481 ImportKind::ExternCrate { .. } => "<extern crate>".to_string(),
1482 ImportKind::MacroUse => "#[macro_use]".to_string(),
1483 ImportKind::MacroExport => "#[macro_export]".to_string(),
1484 }
1485 }