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