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> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result90 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> {
is_glob(&self) -> bool180 pub(crate) fn is_glob(&self) -> bool {
181 matches!(self.kind, ImportKind::Glob { .. })
182 }
183
is_nested(&self) -> bool184 pub(crate) fn is_nested(&self) -> bool {
185 match self.kind {
186 ImportKind::Single { nested, .. } => nested,
187 _ => false,
188 }
189 }
190
expect_vis(&self) -> ty::Visibility191 pub(crate) fn expect_vis(&self) -> ty::Visibility {
192 self.vis.get().expect("encountered cleared import visibility")
193 }
194
id(&self) -> Option<NodeId>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
simplify(&self, r: &Resolver<'_, '_>) -> Reexport204 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.
binding(&self) -> Option<NameBinding<'a>>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.
pub_use_of_private_extern_crate_hack(import: Import<'_>, binding: NameBinding<'_>) -> bool253 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.
import(&self, binding: NameBinding<'a>, import: Import<'a>) -> NameBinding<'a>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 span: import.span,
288 vis,
289 expansion: import.parent_scope.expansion,
290 })
291 }
292
293 /// Define the name or return the existing binding if there is a collision.
try_define( &mut self, module: Module<'a>, key: BindingKey, binding: NameBinding<'a>, ) -> Result<(), NameBinding<'a>>294 pub(crate) fn try_define(
295 &mut self,
296 module: Module<'a>,
297 key: BindingKey,
298 binding: NameBinding<'a>,
299 ) -> Result<(), NameBinding<'a>> {
300 let res = binding.res();
301 self.check_reserved_macro_name(key.ident, res);
302 self.set_binding_parent_module(binding, module);
303 self.update_resolution(module, key, |this, resolution| {
304 if let Some(old_binding) = resolution.binding {
305 if res == Res::Err && old_binding.res() != Res::Err {
306 // Do not override real bindings with `Res::Err`s from error recovery.
307 return Ok(());
308 }
309 match (old_binding.is_glob_import(), binding.is_glob_import()) {
310 (true, true) => {
311 if res != old_binding.res() {
312 resolution.binding = Some(this.ambiguity(
313 AmbiguityKind::GlobVsGlob,
314 old_binding,
315 binding,
316 ));
317 } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
318 // We are glob-importing the same item but with greater visibility.
319 resolution.binding = Some(binding);
320 }
321 }
322 (old_glob @ true, false) | (old_glob @ false, true) => {
323 let (glob_binding, nonglob_binding) =
324 if old_glob { (old_binding, binding) } else { (binding, old_binding) };
325 if glob_binding.res() != nonglob_binding.res()
326 && key.ns == MacroNS
327 && nonglob_binding.expansion != LocalExpnId::ROOT
328 {
329 resolution.binding = Some(this.ambiguity(
330 AmbiguityKind::GlobVsExpanded,
331 nonglob_binding,
332 glob_binding,
333 ));
334 } else {
335 resolution.binding = Some(nonglob_binding);
336 }
337
338 if let Some(old_binding) = resolution.shadowed_glob {
339 assert!(old_binding.is_glob_import());
340 if glob_binding.res() != old_binding.res() {
341 resolution.shadowed_glob = Some(this.ambiguity(
342 AmbiguityKind::GlobVsGlob,
343 old_binding,
344 glob_binding,
345 ));
346 } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
347 resolution.shadowed_glob = Some(glob_binding);
348 }
349 } else {
350 resolution.shadowed_glob = Some(glob_binding);
351 }
352 }
353 (false, false) => {
354 return Err(old_binding);
355 }
356 }
357 } else {
358 resolution.binding = Some(binding);
359 }
360
361 Ok(())
362 })
363 }
364
ambiguity( &self, kind: AmbiguityKind, primary_binding: NameBinding<'a>, secondary_binding: NameBinding<'a>, ) -> NameBinding<'a>365 fn ambiguity(
366 &self,
367 kind: AmbiguityKind,
368 primary_binding: NameBinding<'a>,
369 secondary_binding: NameBinding<'a>,
370 ) -> NameBinding<'a> {
371 self.arenas.alloc_name_binding(NameBindingData {
372 ambiguity: Some((secondary_binding, kind)),
373 ..(*primary_binding).clone()
374 })
375 }
376
377 // Use `f` to mutate the resolution of the name in the module.
378 // If the resolution becomes a success, define it in the module's glob importers.
update_resolution<T, F>(&mut self, module: Module<'a>, key: BindingKey, f: F) -> T where F: FnOnce(&mut Resolver<'a, 'tcx>, &mut NameResolution<'a>) -> T,379 fn update_resolution<T, F>(&mut self, module: Module<'a>, key: BindingKey, f: F) -> T
380 where
381 F: FnOnce(&mut Resolver<'a, 'tcx>, &mut NameResolution<'a>) -> T,
382 {
383 // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
384 // during which the resolution might end up getting re-defined via a glob cycle.
385 let (binding, t) = {
386 let resolution = &mut *self.resolution(module, key).borrow_mut();
387 let old_binding = resolution.binding();
388
389 let t = f(self, resolution);
390
391 if old_binding.is_none() && let Some(binding) = resolution.binding() {
392 (binding, t)
393 } else {
394 return t;
395 }
396 };
397
398 // Define `binding` in `module`s glob importers.
399 for import in module.glob_importers.borrow_mut().iter() {
400 let mut ident = key.ident;
401 let scope = match ident.span.reverse_glob_adjust(module.expansion, import.span) {
402 Some(Some(def)) => self.expn_def_scope(def),
403 Some(None) => import.parent_scope.module,
404 None => continue,
405 };
406 if self.is_accessible_from(binding.vis, scope) {
407 let imported_binding = self.import(binding, *import);
408 let key = BindingKey { ident, ..key };
409 let _ = self.try_define(import.parent_scope.module, key, imported_binding);
410 }
411 }
412
413 t
414 }
415
416 // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
417 // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
import_dummy_binding(&mut self, import: Import<'a>, is_indeterminate: bool)418 fn import_dummy_binding(&mut self, import: Import<'a>, is_indeterminate: bool) {
419 if let ImportKind::Single { target, ref target_bindings, .. } = import.kind {
420 if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().is_none()))
421 {
422 return; // Has resolution, do not create the dummy binding
423 }
424 let dummy_binding = self.dummy_binding;
425 let dummy_binding = self.import(dummy_binding, import);
426 self.per_ns(|this, ns| {
427 let key = BindingKey::new(target, ns);
428 let _ = this.try_define(import.parent_scope.module, key, dummy_binding);
429 });
430 self.record_use(target, dummy_binding, false);
431 } else if import.imported_module.get().is_none() {
432 import.used.set(true);
433 if let Some(id) = import.id() {
434 self.used_imports.insert(id);
435 }
436 }
437 }
438
439 // Import resolution
440 //
441 // This is a fixed-point algorithm. We resolve imports until our efforts
442 // are stymied by an unresolved import; then we bail out of the current
443 // module and continue. We terminate successfully once no more imports
444 // remain or unsuccessfully when no forward progress in resolving imports
445 // is made.
446
447 /// Resolves all imports for the crate. This method performs the fixed-
448 /// point iteration.
resolve_imports(&mut self)449 pub(crate) fn resolve_imports(&mut self) {
450 let mut prev_indeterminate_count = usize::MAX;
451 let mut indeterminate_count = self.indeterminate_imports.len() * 3;
452 while indeterminate_count < prev_indeterminate_count {
453 prev_indeterminate_count = indeterminate_count;
454 indeterminate_count = 0;
455 for import in mem::take(&mut self.indeterminate_imports) {
456 let import_indeterminate_count = self.resolve_import(import);
457 indeterminate_count += import_indeterminate_count;
458 match import_indeterminate_count {
459 0 => self.determined_imports.push(import),
460 _ => self.indeterminate_imports.push(import),
461 }
462 }
463 }
464 }
465
finalize_imports(&mut self)466 pub(crate) fn finalize_imports(&mut self) {
467 for module in self.arenas.local_modules().iter() {
468 self.finalize_resolutions_in(*module);
469 }
470
471 let mut seen_spans = FxHashSet::default();
472 let mut errors = vec![];
473 let mut prev_root_id: NodeId = NodeId::from_u32(0);
474 let determined_imports = mem::take(&mut self.determined_imports);
475 let indeterminate_imports = mem::take(&mut self.indeterminate_imports);
476
477 for (is_indeterminate, import) in determined_imports
478 .into_iter()
479 .map(|i| (false, i))
480 .chain(indeterminate_imports.into_iter().map(|i| (true, i)))
481 {
482 let unresolved_import_error = self.finalize_import(import);
483
484 // If this import is unresolved then create a dummy import
485 // resolution for it so that later resolve stages won't complain.
486 self.import_dummy_binding(import, is_indeterminate);
487
488 if let Some(err) = unresolved_import_error {
489 if let ImportKind::Single { source, ref source_bindings, .. } = import.kind {
490 if source.name == kw::SelfLower {
491 // Silence `unresolved import` error if E0429 is already emitted
492 if let Err(Determined) = source_bindings.value_ns.get() {
493 continue;
494 }
495 }
496 }
497
498 if prev_root_id.as_u32() != 0
499 && prev_root_id.as_u32() != import.root_id.as_u32()
500 && !errors.is_empty()
501 {
502 // In the case of a new import line, throw a diagnostic message
503 // for the previous line.
504 self.throw_unresolved_import_error(errors);
505 errors = vec![];
506 }
507 if seen_spans.insert(err.span) {
508 errors.push((import, err));
509 prev_root_id = import.root_id;
510 }
511 } else if is_indeterminate {
512 let path = import_path_to_string(
513 &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
514 &import.kind,
515 import.span,
516 );
517 let err = UnresolvedImportError {
518 span: import.span,
519 label: None,
520 note: None,
521 suggestion: None,
522 candidates: None,
523 };
524 // FIXME: there should be a better way of doing this than
525 // formatting this as a string then checking for `::`
526 if path.contains("::") {
527 errors.push((import, err))
528 }
529 }
530 }
531
532 if !errors.is_empty() {
533 self.throw_unresolved_import_error(errors);
534 }
535 }
536
check_hidden_glob_reexports( &mut self, exported_ambiguities: FxHashSet<NameBinding<'a>>, )537 pub(crate) fn check_hidden_glob_reexports(
538 &mut self,
539 exported_ambiguities: FxHashSet<NameBinding<'a>>,
540 ) {
541 for module in self.arenas.local_modules().iter() {
542 for (key, resolution) in self.resolutions(*module).borrow().iter() {
543 let resolution = resolution.borrow();
544
545 if let Some(binding) = resolution.binding {
546 if let NameBindingKind::Import { import, .. } = binding.kind
547 && let Some((amb_binding, _)) = binding.ambiguity
548 && binding.res() != Res::Err
549 && exported_ambiguities.contains(&binding)
550 {
551 self.lint_buffer.buffer_lint_with_diagnostic(
552 AMBIGUOUS_GLOB_REEXPORTS,
553 import.root_id,
554 import.root_span,
555 "ambiguous glob re-exports",
556 BuiltinLintDiagnostics::AmbiguousGlobReexports {
557 name: key.ident.to_string(),
558 namespace: key.ns.descr().to_string(),
559 first_reexport_span: import.root_span,
560 duplicate_reexport_span: amb_binding.span,
561 },
562 );
563 }
564
565 if let Some(glob_binding) = resolution.shadowed_glob {
566 let binding_id = match binding.kind {
567 NameBindingKind::Res(res) => {
568 Some(self.def_id_to_node_id[res.def_id().expect_local()])
569 }
570 NameBindingKind::Module(module) => {
571 Some(self.def_id_to_node_id[module.def_id().expect_local()])
572 }
573 NameBindingKind::Import { import, .. } => import.id(),
574 };
575
576 if binding.res() != Res::Err
577 && glob_binding.res() != Res::Err
578 && let NameBindingKind::Import { import: glob_import, .. } = glob_binding.kind
579 && let Some(binding_id) = binding_id
580 && let Some(glob_import_id) = glob_import.id()
581 && let glob_import_def_id = self.local_def_id(glob_import_id)
582 && self.effective_visibilities.is_exported(glob_import_def_id)
583 && glob_binding.vis.is_public()
584 && !binding.vis.is_public()
585 {
586 self.lint_buffer.buffer_lint_with_diagnostic(
587 HIDDEN_GLOB_REEXPORTS,
588 binding_id,
589 binding.span,
590 "private item shadows public glob re-export",
591 BuiltinLintDiagnostics::HiddenGlobReexports {
592 name: key.ident.name.to_string(),
593 namespace: key.ns.descr().to_owned(),
594 glob_reexport_span: glob_binding.span,
595 private_item_span: binding.span,
596 },
597 );
598 }
599 }
600 }
601 }
602 }
603 }
604
throw_unresolved_import_error(&mut self, errors: Vec<(Import<'_>, UnresolvedImportError)>)605 fn throw_unresolved_import_error(&mut self, errors: Vec<(Import<'_>, UnresolvedImportError)>) {
606 if errors.is_empty() {
607 return;
608 }
609
610 /// Upper limit on the number of `span_label` messages.
611 const MAX_LABEL_COUNT: usize = 10;
612
613 let span = MultiSpan::from_spans(errors.iter().map(|(_, err)| err.span).collect());
614 let paths = errors
615 .iter()
616 .map(|(import, err)| {
617 let path = import_path_to_string(
618 &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
619 &import.kind,
620 err.span,
621 );
622 format!("`{path}`")
623 })
624 .collect::<Vec<_>>();
625 let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),);
626
627 let mut diag = struct_span_err!(self.tcx.sess, span, E0432, "{}", &msg);
628
629 if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() {
630 diag.note(note.clone());
631 }
632
633 for (import, err) in errors.into_iter().take(MAX_LABEL_COUNT) {
634 if let Some(label) = err.label {
635 diag.span_label(err.span, label);
636 }
637
638 if let Some((suggestions, msg, applicability)) = err.suggestion {
639 if suggestions.is_empty() {
640 diag.help(msg);
641 continue;
642 }
643 diag.multipart_suggestion(msg, suggestions, applicability);
644 }
645
646 if let Some(candidates) = &err.candidates {
647 match &import.kind {
648 ImportKind::Single { nested: false, source, target, .. } => import_candidates(
649 self.tcx,
650 &mut diag,
651 Some(err.span),
652 &candidates,
653 DiagnosticMode::Import,
654 (source != target)
655 .then(|| format!(" as {target}"))
656 .as_deref()
657 .unwrap_or(""),
658 ),
659 ImportKind::Single { nested: true, source, target, .. } => {
660 import_candidates(
661 self.tcx,
662 &mut diag,
663 None,
664 &candidates,
665 DiagnosticMode::Normal,
666 (source != target)
667 .then(|| format!(" as {target}"))
668 .as_deref()
669 .unwrap_or(""),
670 );
671 }
672 _ => {}
673 }
674 }
675
676 match &import.kind {
677 ImportKind::Single { source, .. } => {
678 if let Some(ModuleOrUniformRoot::Module(module)) = import.imported_module.get()
679 && let Some(module) = module.opt_def_id()
680 {
681 self.find_cfg_stripped(&mut diag, &source.name, module)
682 }
683 },
684 _ => {}
685 }
686 }
687
688 diag.emit();
689 }
690
691 /// Attempts to resolve the given import, returning:
692 /// - `0` means its resolution is determined.
693 /// - Other values mean that indeterminate exists under certain namespaces.
694 ///
695 /// Meanwhile, if resolve successful, the resolved bindings are written
696 /// into the module.
resolve_import(&mut self, import: Import<'a>) -> usize697 fn resolve_import(&mut self, import: Import<'a>) -> usize {
698 debug!(
699 "(resolving import for module) resolving import `{}::...` in `{}`",
700 Segment::names_to_string(&import.module_path),
701 module_to_string(import.parent_scope.module).unwrap_or_else(|| "???".to_string()),
702 );
703
704 let module = if let Some(module) = import.imported_module.get() {
705 module
706 } else {
707 // For better failure detection, pretend that the import will
708 // not define any names while resolving its module path.
709 let orig_vis = import.vis.take();
710 let path_res = self.maybe_resolve_path(&import.module_path, None, &import.parent_scope);
711 import.vis.set(orig_vis);
712
713 match path_res {
714 PathResult::Module(module) => module,
715 PathResult::Indeterminate => return 3,
716 PathResult::NonModule(..) | PathResult::Failed { .. } => return 0,
717 }
718 };
719
720 import.imported_module.set(Some(module));
721 let (source, target, source_bindings, target_bindings, type_ns_only) = match import.kind {
722 ImportKind::Single {
723 source,
724 target,
725 ref source_bindings,
726 ref target_bindings,
727 type_ns_only,
728 ..
729 } => (source, target, source_bindings, target_bindings, type_ns_only),
730 ImportKind::Glob { .. } => {
731 self.resolve_glob_import(import);
732 return 0;
733 }
734 _ => unreachable!(),
735 };
736
737 let mut indeterminate_count = 0;
738 self.per_ns(|this, ns| {
739 if !type_ns_only || ns == TypeNS {
740 if let Err(Undetermined) = source_bindings[ns].get() {
741 // For better failure detection, pretend that the import will
742 // not define any names while resolving its module path.
743 let orig_vis = import.vis.take();
744 let binding = this.resolve_ident_in_module(
745 module,
746 source,
747 ns,
748 &import.parent_scope,
749 None,
750 None,
751 );
752 import.vis.set(orig_vis);
753 source_bindings[ns].set(binding);
754 } else {
755 return;
756 };
757
758 let parent = import.parent_scope.module;
759 match source_bindings[ns].get() {
760 Err(Undetermined) => indeterminate_count += 1,
761 // Don't update the resolution, because it was never added.
762 Err(Determined) if target.name == kw::Underscore => {}
763 Ok(binding) if binding.is_importable() => {
764 let imported_binding = this.import(binding, import);
765 target_bindings[ns].set(Some(imported_binding));
766 this.define(parent, target, ns, imported_binding);
767 }
768 source_binding @ (Ok(..) | Err(Determined)) => {
769 if source_binding.is_ok() {
770 this.tcx
771 .sess
772 .create_err(IsNotDirectlyImportable { span: import.span, target })
773 .emit();
774 }
775 let key = BindingKey::new(target, ns);
776 this.update_resolution(parent, key, |_, resolution| {
777 resolution.single_imports.remove(&import);
778 });
779 }
780 }
781 }
782 });
783
784 indeterminate_count
785 }
786
787 /// Performs final import resolution, consistency checks and error reporting.
788 ///
789 /// Optionally returns an unresolved import error. This error is buffered and used to
790 /// consolidate multiple unresolved import errors into a single diagnostic.
finalize_import(&mut self, import: Import<'a>) -> Option<UnresolvedImportError>791 fn finalize_import(&mut self, import: Import<'a>) -> Option<UnresolvedImportError> {
792 let orig_vis = import.vis.take();
793 let ignore_binding = match &import.kind {
794 ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(),
795 _ => None,
796 };
797 let prev_ambiguity_errors_len = self.ambiguity_errors.len();
798 let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span);
799
800 // We'll provide more context to the privacy errors later, up to `len`.
801 let privacy_errors_len = self.privacy_errors.len();
802
803 let path_res = self.resolve_path(
804 &import.module_path,
805 None,
806 &import.parent_scope,
807 Some(finalize),
808 ignore_binding,
809 );
810
811 let no_ambiguity = self.ambiguity_errors.len() == prev_ambiguity_errors_len;
812 import.vis.set(orig_vis);
813 let module = match path_res {
814 PathResult::Module(module) => {
815 // Consistency checks, analogous to `finalize_macro_resolutions`.
816 if let Some(initial_module) = import.imported_module.get() {
817 if module != initial_module && no_ambiguity {
818 span_bug!(import.span, "inconsistent resolution for an import");
819 }
820 } else if self.privacy_errors.is_empty() {
821 self.tcx
822 .sess
823 .create_err(CannotDetermineImportResolution { span: import.span })
824 .emit();
825 }
826
827 module
828 }
829 PathResult::Failed {
830 is_error_from_last_segment: false,
831 span,
832 label,
833 suggestion,
834 module,
835 } => {
836 if no_ambiguity {
837 assert!(import.imported_module.get().is_none());
838 self.report_error(
839 span,
840 ResolutionError::FailedToResolve {
841 last_segment: None,
842 label,
843 suggestion,
844 module,
845 },
846 );
847 }
848 return None;
849 }
850 PathResult::Failed {
851 is_error_from_last_segment: true,
852 span,
853 label,
854 suggestion,
855 ..
856 } => {
857 if no_ambiguity {
858 assert!(import.imported_module.get().is_none());
859 let err = match self.make_path_suggestion(
860 span,
861 import.module_path.clone(),
862 &import.parent_scope,
863 ) {
864 Some((suggestion, note)) => UnresolvedImportError {
865 span,
866 label: None,
867 note,
868 suggestion: Some((
869 vec![(span, Segment::names_to_string(&suggestion))],
870 String::from("a similar path exists"),
871 Applicability::MaybeIncorrect,
872 )),
873 candidates: None,
874 },
875 None => UnresolvedImportError {
876 span,
877 label: Some(label),
878 note: None,
879 suggestion,
880 candidates: None,
881 },
882 };
883 return Some(err);
884 }
885 return None;
886 }
887 PathResult::NonModule(partial_res) => {
888 if no_ambiguity && partial_res.full_res() != Some(Res::Err) {
889 // Check if there are no ambiguities and the result is not dummy.
890 assert!(import.imported_module.get().is_none());
891 }
892 // The error was already reported earlier.
893 return None;
894 }
895 PathResult::Indeterminate => unreachable!(),
896 };
897
898 let (ident, target, source_bindings, target_bindings, type_ns_only, import_id) =
899 match import.kind {
900 ImportKind::Single {
901 source,
902 target,
903 ref source_bindings,
904 ref target_bindings,
905 type_ns_only,
906 id,
907 ..
908 } => (source, target, source_bindings, target_bindings, type_ns_only, id),
909 ImportKind::Glob { is_prelude, ref max_vis, id } => {
910 if import.module_path.len() <= 1 {
911 // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
912 // 2 segments, so the `resolve_path` above won't trigger it.
913 let mut full_path = import.module_path.clone();
914 full_path.push(Segment::from_ident(Ident::empty()));
915 self.lint_if_path_starts_with_module(Some(finalize), &full_path, None);
916 }
917
918 if let ModuleOrUniformRoot::Module(module) = module {
919 if module == import.parent_scope.module {
920 // Importing a module into itself is not allowed.
921 return Some(UnresolvedImportError {
922 span: import.span,
923 label: Some(String::from(
924 "cannot glob-import a module into itself",
925 )),
926 note: None,
927 suggestion: None,
928 candidates: None,
929 });
930 }
931 }
932 if !is_prelude
933 && let Some(max_vis) = max_vis.get()
934 && !max_vis.is_at_least(import.expect_vis(), self.tcx)
935 {
936 self.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, fluent::resolve_glob_import_doesnt_reexport);
937 }
938 return None;
939 }
940 _ => unreachable!(),
941 };
942
943 if self.privacy_errors.len() != privacy_errors_len {
944 // Get the Res for the last element, so that we can point to alternative ways of
945 // importing it if available.
946 let mut path = import.module_path.clone();
947 path.push(Segment::from_ident(ident));
948 if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
949 self.resolve_path(&path, None, &import.parent_scope, Some(finalize), ignore_binding)
950 {
951 let res = module.res().map(|r| (r, ident));
952 for error in &mut self.privacy_errors[privacy_errors_len..] {
953 error.outermost_res = res;
954 }
955 }
956 }
957
958 let mut all_ns_err = true;
959 self.per_ns(|this, ns| {
960 if !type_ns_only || ns == TypeNS {
961 let orig_vis = import.vis.take();
962 let binding = this.resolve_ident_in_module(
963 module,
964 ident,
965 ns,
966 &import.parent_scope,
967 Some(Finalize { report_private: false, ..finalize }),
968 target_bindings[ns].get(),
969 );
970 import.vis.set(orig_vis);
971
972 match binding {
973 Ok(binding) => {
974 // Consistency checks, analogous to `finalize_macro_resolutions`.
975 let initial_res = source_bindings[ns].get().map(|initial_binding| {
976 all_ns_err = false;
977 if let Some(target_binding) = target_bindings[ns].get() {
978 if target.name == kw::Underscore
979 && initial_binding.is_extern_crate()
980 && !initial_binding.is_import()
981 {
982 this.record_use(
983 ident,
984 target_binding,
985 import.module_path.is_empty(),
986 );
987 }
988 }
989 initial_binding.res()
990 });
991 let res = binding.res();
992 if let Ok(initial_res) = initial_res {
993 if res != initial_res && this.ambiguity_errors.is_empty() {
994 span_bug!(import.span, "inconsistent resolution for an import");
995 }
996 } else if res != Res::Err
997 && this.ambiguity_errors.is_empty()
998 && this.privacy_errors.is_empty()
999 {
1000 this.tcx
1001 .sess
1002 .create_err(CannotDetermineImportResolution { span: import.span })
1003 .emit();
1004 }
1005 }
1006 Err(..) => {
1007 // FIXME: This assert may fire if public glob is later shadowed by a private
1008 // single import (see test `issue-55884-2.rs`). In theory single imports should
1009 // always block globs, even if they are not yet resolved, so that this kind of
1010 // self-inconsistent resolution never happens.
1011 // Re-enable the assert when the issue is fixed.
1012 // assert!(result[ns].get().is_err());
1013 }
1014 }
1015 }
1016 });
1017
1018 if all_ns_err {
1019 let mut all_ns_failed = true;
1020 self.per_ns(|this, ns| {
1021 if !type_ns_only || ns == TypeNS {
1022 let binding = this.resolve_ident_in_module(
1023 module,
1024 ident,
1025 ns,
1026 &import.parent_scope,
1027 Some(finalize),
1028 None,
1029 );
1030 if binding.is_ok() {
1031 all_ns_failed = false;
1032 }
1033 }
1034 });
1035
1036 return if all_ns_failed {
1037 let resolutions = match module {
1038 ModuleOrUniformRoot::Module(module) => Some(self.resolutions(module).borrow()),
1039 _ => None,
1040 };
1041 let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
1042 let names = resolutions
1043 .filter_map(|(BindingKey { ident: i, .. }, resolution)| {
1044 if i.name == ident.name {
1045 return None;
1046 } // Never suggest the same name
1047 match *resolution.borrow() {
1048 NameResolution { binding: Some(name_binding), .. } => {
1049 match name_binding.kind {
1050 NameBindingKind::Import { binding, .. } => {
1051 match binding.kind {
1052 // Never suggest the name that has binding error
1053 // i.e., the name that cannot be previously resolved
1054 NameBindingKind::Res(Res::Err) => None,
1055 _ => Some(i.name),
1056 }
1057 }
1058 _ => Some(i.name),
1059 }
1060 }
1061 NameResolution { ref single_imports, .. }
1062 if single_imports.is_empty() =>
1063 {
1064 None
1065 }
1066 _ => Some(i.name),
1067 }
1068 })
1069 .collect::<Vec<Symbol>>();
1070
1071 let lev_suggestion =
1072 find_best_match_for_name(&names, ident.name, None).map(|suggestion| {
1073 (
1074 vec![(ident.span, suggestion.to_string())],
1075 String::from("a similar name exists in the module"),
1076 Applicability::MaybeIncorrect,
1077 )
1078 });
1079
1080 let (suggestion, note) =
1081 match self.check_for_module_export_macro(import, module, ident) {
1082 Some((suggestion, note)) => (suggestion.or(lev_suggestion), note),
1083 _ => (lev_suggestion, None),
1084 };
1085
1086 let label = match module {
1087 ModuleOrUniformRoot::Module(module) => {
1088 let module_str = module_to_string(module);
1089 if let Some(module_str) = module_str {
1090 format!("no `{}` in `{}`", ident, module_str)
1091 } else {
1092 format!("no `{}` in the root", ident)
1093 }
1094 }
1095 _ => {
1096 if !ident.is_path_segment_keyword() {
1097 format!("no external crate `{}`", ident)
1098 } else {
1099 // HACK(eddyb) this shows up for `self` & `super`, which
1100 // should work instead - for now keep the same error message.
1101 format!("no `{}` in the root", ident)
1102 }
1103 }
1104 };
1105
1106 let parent_suggestion =
1107 self.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true);
1108
1109 Some(UnresolvedImportError {
1110 span: import.span,
1111 label: Some(label),
1112 note,
1113 suggestion,
1114 candidates: if !parent_suggestion.is_empty() {
1115 Some(parent_suggestion)
1116 } else {
1117 None
1118 },
1119 })
1120 } else {
1121 // `resolve_ident_in_module` reported a privacy error.
1122 None
1123 };
1124 }
1125
1126 let mut reexport_error = None;
1127 let mut any_successful_reexport = false;
1128 let mut crate_private_reexport = false;
1129 self.per_ns(|this, ns| {
1130 if let Ok(binding) = source_bindings[ns].get() {
1131 if !binding.vis.is_at_least(import.expect_vis(), this.tcx) {
1132 reexport_error = Some((ns, binding));
1133 if let ty::Visibility::Restricted(binding_def_id) = binding.vis {
1134 if binding_def_id.is_top_level_module() {
1135 crate_private_reexport = true;
1136 }
1137 }
1138 } else {
1139 any_successful_reexport = true;
1140 }
1141 }
1142 });
1143
1144 // All namespaces must be re-exported with extra visibility for an error to occur.
1145 if !any_successful_reexport {
1146 let (ns, binding) = reexport_error.unwrap();
1147 if pub_use_of_private_extern_crate_hack(import, binding) {
1148 let msg = format!(
1149 "extern crate `{}` is private, and cannot be \
1150 re-exported (error E0365), consider declaring with \
1151 `pub`",
1152 ident
1153 );
1154 self.lint_buffer.buffer_lint(
1155 PUB_USE_OF_PRIVATE_EXTERN_CRATE,
1156 import_id,
1157 import.span,
1158 msg,
1159 );
1160 } else {
1161 if ns == TypeNS {
1162 let mut err = if crate_private_reexport {
1163 self.tcx.sess.create_err(CannotBeReexportedCratePublicNS {
1164 span: import.span,
1165 ident,
1166 })
1167 } else {
1168 self.tcx
1169 .sess
1170 .create_err(CannotBeReexportedPrivateNS { span: import.span, ident })
1171 };
1172 err.emit();
1173 } else {
1174 let mut err = if crate_private_reexport {
1175 self.tcx
1176 .sess
1177 .create_err(CannotBeReexportedCratePublic { span: import.span, ident })
1178 } else {
1179 self.tcx
1180 .sess
1181 .create_err(CannotBeReexportedPrivate { span: import.span, ident })
1182 };
1183
1184 match binding.kind {
1185 NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id))
1186 // exclude decl_macro
1187 if self.get_macro_by_def_id(def_id).macro_rules =>
1188 {
1189 err.subdiagnostic(ConsiderAddingMacroExport {
1190 span: binding.span,
1191 });
1192 }
1193 _ => {
1194 err.subdiagnostic(ConsiderMarkingAsPub {
1195 span: import.span,
1196 ident,
1197 });
1198 }
1199 }
1200 err.emit();
1201 }
1202 }
1203 }
1204
1205 if import.module_path.len() <= 1 {
1206 // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
1207 // 2 segments, so the `resolve_path` above won't trigger it.
1208 let mut full_path = import.module_path.clone();
1209 full_path.push(Segment::from_ident(ident));
1210 self.per_ns(|this, ns| {
1211 if let Ok(binding) = source_bindings[ns].get() {
1212 this.lint_if_path_starts_with_module(Some(finalize), &full_path, Some(binding));
1213 }
1214 });
1215 }
1216
1217 // Record what this import resolves to for later uses in documentation,
1218 // this may resolve to either a value or a type, but for documentation
1219 // purposes it's good enough to just favor one over the other.
1220 self.per_ns(|this, ns| {
1221 if let Ok(binding) = source_bindings[ns].get() {
1222 this.import_res_map.entry(import_id).or_default()[ns] = Some(binding.res());
1223 }
1224 });
1225
1226 self.check_for_redundant_imports(ident, import, source_bindings, target_bindings, target);
1227
1228 debug!("(resolving single import) successfully resolved import");
1229 None
1230 }
1231
check_for_redundant_imports( &mut self, ident: Ident, import: Import<'a>, source_bindings: &PerNS<Cell<Result<NameBinding<'a>, Determinacy>>>, target_bindings: &PerNS<Cell<Option<NameBinding<'a>>>>, target: Ident, )1232 fn check_for_redundant_imports(
1233 &mut self,
1234 ident: Ident,
1235 import: Import<'a>,
1236 source_bindings: &PerNS<Cell<Result<NameBinding<'a>, Determinacy>>>,
1237 target_bindings: &PerNS<Cell<Option<NameBinding<'a>>>>,
1238 target: Ident,
1239 ) {
1240 // This function is only called for single imports.
1241 let ImportKind::Single { id, .. } = import.kind else { unreachable!() };
1242
1243 // Skip if the import was produced by a macro.
1244 if import.parent_scope.expansion != LocalExpnId::ROOT {
1245 return;
1246 }
1247
1248 // Skip if we are inside a named module (in contrast to an anonymous
1249 // module defined by a block).
1250 if let ModuleKind::Def(..) = import.parent_scope.module.kind {
1251 return;
1252 }
1253
1254 let mut is_redundant = PerNS { value_ns: None, type_ns: None, macro_ns: None };
1255
1256 let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None };
1257
1258 self.per_ns(|this, ns| {
1259 if let Ok(binding) = source_bindings[ns].get() {
1260 if binding.res() == Res::Err {
1261 return;
1262 }
1263
1264 match this.early_resolve_ident_in_lexical_scope(
1265 target,
1266 ScopeSet::All(ns),
1267 &import.parent_scope,
1268 None,
1269 false,
1270 target_bindings[ns].get(),
1271 ) {
1272 Ok(other_binding) => {
1273 is_redundant[ns] = Some(
1274 binding.res() == other_binding.res() && !other_binding.is_ambiguity(),
1275 );
1276 redundant_span[ns] = Some((other_binding.span, other_binding.is_import()));
1277 }
1278 Err(_) => is_redundant[ns] = Some(false),
1279 }
1280 }
1281 });
1282
1283 if !is_redundant.is_empty() && is_redundant.present_items().all(|is_redundant| is_redundant)
1284 {
1285 let mut redundant_spans: Vec<_> = redundant_span.present_items().collect();
1286 redundant_spans.sort();
1287 redundant_spans.dedup();
1288 self.lint_buffer.buffer_lint_with_diagnostic(
1289 UNUSED_IMPORTS,
1290 id,
1291 import.span,
1292 format!("the item `{}` is imported redundantly", ident),
1293 BuiltinLintDiagnostics::RedundantImport(redundant_spans, ident),
1294 );
1295 }
1296 }
1297
resolve_glob_import(&mut self, import: Import<'a>)1298 fn resolve_glob_import(&mut self, import: Import<'a>) {
1299 // This function is only called for glob imports.
1300 let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() };
1301
1302 let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else {
1303 self.tcx.sess.create_err(CannotGlobImportAllCrates {
1304 span: import.span,
1305 }).emit();
1306 return;
1307 };
1308
1309 if module.is_trait() {
1310 self.tcx.sess.create_err(ItemsInTraitsAreNotImportable { span: import.span }).emit();
1311 return;
1312 } else if module == import.parent_scope.module {
1313 return;
1314 } else if is_prelude {
1315 self.prelude = Some(module);
1316 return;
1317 }
1318
1319 // Add to module's glob_importers
1320 module.glob_importers.borrow_mut().push(import);
1321
1322 // Ensure that `resolutions` isn't borrowed during `try_define`,
1323 // since it might get updated via a glob cycle.
1324 let bindings = self
1325 .resolutions(module)
1326 .borrow()
1327 .iter()
1328 .filter_map(|(key, resolution)| {
1329 resolution.borrow().binding().map(|binding| (*key, binding))
1330 })
1331 .collect::<Vec<_>>();
1332 for (mut key, binding) in bindings {
1333 let scope = match key.ident.span.reverse_glob_adjust(module.expansion, import.span) {
1334 Some(Some(def)) => self.expn_def_scope(def),
1335 Some(None) => import.parent_scope.module,
1336 None => continue,
1337 };
1338 if self.is_accessible_from(binding.vis, scope) {
1339 let imported_binding = self.import(binding, import);
1340 let _ = self.try_define(import.parent_scope.module, key, imported_binding);
1341 }
1342 }
1343
1344 // Record the destination of this import
1345 self.record_partial_res(id, PartialRes::new(module.res().unwrap()));
1346 }
1347
1348 // Miscellaneous post-processing, including recording re-exports,
1349 // reporting conflicts, and reporting unresolved imports.
finalize_resolutions_in(&mut self, module: Module<'a>)1350 fn finalize_resolutions_in(&mut self, module: Module<'a>) {
1351 // Since import resolution is finished, globs will not define any more names.
1352 *module.globs.borrow_mut() = Vec::new();
1353
1354 if let Some(def_id) = module.opt_def_id() {
1355 let mut children = Vec::new();
1356
1357 module.for_each_child(self, |this, ident, _, binding| {
1358 let res = binding.res().expect_non_local();
1359 if res != def::Res::Err && !binding.is_ambiguity() {
1360 let mut reexport_chain = SmallVec::new();
1361 let mut next_binding = binding;
1362 while let NameBindingKind::Import { binding, import, .. } = next_binding.kind {
1363 reexport_chain.push(import.simplify(this));
1364 next_binding = binding;
1365 }
1366
1367 children.push(ModChild { ident, res, vis: binding.vis, reexport_chain });
1368 }
1369 });
1370
1371 if !children.is_empty() {
1372 // Should be fine because this code is only called for local modules.
1373 self.module_children.insert(def_id.expect_local(), children);
1374 }
1375 }
1376 }
1377 }
1378
import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Span) -> String1379 fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Span) -> String {
1380 let pos = names.iter().position(|p| span == p.span && p.name != kw::PathRoot);
1381 let global = !names.is_empty() && names[0].name == kw::PathRoot;
1382 if let Some(pos) = pos {
1383 let names = if global { &names[1..pos + 1] } else { &names[..pos + 1] };
1384 names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>())
1385 } else {
1386 let names = if global { &names[1..] } else { names };
1387 if names.is_empty() {
1388 import_kind_to_string(import_kind)
1389 } else {
1390 format!(
1391 "{}::{}",
1392 names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>()),
1393 import_kind_to_string(import_kind),
1394 )
1395 }
1396 }
1397 }
1398
import_kind_to_string(import_kind: &ImportKind<'_>) -> String1399 fn import_kind_to_string(import_kind: &ImportKind<'_>) -> String {
1400 match import_kind {
1401 ImportKind::Single { source, .. } => source.to_string(),
1402 ImportKind::Glob { .. } => "*".to_string(),
1403 ImportKind::ExternCrate { .. } => "<extern crate>".to_string(),
1404 ImportKind::MacroUse => "#[macro_use]".to_string(),
1405 ImportKind::MacroExport => "#[macro_export]".to_string(),
1406 }
1407 }
1408