]> git.proxmox.com Git - rustc.git/blame - src/librustc_resolve/resolve_imports.rs
New upstream version 1.28.0~beta.14+dfsg1
[rustc.git] / src / librustc_resolve / resolve_imports.rs
CommitLineData
c34b1796
AL
1// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11use self::ImportDirectiveSubclass::*;
12
94b46f34 13use {AmbiguityError, CrateLint, Module, PerNS};
476ff2be 14use Namespace::{self, TypeNS, MacroNS};
ff7c6d11 15use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
c34b1796 16use Resolver;
c34b1796 17use {names_to_string, module_to_string};
c1a9b12d 18use {resolve_error, ResolutionError};
c34b1796 19
a7813a04 20use rustc::ty;
94b46f34
XL
21use rustc::lint::builtin::BuiltinLintDiagnostics;
22use rustc::lint::builtin::{DUPLICATE_MACRO_EXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE};
ff7c6d11 23use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
54a0048b 24use rustc::hir::def::*;
ff7c6d11 25use rustc::session::DiagnosticMessageId;
3b2f2976 26use rustc::util::nodemap::{FxHashMap, FxHashSet};
c34b1796 27
94b46f34 28use syntax::ast::{Ident, Name, NodeId, CRATE_NODE_ID};
c30ab7b3 29use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
476ff2be
SL
30use syntax::ext::hygiene::Mark;
31use syntax::symbol::keywords;
9cc50fc6 32use syntax::util::lev_distance::find_best_match_for_name;
9e0c209e 33use syntax_pos::Span;
c34b1796 34
54a0048b 35use std::cell::{Cell, RefCell};
83c7162d 36use std::{mem, ptr};
3157f602 37
c34b1796 38/// Contains data for specific types of import directives.
54a0048b 39#[derive(Clone, Debug)]
9e0c209e 40pub enum ImportDirectiveSubclass<'a> {
54a0048b 41 SingleImport {
32a655c1
SL
42 target: Ident,
43 source: Ident,
476ff2be 44 result: PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
32a655c1 45 type_ns_only: bool,
9e0c209e
SL
46 },
47 GlobImport {
48 is_prelude: bool,
2c00a5a8
XL
49 max_vis: Cell<ty::Visibility>, // The visibility of the greatest re-export.
50 // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors.
54a0048b 51 },
abe05a73 52 ExternCrate(Option<Name>),
32a655c1 53 MacroUse,
c34b1796
AL
54}
55
56/// One import directive.
7453a54e 57#[derive(Debug,Clone)]
54a0048b 58pub struct ImportDirective<'a> {
94b46f34
XL
59 /// The id of the `extern crate`, `UseTree` etc that imported this `ImportDirective`.
60 ///
61 /// In the case where the `ImportDirective` was expanded from a "nested" use tree,
62 /// this id is the id of the leaf tree. For example:
63 ///
64 /// ```ignore (pacify the mercilous tidy)
65 /// use foo::bar::{a, b}
66 /// ```
67 ///
68 /// If this is the import directive for `foo::bar::a`, we would have the id of the `UseTree`
69 /// for `a` in this field.
a7813a04 70 pub id: NodeId,
94b46f34
XL
71
72 /// The `id` of the "root" use-kind -- this is always the same as
73 /// `id` except in the case of "nested" use trees, in which case
74 /// it will be the `id` of the root use tree. e.g., in the example
75 /// from `id`, this would be the id of the `use foo::bar`
76 /// `UseTree` node.
77 pub root_id: NodeId,
78
79 /// Span of this use tree.
80 pub span: Span,
81
82 /// Span of the *root* use tree (see `root_id`).
83 pub root_span: Span,
84
476ff2be 85 pub parent: Module<'a>,
83c7162d 86 pub module_path: Vec<Ident>,
476ff2be
SL
87 pub imported_module: Cell<Option<Module<'a>>>, // the resolution of `module_path`
88 pub subclass: ImportDirectiveSubclass<'a>,
476ff2be
SL
89 pub vis: Cell<ty::Visibility>,
90 pub expansion: Mark,
32a655c1 91 pub used: Cell<bool>,
c34b1796
AL
92}
93
54a0048b 94impl<'a> ImportDirective<'a> {
a7813a04
XL
95 pub fn is_glob(&self) -> bool {
96 match self.subclass { ImportDirectiveSubclass::GlobImport { .. } => true, _ => false }
97 }
94b46f34
XL
98
99 crate fn crate_lint(&self) -> CrateLint {
100 CrateLint::UsePath { root_id: self.root_id, root_span: self.root_span }
101 }
c34b1796
AL
102}
103
ff7c6d11 104#[derive(Clone, Default, Debug)]
54a0048b 105/// Records information about the resolution of a name in a namespace of a module.
7453a54e 106pub struct NameResolution<'a> {
54a0048b
SL
107 /// The single imports that define the name in the namespace.
108 single_imports: SingleImports<'a>,
7453a54e
SL
109 /// The least shadowable known binding for this name, or None if there are no known bindings.
110 pub binding: Option<&'a NameBinding<'a>>,
476ff2be 111 shadows_glob: Option<&'a NameBinding<'a>>,
54a0048b
SL
112}
113
114#[derive(Clone, Debug)]
115enum SingleImports<'a> {
116 /// No single imports can define the name in the namespace.
117 None,
118 /// Only the given single import can define the name in the namespace.
119 MaybeOne(&'a ImportDirective<'a>),
83c7162d
XL
120 /// Only one of these two single imports can define the name in the namespace.
121 MaybeTwo(&'a ImportDirective<'a>, &'a ImportDirective<'a>),
54a0048b
SL
122 /// At least one single import will define the name in the namespace.
123 AtLeastOne,
124}
125
126impl<'a> Default for SingleImports<'a> {
9e0c209e 127 /// Creates a `SingleImports<'a>` of None type.
54a0048b
SL
128 fn default() -> Self {
129 SingleImports::None
130 }
131}
132
133impl<'a> SingleImports<'a> {
83c7162d 134 fn add_directive(&mut self, directive: &'a ImportDirective<'a>, use_extern_macros: bool) {
54a0048b
SL
135 match *self {
136 SingleImports::None => *self = SingleImports::MaybeOne(directive),
83c7162d
XL
137 SingleImports::MaybeOne(directive_one) => *self = if use_extern_macros {
138 SingleImports::MaybeTwo(directive_one, directive)
139 } else {
140 SingleImports::AtLeastOne
141 },
142 // If three single imports can define the name in the namespace, we can assume that at
143 // least one of them will define it since otherwise we'd get duplicate errors in one of
144 // other namespaces.
145 SingleImports::MaybeTwo(..) => *self = SingleImports::AtLeastOne,
54a0048b
SL
146 SingleImports::AtLeastOne => {}
147 };
148 }
149
83c7162d 150 fn directive_failed(&mut self, dir: &'a ImportDirective<'a>) {
54a0048b
SL
151 match *self {
152 SingleImports::None => unreachable!(),
153 SingleImports::MaybeOne(_) => *self = SingleImports::None,
83c7162d
XL
154 SingleImports::MaybeTwo(dir1, dir2) =>
155 *self = SingleImports::MaybeOne(if ptr::eq(dir1, dir) { dir1 } else { dir2 }),
54a0048b
SL
156 SingleImports::AtLeastOne => {}
157 }
158 }
9cc50fc6
SL
159}
160
7453a54e 161impl<'a> NameResolution<'a> {
54a0048b
SL
162 // Returns the binding for the name if it is known or None if it not known.
163 fn binding(&self) -> Option<&'a NameBinding<'a>> {
164 self.binding.and_then(|binding| match self.single_imports {
165 SingleImports::None => Some(binding),
a7813a04 166 _ if !binding.is_glob_import() => Some(binding),
54a0048b
SL
167 _ => None, // The binding could be shadowed by a single import, so it is not known.
168 })
169 }
9e0c209e
SL
170}
171
172impl<'a> Resolver<'a> {
32a655c1 173 fn resolution(&self, module: Module<'a>, ident: Ident, ns: Namespace)
9e0c209e 174 -> &'a RefCell<NameResolution<'a>> {
7cac9316 175 *module.resolutions.borrow_mut().entry((ident.modern(), ns))
9e0c209e
SL
176 .or_insert_with(|| self.arenas.alloc_name_resolution())
177 }
178
32a655c1 179 /// Attempts to resolve `ident` in namespaces `ns` of `module`.
9e0c209e 180 /// Invariant: if `record_used` is `Some`, import resolution must be complete.
7cac9316
XL
181 pub fn resolve_ident_in_module_unadjusted(&mut self,
182 module: Module<'a>,
183 ident: Ident,
184 ns: Namespace,
185 restricted_shadowing: bool,
186 record_used: bool,
187 path_span: Span)
188 -> Result<&'a NameBinding<'a>, Determinacy> {
9e0c209e
SL
189 self.populate_module_if_necessary(module);
190
32a655c1 191 let resolution = self.resolution(module, ident, ns)
476ff2be
SL
192 .try_borrow_mut()
193 .map_err(|_| Determined)?; // This happens when there is a cycle of imports
9e0c209e 194
7cac9316 195 if record_used {
9e0c209e 196 if let Some(binding) = resolution.binding {
476ff2be 197 if let Some(shadowed_glob) = resolution.shadows_glob {
32a655c1 198 let name = ident.name;
cc61c64b
XL
199 // Forbid expanded shadowing to avoid time travel.
200 if restricted_shadowing &&
476ff2be
SL
201 binding.expansion != Mark::root() &&
202 ns != MacroNS && // In MacroNS, `try_define` always forbids this shadowing
203 binding.def() != shadowed_glob.def() {
204 self.ambiguity_errors.push(AmbiguityError {
7cac9316 205 span: path_span,
3b2f2976 206 name,
7cac9316
XL
207 lexical: false,
208 b1: binding,
209 b2: shadowed_glob,
476ff2be
SL
210 });
211 }
9e0c209e 212 }
7cac9316 213 if self.record_use(ident, ns, binding, path_span) {
476ff2be 214 return Ok(self.dummy_binding);
9e0c209e
SL
215 }
216 if !self.is_accessible(binding.vis) {
7cac9316 217 self.privacy_errors.push(PrivacyError(path_span, ident.name, binding));
9e0c209e
SL
218 }
219 }
220
476ff2be 221 return resolution.binding.ok_or(Determined);
9e0c209e
SL
222 }
223
476ff2be 224 let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
0531ce1d 225 // `extern crate` are always usable for backwards compatibility, see issue #37020.
476ff2be
SL
226 let usable = this.is_accessible(binding.vis) || binding.is_extern_crate();
227 if usable { Ok(binding) } else { Err(Determined) }
228 };
9e0c209e 229
476ff2be
SL
230 // Items and single imports are not shadowable.
231 if let Some(binding) = resolution.binding {
232 if !binding.is_glob_import() {
233 return check_usable(self, binding);
9e0c209e
SL
234 }
235 }
236
54a0048b 237 // Check if a single import can still define the name.
83c7162d
XL
238 let resolve_single_import = |this: &mut Self, directive: &'a ImportDirective<'a>| {
239 let module = match directive.imported_module.get() {
240 Some(module) => module,
241 None => return false,
242 };
243 let ident = match directive.subclass {
244 SingleImport { source, .. } => source,
245 _ => unreachable!(),
246 };
247 match this.resolve_ident_in_module(module, ident, ns, false, false, path_span) {
248 Err(Determined) => {}
249 _ => return false,
250 }
251 true
252 };
9e0c209e 253 match resolution.single_imports {
476ff2be 254 SingleImports::AtLeastOne => return Err(Undetermined),
83c7162d
XL
255 SingleImports::MaybeOne(directive) => {
256 let accessible = self.is_accessible(directive.vis.get());
257 if accessible {
258 if !resolve_single_import(self, directive) {
259 return Err(Undetermined)
260 }
261 }
262 }
263 SingleImports::MaybeTwo(directive1, directive2) => {
264 let accessible1 = self.is_accessible(directive1.vis.get());
265 let accessible2 = self.is_accessible(directive2.vis.get());
266 if accessible1 && accessible2 {
267 if !resolve_single_import(self, directive1) &&
268 !resolve_single_import(self, directive2) {
269 return Err(Undetermined)
270 }
271 } else if accessible1 {
272 if !resolve_single_import(self, directive1) {
273 return Err(Undetermined)
274 }
275 } else {
276 if !resolve_single_import(self, directive2) {
277 return Err(Undetermined)
278 }
54a0048b 279 }
7453a54e 280 }
83c7162d 281 SingleImports::None => {},
7453a54e 282 }
c34b1796 283
476ff2be 284 let no_unresolved_invocations =
cc61c64b 285 restricted_shadowing || module.unresolved_invocations.borrow().is_empty();
476ff2be
SL
286 match resolution.binding {
287 // In `MacroNS`, expanded bindings do not shadow (enforced in `try_define`).
288 Some(binding) if no_unresolved_invocations || ns == MacroNS =>
289 return check_usable(self, binding),
290 None if no_unresolved_invocations => {}
291 _ => return Err(Undetermined),
292 }
293
294 // Check if the globs are determined
cc61c64b
XL
295 if restricted_shadowing && module.def().is_some() {
296 return Err(Determined);
297 }
476ff2be 298 for directive in module.globs.borrow().iter() {
7cac9316
XL
299 if !self.is_accessible(directive.vis.get()) {
300 continue
301 }
302 let module = unwrap_or!(directive.imported_module.get(), return Err(Undetermined));
303 let (orig_current_module, mut ident) = (self.current_module, ident.modern());
83c7162d 304 match ident.span.glob_adjust(module.expansion, directive.span.ctxt().modern()) {
7cac9316
XL
305 Some(Some(def)) => self.current_module = self.macro_def_scope(def),
306 Some(None) => {}
307 None => continue,
308 };
309 let result = self.resolve_ident_in_module_unadjusted(
310 module, ident, ns, false, false, path_span,
311 );
312 self.current_module = orig_current_module;
313 if let Err(Undetermined) = result {
314 return Err(Undetermined);
476ff2be
SL
315 }
316 }
317
318 Err(Determined)
54a0048b
SL
319 }
320
9e0c209e
SL
321 // Add an import directive to the current module.
322 pub fn add_import_directive(&mut self,
83c7162d 323 module_path: Vec<Ident>,
9e0c209e 324 subclass: ImportDirectiveSubclass<'a>,
54a0048b
SL
325 span: Span,
326 id: NodeId,
94b46f34
XL
327 root_span: Span,
328 root_id: NodeId,
476ff2be
SL
329 vis: ty::Visibility,
330 expansion: Mark) {
9e0c209e 331 let current_module = self.current_module;
54a0048b 332 let directive = self.arenas.alloc_import_directive(ImportDirective {
9e0c209e 333 parent: current_module,
3b2f2976 334 module_path,
9e0c209e 335 imported_module: Cell::new(None),
3b2f2976
XL
336 subclass,
337 span,
338 id,
94b46f34
XL
339 root_span,
340 root_id,
9e0c209e 341 vis: Cell::new(vis),
3b2f2976 342 expansion,
32a655c1 343 used: Cell::new(false),
54a0048b
SL
344 });
345
9e0c209e 346 self.indeterminate_imports.push(directive);
54a0048b 347 match directive.subclass {
94b46f34
XL
348 SingleImport { target, type_ns_only, .. } => {
349 self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
476ff2be 350 let mut resolution = this.resolution(current_module, target, ns).borrow_mut();
83c7162d 351 resolution.single_imports.add_directive(directive, this.use_extern_macros);
476ff2be 352 });
7453a54e 353 }
54a0048b
SL
354 // We don't add prelude imports to the globs since they only affect lexical scopes,
355 // which are not relevant to import resolution.
9e0c209e
SL
356 GlobImport { is_prelude: true, .. } => {}
357 GlobImport { .. } => self.current_module.globs.borrow_mut().push(directive),
476ff2be 358 _ => unreachable!(),
c34b1796 359 }
54a0048b 360 }
5bcae85e 361
5bcae85e
SL
362 // Given a binding and an import directive that resolves to it,
363 // return the corresponding binding defined by the import directive.
32a655c1
SL
364 pub fn import(&self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
365 -> &'a NameBinding<'a> {
9e0c209e 366 let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) ||
041b39d2
XL
367 // c.f. `PUB_USE_OF_PRIVATE_EXTERN_CRATE`
368 !directive.is_glob() && binding.is_extern_crate() {
9e0c209e
SL
369 directive.vis.get()
370 } else {
371 binding.pseudo_vis()
372 };
373
374 if let GlobImport { ref max_vis, .. } = directive.subclass {
375 if vis == directive.vis.get() || vis.is_at_least(max_vis.get(), self) {
376 max_vis.set(vis)
377 }
378 }
379
32a655c1 380 self.arenas.alloc_name_binding(NameBinding {
5bcae85e 381 kind: NameBindingKind::Import {
3b2f2976
XL
382 binding,
383 directive,
9e0c209e 384 used: Cell::new(false),
5bcae85e
SL
385 },
386 span: directive.span,
3b2f2976 387 vis,
476ff2be 388 expansion: directive.expansion,
32a655c1 389 })
5bcae85e 390 }
54a0048b 391
5bcae85e 392 // Define the name or return the existing binding if there is a collision.
32a655c1
SL
393 pub fn try_define(&mut self,
394 module: Module<'a>,
395 ident: Ident,
396 ns: Namespace,
397 binding: &'a NameBinding<'a>)
398 -> Result<(), &'a NameBinding<'a>> {
399 self.update_resolution(module, ident, ns, |this, resolution| {
5bcae85e
SL
400 if let Some(old_binding) = resolution.binding {
401 if binding.is_glob_import() {
476ff2be
SL
402 if !old_binding.is_glob_import() &&
403 !(ns == MacroNS && old_binding.expansion != Mark::root()) {
404 resolution.shadows_glob = Some(binding);
9e0c209e 405 } else if binding.def() != old_binding.def() {
476ff2be 406 resolution.binding = Some(this.ambiguity(old_binding, binding));
32a655c1 407 } else if !old_binding.vis.is_at_least(binding.vis, &*this) {
9e0c209e
SL
408 // We are glob-importing the same item but with greater visibility.
409 resolution.binding = Some(binding);
410 }
5bcae85e 411 } else if old_binding.is_glob_import() {
476ff2be
SL
412 if ns == MacroNS && binding.expansion != Mark::root() &&
413 binding.def() != old_binding.def() {
414 resolution.binding = Some(this.ambiguity(binding, old_binding));
415 } else {
416 resolution.binding = Some(binding);
417 resolution.shadows_glob = Some(old_binding);
418 }
5bcae85e
SL
419 } else {
420 return Err(old_binding);
421 }
422 } else {
423 resolution.binding = Some(binding);
424 }
425
426 Ok(())
427 })
428 }
429
32a655c1 430 pub fn ambiguity(&self, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>)
476ff2be
SL
431 -> &'a NameBinding<'a> {
432 self.arenas.alloc_name_binding(NameBinding {
94b46f34 433 kind: NameBindingKind::Ambiguity { b1, b2 },
476ff2be
SL
434 vis: if b1.vis.is_at_least(b2.vis, self) { b1.vis } else { b2.vis },
435 span: b1.span,
436 expansion: Mark::root(),
437 })
438 }
439
5bcae85e 440 // Use `f` to mutate the resolution of the name in the module.
54a0048b 441 // If the resolution becomes a success, define it in the module's glob importers.
32a655c1
SL
442 fn update_resolution<T, F>(&mut self, module: Module<'a>, ident: Ident, ns: Namespace, f: F)
443 -> T
5bcae85e 444 where F: FnOnce(&mut Resolver<'a>, &mut NameResolution<'a>) -> T
54a0048b 445 {
5bcae85e
SL
446 // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
447 // during which the resolution might end up getting re-defined via a glob cycle.
9e0c209e 448 let (binding, t) = {
3b2f2976 449 let resolution = &mut *self.resolution(module, ident, ns).borrow_mut();
9e0c209e 450 let old_binding = resolution.binding();
54a0048b 451
5bcae85e 452 let t = f(self, resolution);
54a0048b 453
54a0048b 454 match resolution.binding() {
476ff2be 455 _ if old_binding.is_some() => return t,
54a0048b 456 None => return t,
9e0c209e
SL
457 Some(binding) => match old_binding {
458 Some(old_binding) if old_binding as *const _ == binding as *const _ => return t,
459 _ => (binding, t),
460 }
54a0048b
SL
461 }
462 };
c34b1796 463
9e0c209e
SL
464 // Define `binding` in `module`s glob importers.
465 for directive in module.glob_importers.borrow_mut().iter() {
7cac9316 466 let mut ident = ident.modern();
83c7162d 467 let scope = match ident.span.reverse_glob_adjust(module.expansion,
ea8adc8c 468 directive.span.ctxt().modern()) {
7cac9316
XL
469 Some(Some(def)) => self.macro_def_scope(def),
470 Some(None) => directive.parent,
471 None => continue,
472 };
473 if self.is_accessible_from(binding.vis, scope) {
9e0c209e 474 let imported_binding = self.import(binding, directive);
32a655c1 475 let _ = self.try_define(directive.parent, ident, ns, imported_binding);
5bcae85e 476 }
54a0048b 477 }
5bcae85e
SL
478
479 t
c34b1796 480 }
476ff2be
SL
481
482 // Define a "dummy" resolution containing a Def::Err as a placeholder for a
483 // failed resolution
484 fn import_dummy_binding(&mut self, directive: &'a ImportDirective<'a>) {
485 if let SingleImport { target, .. } = directive.subclass {
486 let dummy_binding = self.dummy_binding;
487 let dummy_binding = self.import(dummy_binding, directive);
488 self.per_ns(|this, ns| {
32a655c1 489 let _ = this.try_define(directive.parent, target, ns, dummy_binding);
476ff2be
SL
490 });
491 }
492 }
c34b1796
AL
493}
494
476ff2be
SL
495pub struct ImportResolver<'a, 'b: 'a> {
496 pub resolver: &'a mut Resolver<'b>,
c34b1796
AL
497}
498
5bcae85e
SL
499impl<'a, 'b: 'a> ::std::ops::Deref for ImportResolver<'a, 'b> {
500 type Target = Resolver<'b>;
501 fn deref(&self) -> &Resolver<'b> {
502 self.resolver
503 }
504}
505
506impl<'a, 'b: 'a> ::std::ops::DerefMut for ImportResolver<'a, 'b> {
507 fn deref_mut(&mut self) -> &mut Resolver<'b> {
508 self.resolver
509 }
510}
511
32a655c1
SL
512impl<'a, 'b: 'a> ty::DefIdTree for &'a ImportResolver<'a, 'b> {
513 fn parent(self, id: DefId) -> Option<DefId> {
514 self.resolver.parent(id)
5bcae85e
SL
515 }
516}
517
a7813a04 518impl<'a, 'b:'a> ImportResolver<'a, 'b> {
c34b1796
AL
519 // Import resolution
520 //
521 // This is a fixed-point algorithm. We resolve imports until our efforts
522 // are stymied by an unresolved import; then we bail out of the current
523 // module and continue. We terminate successfully once no more imports
524 // remain or unsuccessfully when no forward progress in resolving imports
525 // is made.
526
527 /// Resolves all imports for the crate. This method performs the fixed-
528 /// point iteration.
476ff2be 529 pub fn resolve_imports(&mut self) {
9e0c209e 530 let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1;
9e0c209e
SL
531 while self.indeterminate_imports.len() < prev_num_indeterminates {
532 prev_num_indeterminates = self.indeterminate_imports.len();
476ff2be 533 for import in mem::replace(&mut self.indeterminate_imports, Vec::new()) {
9e0c209e 534 match self.resolve_import(&import) {
476ff2be
SL
535 true => self.determined_imports.push(import),
536 false => self.indeterminate_imports.push(import),
a7813a04 537 }
c34b1796 538 }
9e0c209e 539 }
476ff2be 540 }
9e0c209e 541
476ff2be 542 pub fn finalize_imports(&mut self) {
9e0c209e
SL
543 for module in self.arenas.local_modules().iter() {
544 self.finalize_resolutions_in(module);
545 }
546
547 let mut errors = false;
3b2f2976 548 let mut seen_spans = FxHashSet();
9e0c209e
SL
549 for i in 0 .. self.determined_imports.len() {
550 let import = self.determined_imports[i];
3b2f2976 551 if let Some((span, err)) = self.finalize_import(import) {
9e0c209e 552 errors = true;
9e0c209e 553
041b39d2
XL
554 if let SingleImport { source, ref result, .. } = import.subclass {
555 if source.name == "self" {
556 // Silence `unresolved import` error if E0429 is already emitted
557 match result.value_ns.get() {
558 Err(Determined) => continue,
559 _ => {},
560 }
561 }
562 }
563
9e0c209e
SL
564 // If the error is a single failed import then create a "fake" import
565 // resolution for it so that later resolve stages won't complain.
566 self.import_dummy_binding(import);
3b2f2976
XL
567 if !seen_spans.contains(&span) {
568 let path = import_path_to_string(&import.module_path[..],
569 &import.subclass,
570 span);
571 let error = ResolutionError::UnresolvedImport(Some((span, &path, &err)));
572 resolve_error(self.resolver, span, error);
573 seen_spans.insert(span);
574 }
c34b1796 575 }
9e0c209e 576 }
c34b1796 577
9e0c209e
SL
578 // Report unresolved imports only if no hard error was already reported
579 // to avoid generating multiple errors on the same import.
580 if !errors {
581 if let Some(import) = self.indeterminate_imports.iter().next() {
582 let error = ResolutionError::UnresolvedImport(None);
583 resolve_error(self.resolver, import.span, error);
584 }
c34b1796
AL
585 }
586 }
587
476ff2be 588 /// Attempts to resolve the given import, returning true if its resolution is determined.
c34b1796 589 /// If successful, the resolved bindings are written into the module.
476ff2be 590 fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool {
c34b1796 591 debug!("(resolving import for module) resolving import `{}::...` in `{}`",
3b2f2976 592 names_to_string(&directive.module_path[..]),
2c00a5a8 593 module_to_string(self.current_module).unwrap_or("???".to_string()));
54a0048b 594
9e0c209e
SL
595 self.current_module = directive.parent;
596
597 let module = if let Some(module) = directive.imported_module.get() {
598 module
599 } else {
600 let vis = directive.vis.get();
601 // For better failure detection, pretend that the import will not define any names
602 // while resolving its module path.
32a655c1 603 directive.vis.set(ty::Visibility::Invisible);
83c7162d 604 let result = self.resolve_path(&directive.module_path[..], None, false,
94b46f34 605 directive.span, directive.crate_lint());
9e0c209e
SL
606 directive.vis.set(vis);
607
608 match result {
476ff2be
SL
609 PathResult::Module(module) => module,
610 PathResult::Indeterminate => return false,
611 _ => return true,
9e0c209e 612 }
c34b1796
AL
613 };
614
9e0c209e 615 directive.imported_module.set(Some(module));
32a655c1
SL
616 let (source, target, result, type_ns_only) = match directive.subclass {
617 SingleImport { source, target, ref result, type_ns_only } =>
618 (source, target, result, type_ns_only),
9e0c209e
SL
619 GlobImport { .. } => {
620 self.resolve_glob_import(directive);
476ff2be 621 return true;
9e0c209e 622 }
476ff2be 623 _ => unreachable!(),
54a0048b 624 };
c34b1796 625
9e0c209e 626 let mut indeterminate = false;
32a655c1 627 self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
476ff2be 628 if let Err(Undetermined) = result[ns].get() {
7cac9316
XL
629 result[ns].set(this.resolve_ident_in_module(module,
630 source,
631 ns,
632 false,
633 false,
634 directive.span));
9e0c209e 635 } else {
476ff2be 636 return
9e0c209e
SL
637 };
638
32a655c1 639 let parent = directive.parent;
476ff2be 640 match result[ns].get() {
9e0c209e
SL
641 Err(Undetermined) => indeterminate = true,
642 Err(Determined) => {
32a655c1 643 this.update_resolution(parent, target, ns, |_, resolution| {
83c7162d 644 resolution.single_imports.directive_failed(directive)
5bcae85e
SL
645 });
646 }
9e0c209e 647 Ok(binding) if !binding.is_importable() => {
54a0048b 648 let msg = format!("`{}` is not directly importable", target);
476ff2be 649 struct_span_err!(this.session, directive.span, E0253, "{}", &msg)
7cac9316 650 .span_label(directive.span, "cannot be imported directly")
5bcae85e
SL
651 .emit();
652 // Do not import this illegal binding. Import a dummy binding and pretend
653 // everything is fine
476ff2be 654 this.import_dummy_binding(directive);
54a0048b 655 }
9e0c209e 656 Ok(binding) => {
476ff2be 657 let imported_binding = this.import(binding, directive);
32a655c1 658 let conflict = this.try_define(parent, target, ns, imported_binding);
5bcae85e 659 if let Err(old_binding) = conflict {
32a655c1 660 this.report_conflict(parent, target, ns, imported_binding, old_binding);
5bcae85e 661 }
54a0048b 662 }
54a0048b 663 }
476ff2be 664 });
c34b1796 665
476ff2be 666 !indeterminate
9e0c209e
SL
667 }
668
476ff2be 669 // If appropriate, returns an error to report.
3b2f2976 670 fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Span, String)> {
9e0c209e 671 self.current_module = directive.parent;
9e0c209e 672 let ImportDirective { ref module_path, span, .. } = *directive;
94b46f34 673 let mut warn_if_binding_comes_from_local_crate = false;
ff7c6d11 674
2c00a5a8
XL
675 // FIXME: Last path segment is treated specially in import resolution, so extern crate
676 // mode for absolute paths needs some special support for single-segment imports.
83c7162d
XL
677 if module_path.len() == 1 && (module_path[0].name == keywords::CrateRoot.name() ||
678 module_path[0].name == keywords::Extern.name()) {
679 let is_extern = module_path[0].name == keywords::Extern.name() ||
680 (self.session.features_untracked().extern_absolute_paths &&
681 self.session.rust_2018());
ff7c6d11 682 match directive.subclass {
2c00a5a8 683 GlobImport { .. } if is_extern => {
ff7c6d11
XL
684 return Some((directive.span,
685 "cannot glob-import all possible crates".to_string()));
686 }
94b46f34
XL
687 GlobImport { .. } if self.session.features_untracked().extern_absolute_paths => {
688 self.lint_path_starts_with_module(
689 directive.root_id,
690 directive.root_span,
691 );
692 }
ff7c6d11 693 SingleImport { source, target, .. } => {
2c00a5a8 694 let crate_root = if source.name == keywords::Crate.name() &&
83c7162d 695 module_path[0].name != keywords::Extern.name() {
ff7c6d11
XL
696 if target.name == keywords::Crate.name() {
697 return Some((directive.span,
698 "crate root imports need to be explicitly named: \
699 `use crate as name;`".to_string()));
700 } else {
83c7162d 701 Some(self.resolve_crate_root(source.span.ctxt().modern(), false))
ff7c6d11 702 }
94b46f34 703 } else if is_extern && !source.is_path_segment_keyword() {
ff7c6d11 704 let crate_id =
83c7162d
XL
705 self.resolver.crate_loader.process_use_extern(
706 source.name,
707 directive.span,
708 directive.id,
709 &self.resolver.definitions,
710 );
ff7c6d11
XL
711 let crate_root =
712 self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
713 self.populate_module_if_necessary(crate_root);
714 Some(crate_root)
715 } else {
94b46f34 716 warn_if_binding_comes_from_local_crate = true;
ff7c6d11
XL
717 None
718 };
719
720 if let Some(crate_root) = crate_root {
721 let binding = (crate_root, ty::Visibility::Public, directive.span,
722 directive.expansion).to_name_binding(self.arenas);
723 let binding = self.arenas.alloc_name_binding(NameBinding {
724 kind: NameBindingKind::Import {
725 binding,
726 directive,
727 used: Cell::new(false),
ff7c6d11
XL
728 },
729 vis: directive.vis.get(),
730 span: directive.span,
731 expansion: directive.expansion,
732 });
733 let _ = self.try_define(directive.parent, target, TypeNS, binding);
734 return None;
735 }
736 }
737 _ => {}
738 }
739 }
740
94b46f34
XL
741 let module_result = self.resolve_path(
742 &module_path,
743 None,
744 true,
745 span,
746 directive.crate_lint(),
747 );
9e0c209e 748 let module = match module_result {
476ff2be 749 PathResult::Module(module) => module,
ff7c6d11
XL
750 PathResult::Failed(span, msg, false) => {
751 resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
752 return None;
753 }
754 PathResult::Failed(span, msg, true) => {
32a655c1 755 let (mut self_path, mut self_result) = (module_path.clone(), None);
94b46f34
XL
756 let is_special = |ident: Ident| ident.is_path_segment_keyword() &&
757 ident.name != keywords::CrateRoot.name();
83c7162d
XL
758 if !self_path.is_empty() && !is_special(self_path[0]) &&
759 !(self_path.len() > 1 && is_special(self_path[1])) {
760 self_path[0].name = keywords::SelfValue.name();
761 self_result = Some(self.resolve_path(&self_path, None, false,
94b46f34 762 span, CrateLint::No));
32a655c1
SL
763 }
764 return if let Some(PathResult::Module(..)) = self_result {
3b2f2976 765 Some((span, format!("Did you mean `{}`?", names_to_string(&self_path[..]))))
9e0c209e 766 } else {
3b2f2976 767 Some((span, msg))
9e0c209e
SL
768 };
769 },
476ff2be 770 _ => return None,
9e0c209e
SL
771 };
772
32a655c1
SL
773 let (ident, result, type_ns_only) = match directive.subclass {
774 SingleImport { source, ref result, type_ns_only, .. } => (source, result, type_ns_only),
9e0c209e
SL
775 GlobImport { .. } if module.def_id() == directive.parent.def_id() => {
776 // Importing a module into itself is not allowed.
3b2f2976
XL
777 return Some((directive.span,
778 "Cannot glob-import a module into itself.".to_string()));
9e0c209e
SL
779 }
780 GlobImport { is_prelude, ref max_vis } => {
781 if !is_prelude &&
32a655c1
SL
782 max_vis.get() != ty::Visibility::Invisible && // Allow empty globs.
783 !max_vis.get().is_at_least(directive.vis.get(), &*self) {
9e0c209e
SL
784 let msg = "A non-empty glob must import something with the glob's visibility";
785 self.session.span_err(directive.span, msg);
786 }
476ff2be 787 return None;
9e0c209e 788 }
476ff2be 789 _ => unreachable!(),
9e0c209e
SL
790 };
791
476ff2be 792 let mut all_ns_err = true;
32a655c1 793 self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
476ff2be
SL
794 if let Ok(binding) = result[ns].get() {
795 all_ns_err = false;
32a655c1
SL
796 if this.record_use(ident, ns, binding, directive.span) {
797 this.resolution(module, ident, ns).borrow_mut().binding =
476ff2be 798 Some(this.dummy_binding);
9e0c209e
SL
799 }
800 }
476ff2be 801 });
9e0c209e 802
476ff2be
SL
803 if all_ns_err {
804 let mut all_ns_failed = true;
32a655c1 805 self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
7cac9316 806 match this.resolve_ident_in_module(module, ident, ns, false, true, span) {
476ff2be
SL
807 Ok(_) => all_ns_failed = false,
808 _ => {}
809 }
810 });
9e0c209e 811
476ff2be 812 return if all_ns_failed {
9e0c209e 813 let resolutions = module.resolutions.borrow();
32a655c1
SL
814 let names = resolutions.iter().filter_map(|(&(ref i, _), resolution)| {
815 if *i == ident { return None; } // Never suggest the same name
54a0048b 816 match *resolution.borrow() {
8bb4bdeb
XL
817 NameResolution { binding: Some(name_binding), .. } => {
818 match name_binding.kind {
819 NameBindingKind::Import { binding, .. } => {
820 match binding.kind {
821 // Never suggest the name that has binding error
822 // i.e. the name that cannot be previously resolved
823 NameBindingKind::Def(Def::Err) => return None,
824 _ => Some(&i.name),
825 }
826 },
827 _ => Some(&i.name),
828 }
829 },
54a0048b 830 NameResolution { single_imports: SingleImports::None, .. } => None,
32a655c1 831 _ => Some(&i.name),
54a0048b
SL
832 }
833 });
32a655c1 834 let lev_suggestion =
94b46f34 835 match find_best_match_for_name(names, &ident.as_str(), None) {
32a655c1
SL
836 Some(name) => format!(". Did you mean to use `{}`?", name),
837 None => "".to_owned(),
838 };
9e0c209e 839 let module_str = module_to_string(module);
2c00a5a8 840 let msg = if let Some(module_str) = module_str {
32a655c1 841 format!("no `{}` in `{}`{}", ident, module_str, lev_suggestion)
2c00a5a8
XL
842 } else {
843 format!("no `{}` in the root{}", ident, lev_suggestion)
a7813a04 844 };
3b2f2976 845 Some((span, msg))
9e0c209e 846 } else {
32a655c1 847 // `resolve_ident_in_module` reported a privacy error.
9e0c209e 848 self.import_dummy_binding(directive);
476ff2be 849 None
7453a54e 850 }
7453a54e 851 }
c34b1796 852
476ff2be
SL
853 let mut reexport_error = None;
854 let mut any_successful_reexport = false;
855 self.per_ns(|this, ns| {
856 if let Ok(binding) = result[ns].get() {
9e0c209e 857 let vis = directive.vis.get();
32a655c1 858 if !binding.pseudo_vis().is_at_least(vis, &*this) {
476ff2be 859 reexport_error = Some((ns, binding));
54a0048b 860 } else {
476ff2be 861 any_successful_reexport = true;
c34b1796
AL
862 }
863 }
476ff2be 864 });
c34b1796 865
476ff2be
SL
866 // All namespaces must be re-exported with extra visibility for an error to occur.
867 if !any_successful_reexport {
868 let (ns, binding) = reexport_error.unwrap();
869 if ns == TypeNS && binding.is_extern_crate() {
2c00a5a8
XL
870 let msg = format!("extern crate `{}` is private, and cannot be \
871 re-exported (error E0365), consider declaring with \
872 `pub`",
32a655c1 873 ident);
3b2f2976
XL
874 self.session.buffer_lint(PUB_USE_OF_PRIVATE_EXTERN_CRATE,
875 directive.id,
876 directive.span,
877 &msg);
476ff2be
SL
878 } else if ns == TypeNS {
879 struct_span_err!(self.session, directive.span, E0365,
2c00a5a8
XL
880 "`{}` is private, and cannot be re-exported", ident)
881 .span_label(directive.span, format!("re-export of private `{}`", ident))
32a655c1 882 .note(&format!("consider declaring type or module `{}` with `pub`", ident))
476ff2be
SL
883 .emit();
884 } else {
2c00a5a8 885 let msg = format!("`{}` is private, and cannot be re-exported", ident);
476ff2be 886 let note_msg =
32a655c1 887 format!("consider marking `{}` as `pub` in the imported module", ident);
476ff2be
SL
888 struct_span_err!(self.session, directive.span, E0364, "{}", &msg)
889 .span_note(directive.span, &note_msg)
890 .emit();
891 }
c34b1796
AL
892 }
893
94b46f34
XL
894 if warn_if_binding_comes_from_local_crate {
895 let mut warned = false;
896 self.per_ns(|this, ns| {
897 let binding = match result[ns].get().ok() {
898 Some(b) => b,
899 None => return
900 };
901 if let NameBindingKind::Import { directive: d, .. } = binding.kind {
902 if let ImportDirectiveSubclass::ExternCrate(..) = d.subclass {
903 return
904 }
905 }
906 if warned {
907 return
908 }
909 warned = true;
910 this.lint_path_starts_with_module(
911 directive.root_id,
912 directive.root_span,
913 );
914 });
915 }
916
c34b1796
AL
917 // Record what this import resolves to for later uses in documentation,
918 // this may resolve to either a value or a type, but for documentation
919 // purposes it's good enough to just favor one over the other.
476ff2be 920 self.per_ns(|this, ns| if let Some(binding) = result[ns].get().ok() {
94b46f34
XL
921 let mut import = this.import_map.entry(directive.id).or_default();
922 import[ns] = Some(PathResolution::new(binding.def()));
476ff2be 923 });
c34b1796
AL
924
925 debug!("(resolving single import) successfully resolved import");
476ff2be 926 None
c34b1796
AL
927 }
928
9e0c209e
SL
929 fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) {
930 let module = directive.imported_module.get().unwrap();
931 self.populate_module_if_necessary(module);
c34b1796 932
9e0c209e
SL
933 if let Some(Def::Trait(_)) = module.def() {
934 self.session.span_err(directive.span, "items in traits are not importable.");
935 return;
936 } else if module.def_id() == directive.parent.def_id() {
937 return;
938 } else if let GlobImport { is_prelude: true, .. } = directive.subclass {
939 self.prelude = Some(module);
940 return;
54a0048b
SL
941 }
942
9e0c209e
SL
943 // Add to module's glob_importers
944 module.glob_importers.borrow_mut().push(directive);
54a0048b 945
5bcae85e 946 // Ensure that `resolutions` isn't borrowed during `try_define`,
54a0048b 947 // since it might get updated via a glob cycle.
32a655c1
SL
948 let bindings = module.resolutions.borrow().iter().filter_map(|(&ident, resolution)| {
949 resolution.borrow().binding().map(|binding| (ident, binding))
54a0048b 950 }).collect::<Vec<_>>();
7cac9316 951 for ((mut ident, ns), binding) in bindings {
83c7162d 952 let scope = match ident.span.reverse_glob_adjust(module.expansion,
ea8adc8c 953 directive.span.ctxt().modern()) {
7cac9316
XL
954 Some(Some(def)) => self.macro_def_scope(def),
955 Some(None) => self.current_module,
956 None => continue,
957 };
958 if self.is_accessible_from(binding.pseudo_vis(), scope) {
5bcae85e 959 let imported_binding = self.import(binding, directive);
32a655c1 960 let _ = self.try_define(directive.parent, ident, ns, imported_binding);
7453a54e 961 }
54a0048b 962 }
c34b1796 963
c34b1796 964 // Record the destination of this import
32a655c1 965 self.record_def(directive.id, PathResolution::new(module.def().unwrap()));
c34b1796
AL
966 }
967
2c00a5a8 968 // Miscellaneous post-processing, including recording re-exports,
7cac9316 969 // reporting conflicts, and reporting unresolved imports.
9e0c209e 970 fn finalize_resolutions_in(&mut self, module: Module<'b>) {
54a0048b
SL
971 // Since import resolution is finished, globs will not define any more names.
972 *module.globs.borrow_mut() = Vec::new();
973
974 let mut reexports = Vec::new();
cc61c64b 975 let mut exported_macro_names = FxHashMap();
476ff2be 976 if module as *const _ == self.graph_root as *const _ {
cc61c64b
XL
977 let macro_exports = mem::replace(&mut self.macro_exports, Vec::new());
978 for export in macro_exports.into_iter().rev() {
94b46f34
XL
979 if let Some(later_span) = exported_macro_names.insert(export.ident.modern(),
980 export.span) {
981 self.session.buffer_lint_with_diagnostic(
982 DUPLICATE_MACRO_EXPORTS,
983 CRATE_NODE_ID,
984 later_span,
985 &format!("a macro named `{}` has already been exported", export.ident),
986 BuiltinLintDiagnostics::DuplicatedMacroExports(
987 export.ident, export.span, later_span));
988 } else {
476ff2be
SL
989 reexports.push(export);
990 }
991 }
992 }
993
32a655c1 994 for (&(ident, ns), resolution) in module.resolutions.borrow().iter() {
476ff2be 995 let resolution = &mut *resolution.borrow_mut();
54a0048b
SL
996 let binding = match resolution.binding {
997 Some(binding) => binding,
998 None => continue,
999 };
1000
ff7c6d11 1001 if binding.is_import() || binding.is_macro_def() {
9e0c209e
SL
1002 let def = binding.def();
1003 if def != Def::Err {
476ff2be 1004 if !def.def_id().is_local() {
ea8adc8c 1005 self.cstore.export_macros_untracked(def.def_id().krate);
476ff2be 1006 }
cc61c64b 1007 if let Def::Macro(..) = def {
7cac9316 1008 if let Some(&span) = exported_macro_names.get(&ident.modern()) {
cc61c64b
XL
1009 let msg =
1010 format!("a macro named `{}` has already been exported", ident);
1011 self.session.struct_span_err(span, &msg)
7cac9316 1012 .span_label(span, format!("`{}` already exported", ident))
cc61c64b
XL
1013 .span_note(binding.span, "previous macro export here")
1014 .emit();
1015 }
1016 }
ff7c6d11
XL
1017 reexports.push(Export {
1018 ident: ident.modern(),
1019 def: def,
1020 span: binding.span,
1021 vis: binding.vis,
ff7c6d11 1022 });
54a0048b
SL
1023 }
1024 }
1025
476ff2be 1026 match binding.kind {
ff7c6d11 1027 NameBindingKind::Import { binding: orig_binding, directive, .. } => {
476ff2be 1028 if ns == TypeNS && orig_binding.is_variant() &&
ff7c6d11
XL
1029 !orig_binding.vis.is_at_least(binding.vis, &*self) {
1030 let msg = match directive.subclass {
1031 ImportDirectiveSubclass::SingleImport { .. } => {
2c00a5a8 1032 format!("variant `{}` is private and cannot be re-exported",
ff7c6d11
XL
1033 ident)
1034 },
1035 ImportDirectiveSubclass::GlobImport { .. } => {
1036 let msg = "enum is private and its variants \
2c00a5a8 1037 cannot be re-exported".to_owned();
ff7c6d11
XL
1038 let error_id = (DiagnosticMessageId::ErrorId(0), // no code?!
1039 Some(binding.span),
1040 msg.clone());
1041 let fresh = self.session.one_time_diagnostics
1042 .borrow_mut().insert(error_id);
1043 if !fresh {
1044 continue;
1045 }
1046 msg
1047 },
1048 ref s @ _ => bug!("unexpected import subclass {:?}", s)
1049 };
1050 let mut err = self.session.struct_span_err(binding.span, &msg);
1051
1052 let imported_module = directive.imported_module.get()
1053 .expect("module should exist");
1054 let resolutions = imported_module.parent.expect("parent should exist")
1055 .resolutions.borrow();
1056 let enum_path_segment_index = directive.module_path.len() - 1;
83c7162d 1057 let enum_ident = directive.module_path[enum_path_segment_index];
ff7c6d11
XL
1058
1059 let enum_resolution = resolutions.get(&(enum_ident, TypeNS))
1060 .expect("resolution should exist");
1061 let enum_span = enum_resolution.borrow()
1062 .binding.expect("binding should exist")
1063 .span;
1064 let enum_def_span = self.session.codemap().def_span(enum_span);
1065 let enum_def_snippet = self.session.codemap()
1066 .span_to_snippet(enum_def_span).expect("snippet should exist");
1067 // potentially need to strip extant `crate`/`pub(path)` for suggestion
1068 let after_vis_index = enum_def_snippet.find("enum")
1069 .expect("`enum` keyword should exist in snippet");
1070 let suggestion = format!("pub {}",
1071 &enum_def_snippet[after_vis_index..]);
1072
1073 self.session
1074 .diag_span_suggestion_once(&mut err,
1075 DiagnosticMessageId::ErrorId(0),
1076 enum_def_span,
1077 "consider making the enum public",
1078 suggestion);
1079 err.emit();
476ff2be
SL
1080 }
1081 }
476ff2be 1082 _ => {}
c34b1796 1083 }
c34b1796 1084 }
c34b1796 1085
54a0048b
SL
1086 if reexports.len() > 0 {
1087 if let Some(def_id) = module.def_id() {
ea8adc8c 1088 self.export_map.insert(def_id, reexports);
54a0048b 1089 }
c34b1796 1090 }
c34b1796
AL
1091 }
1092}
1093
83c7162d 1094fn import_path_to_string(names: &[Ident],
3b2f2976
XL
1095 subclass: &ImportDirectiveSubclass,
1096 span: Span) -> String {
1097 let pos = names.iter()
83c7162d
XL
1098 .position(|p| span == p.span && p.name != keywords::CrateRoot.name());
1099 let global = !names.is_empty() && names[0].name == keywords::CrateRoot.name();
3b2f2976
XL
1100 if let Some(pos) = pos {
1101 let names = if global { &names[1..pos + 1] } else { &names[..pos + 1] };
1102 names_to_string(names)
c34b1796 1103 } else {
3b2f2976
XL
1104 let names = if global { &names[1..] } else { names };
1105 if names.is_empty() {
1106 import_directive_subclass_to_string(subclass)
1107 } else {
0531ce1d
XL
1108 format!("{}::{}",
1109 names_to_string(names),
1110 import_directive_subclass_to_string(subclass))
3b2f2976 1111 }
c34b1796
AL
1112 }
1113}
1114
54a0048b
SL
1115fn import_directive_subclass_to_string(subclass: &ImportDirectiveSubclass) -> String {
1116 match *subclass {
1117 SingleImport { source, .. } => source.to_string(),
a7813a04 1118 GlobImport { .. } => "*".to_string(),
abe05a73 1119 ExternCrate(_) => "<extern crate>".to_string(),
32a655c1 1120 MacroUse => "#[macro_use]".to_string(),
c34b1796
AL
1121 }
1122}