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.
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.
11 use self::ImportDirectiveSubclass
::*;
14 use Namespace
::{self, TypeNS, ValueNS}
;
15 use {NameBinding, NameBindingKind, PrivacyError, ToNameBinding}
;
19 use UseLexicalScopeFlag
::DontUseLexicalScope
;
20 use {names_to_string, module_to_string}
;
21 use {resolve_error, ResolutionError}
;
24 use rustc
::lint
::builtin
::PRIVATE_IN_PUBLIC
;
25 use rustc
::hir
::def
::*;
27 use syntax
::ast
::{NodeId, Name}
;
28 use syntax
::util
::lev_distance
::find_best_match_for_name
;
29 use syntax_pos
::{Span, DUMMY_SP}
;
31 use std
::cell
::{Cell, RefCell}
;
33 impl<'a
> Resolver
<'a
> {
34 pub fn resolve_imports(&mut self) {
35 ImportResolver { resolver: self }
.resolve_imports();
39 /// Contains data for specific types of import directives.
40 #[derive(Clone, Debug)]
41 pub enum ImportDirectiveSubclass
{
45 type_determined
: Cell
<bool
>,
46 value_determined
: Cell
<bool
>,
48 GlobImport { is_prelude: bool }
,
51 impl ImportDirectiveSubclass
{
52 pub fn single(target
: Name
, source
: Name
) -> Self {
56 type_determined
: Cell
::new(false),
57 value_determined
: Cell
::new(false),
62 /// One import directive.
63 #[derive(Debug,Clone)]
64 pub struct ImportDirective
<'a
> {
66 module_path
: Vec
<Name
>,
67 target_module
: Cell
<Option
<Module
<'a
>>>, // the resolution of `module_path`
68 subclass
: ImportDirectiveSubclass
,
70 vis
: ty
::Visibility
, // see note in ImportResolutionPerNamespace about how to use this
73 impl<'a
> ImportDirective
<'a
> {
74 pub fn is_glob(&self) -> bool
{
75 match self.subclass { ImportDirectiveSubclass::GlobImport { .. }
=> true, _
=> false }
79 #[derive(Clone, Default)]
80 /// Records information about the resolution of a name in a namespace of a module.
81 pub struct NameResolution
<'a
> {
82 /// The single imports that define the name in the namespace.
83 single_imports
: SingleImports
<'a
>,
84 /// The least shadowable known binding for this name, or None if there are no known bindings.
85 pub binding
: Option
<&'a NameBinding
<'a
>>,
86 duplicate_globs
: Vec
<&'a NameBinding
<'a
>>,
89 #[derive(Clone, Debug)]
90 enum SingleImports
<'a
> {
91 /// No single imports can define the name in the namespace.
93 /// Only the given single import can define the name in the namespace.
94 MaybeOne(&'a ImportDirective
<'a
>),
95 /// At least one single import will define the name in the namespace.
99 impl<'a
> Default
for SingleImports
<'a
> {
100 fn default() -> Self {
105 impl<'a
> SingleImports
<'a
> {
106 fn add_directive(&mut self, directive
: &'a ImportDirective
<'a
>) {
108 SingleImports
::None
=> *self = SingleImports
::MaybeOne(directive
),
109 // If two single imports can define the name in the namespace, we can assume that at
110 // least one of them will define it since otherwise both would have to define only one
111 // namespace, leading to a duplicate error.
112 SingleImports
::MaybeOne(_
) => *self = SingleImports
::AtLeastOne
,
113 SingleImports
::AtLeastOne
=> {}
117 fn directive_failed(&mut self) {
119 SingleImports
::None
=> unreachable
!(),
120 SingleImports
::MaybeOne(_
) => *self = SingleImports
::None
,
121 SingleImports
::AtLeastOne
=> {}
126 impl<'a
> NameResolution
<'a
> {
127 // Returns the binding for the name if it is known or None if it not known.
128 fn binding(&self) -> Option
<&'a NameBinding
<'a
>> {
129 self.binding
.and_then(|binding
| match self.single_imports
{
130 SingleImports
::None
=> Some(binding
),
131 _
if !binding
.is_glob_import() => Some(binding
),
132 _
=> None
, // The binding could be shadowed by a single import, so it is not known.
136 // Returns Some(the resolution of the name), or None if the resolution depends
137 // on whether more globs can define the name.
138 fn try_result(&self, ns
: Namespace
, allow_private_imports
: bool
)
139 -> Option
<ResolveResult
<&'a NameBinding
<'a
>>> {
141 Some(binding
) if !binding
.is_glob_import() =>
142 return Some(Success(binding
)),
143 _
=> {}
// Items and single imports are not shadowable
146 // Check if a single import can still define the name.
147 match self.single_imports
{
148 SingleImports
::None
=> {}
,
149 SingleImports
::AtLeastOne
=> return Some(Indeterminate
),
150 SingleImports
::MaybeOne(directive
) => {
151 // If (1) we don't allow private imports, (2) no public single import can define
152 // the name, and (3) no public glob has defined the name, the resolution depends
153 // on whether more globs can define the name.
154 if !allow_private_imports
&& directive
.vis
!= ty
::Visibility
::Public
&&
155 !self.binding
.map(NameBinding
::is_pseudo_public
).unwrap_or(false) {
159 let target_module
= match directive
.target_module
.get() {
160 Some(target_module
) => target_module
,
161 None
=> return Some(Indeterminate
),
163 let name
= match directive
.subclass
{
164 SingleImport { source, .. }
=> source
,
165 GlobImport { .. }
=> unreachable
!(),
167 match target_module
.resolve_name(name
, ns
, false) {
169 _
=> return Some(Indeterminate
),
174 self.binding
.map(Success
)
178 impl<'a
> ::ModuleS
<'a
> {
179 fn resolution(&self, name
: Name
, ns
: Namespace
) -> &'a RefCell
<NameResolution
<'a
>> {
180 *self.resolutions
.borrow_mut().entry((name
, ns
))
181 .or_insert_with(|| self.arenas
.alloc_name_resolution())
184 pub fn resolve_name(&self, name
: Name
, ns
: Namespace
, allow_private_imports
: bool
)
185 -> ResolveResult
<&'a NameBinding
<'a
>> {
186 let resolution
= self.resolution(name
, ns
);
187 let resolution
= match resolution
.borrow_state() {
188 ::std
::cell
::BorrowState
::Unused
=> resolution
.borrow_mut(),
189 _
=> return Failed(None
), // This happens when there is a cycle of imports
192 if let Some(result
) = resolution
.try_result(ns
, allow_private_imports
) {
193 // If the resolution doesn't depend on glob definability, check privacy and return.
194 return result
.and_then(|binding
| {
195 let allowed
= allow_private_imports
|| !binding
.is_import() ||
196 binding
.is_pseudo_public();
197 if allowed { Success(binding) }
else { Failed(None) }
201 // Check if the globs are determined
202 for directive
in self.globs
.borrow().iter() {
203 if !allow_private_imports
&& directive
.vis
!= ty
::Visibility
::Public { continue }
204 match directive
.target_module
.get() {
205 None
=> return Indeterminate
,
206 Some(target_module
) => match target_module
.resolve_name(name
, ns
, false) {
207 Indeterminate
=> return Indeterminate
,
216 pub fn add_import_directive(&self,
217 module_path
: Vec
<Name
>,
218 subclass
: ImportDirectiveSubclass
,
221 vis
: ty
::Visibility
) {
222 let directive
= self.arenas
.alloc_import_directive(ImportDirective
{
223 module_path
: module_path
,
224 target_module
: Cell
::new(None
),
231 self.unresolved_imports
.borrow_mut().push(directive
);
232 match directive
.subclass
{
233 SingleImport { target, .. }
=> {
234 for &ns
in &[ValueNS
, TypeNS
] {
235 self.resolution(target
, ns
).borrow_mut().single_imports
236 .add_directive(directive
);
239 // We don't add prelude imports to the globs since they only affect lexical scopes,
240 // which are not relevant to import resolution.
241 GlobImport { is_prelude: true }
=> {}
242 GlobImport { .. }
=> self.globs
.borrow_mut().push(directive
),
247 impl<'a
> Resolver
<'a
> {
248 // Given a binding and an import directive that resolves to it,
249 // return the corresponding binding defined by the import directive.
250 fn import(&mut self, binding
: &'a NameBinding
<'a
>, directive
: &'a ImportDirective
<'a
>)
253 kind
: NameBindingKind
::Import
{
255 directive
: directive
,
257 span
: directive
.span
,
262 // Define the name or return the existing binding if there is a collision.
263 pub fn try_define
<T
>(&mut self, module
: Module
<'a
>, name
: Name
, ns
: Namespace
, binding
: T
)
264 -> Result
<(), &'a NameBinding
<'a
>>
265 where T
: ToNameBinding
<'a
>
267 let binding
= self.arenas
.alloc_name_binding(binding
.to_name_binding());
268 self.update_resolution(module
, name
, ns
, |_
, resolution
| {
269 if let Some(old_binding
) = resolution
.binding
{
270 if binding
.is_glob_import() {
271 resolution
.duplicate_globs
.push(binding
);
272 } else if old_binding
.is_glob_import() {
273 resolution
.duplicate_globs
.push(old_binding
);
274 resolution
.binding
= Some(binding
);
276 return Err(old_binding
);
279 resolution
.binding
= Some(binding
);
286 // Use `f` to mutate the resolution of the name in the module.
287 // If the resolution becomes a success, define it in the module's glob importers.
288 fn update_resolution
<T
, F
>(&mut self, module
: Module
<'a
>, name
: Name
, ns
: Namespace
, f
: F
) -> T
289 where F
: FnOnce(&mut Resolver
<'a
>, &mut NameResolution
<'a
>) -> T
291 // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
292 // during which the resolution might end up getting re-defined via a glob cycle.
293 let (new_binding
, t
) = {
294 let mut resolution
= &mut *module
.resolution(name
, ns
).borrow_mut();
295 let was_known
= resolution
.binding().is_some();
297 let t
= f(self, resolution
);
299 if was_known { return t; }
300 match resolution
.binding() {
301 Some(binding
) => (binding
, t
),
306 // Define `new_binding` in `module`s glob importers.
307 if new_binding
.is_importable() && new_binding
.is_pseudo_public() {
308 for &(importer
, directive
) in module
.glob_importers
.borrow_mut().iter() {
309 let imported_binding
= self.import(new_binding
, directive
);
310 let _
= self.try_define(importer
, name
, ns
, imported_binding
);
318 struct ImportResolvingError
<'a
> {
319 /// Module where the error happened
320 source_module
: Module
<'a
>,
321 import_directive
: &'a ImportDirective
<'a
>,
326 struct ImportResolver
<'a
, 'b
: 'a
> {
327 resolver
: &'a
mut Resolver
<'b
>,
330 impl<'a
, 'b
: 'a
> ::std
::ops
::Deref
for ImportResolver
<'a
, 'b
> {
331 type Target
= Resolver
<'b
>;
332 fn deref(&self) -> &Resolver
<'b
> {
337 impl<'a
, 'b
: 'a
> ::std
::ops
::DerefMut
for ImportResolver
<'a
, 'b
> {
338 fn deref_mut(&mut self) -> &mut Resolver
<'b
> {
343 impl<'a
, 'b
: 'a
> ty
::NodeIdTree
for ImportResolver
<'a
, 'b
> {
344 fn is_descendant_of(&self, node
: NodeId
, ancestor
: NodeId
) -> bool
{
345 self.resolver
.is_descendant_of(node
, ancestor
)
349 impl<'a
, 'b
:'a
> ImportResolver
<'a
, 'b
> {
352 // This is a fixed-point algorithm. We resolve imports until our efforts
353 // are stymied by an unresolved import; then we bail out of the current
354 // module and continue. We terminate successfully once no more imports
355 // remain or unsuccessfully when no forward progress in resolving imports
358 /// Resolves all imports for the crate. This method performs the fixed-
360 fn resolve_imports(&mut self) {
362 let mut prev_unresolved_imports
= 0;
363 let mut errors
= Vec
::new();
366 debug
!("(resolving imports) iteration {}, {} imports left", i
, self.unresolved_imports
);
368 // Attempt to resolve imports in all local modules.
369 for module
in self.arenas
.local_modules().iter() {
370 self.current_module
= module
;
371 self.resolve_imports_in_current_module(&mut errors
);
374 if self.unresolved_imports
== 0 {
375 debug
!("(resolving imports) success");
376 for module
in self.arenas
.local_modules().iter() {
377 self.finalize_resolutions_in(module
, false);
382 if self.unresolved_imports
== prev_unresolved_imports
{
384 // Report unresolved imports only if no hard error was already reported
385 // to avoid generating multiple errors on the same import.
386 // Imports that are still indeterminate at this point are actually blocked
387 // by errored imports, so there is no point reporting them.
388 for module
in self.arenas
.local_modules().iter() {
389 self.finalize_resolutions_in(module
, errors
.len() == 0);
392 self.import_resolving_error(e
)
398 prev_unresolved_imports
= self.unresolved_imports
;
402 // Define a "dummy" resolution containing a Def::Err as a placeholder for a
404 fn import_dummy_binding(&mut self,
405 source_module
: Module
<'b
>,
406 directive
: &'b ImportDirective
<'b
>) {
407 if let SingleImport { target, .. }
= directive
.subclass
{
408 let dummy_binding
= self.arenas
.alloc_name_binding(NameBinding
{
409 kind
: NameBindingKind
::Def(Def
::Err
),
411 vis
: ty
::Visibility
::Public
,
413 let dummy_binding
= self.import(dummy_binding
, directive
);
415 let _
= self.try_define(source_module
, target
, ValueNS
, dummy_binding
.clone());
416 let _
= self.try_define(source_module
, target
, TypeNS
, dummy_binding
);
420 /// Resolves an `ImportResolvingError` into the correct enum discriminant
421 /// and passes that on to `resolve_error`.
422 fn import_resolving_error(&mut self, e
: ImportResolvingError
<'b
>) {
423 // If the error is a single failed import then create a "fake" import
424 // resolution for it so that later resolve stages won't complain.
425 self.import_dummy_binding(e
.source_module
, e
.import_directive
);
426 let path
= import_path_to_string(&e
.import_directive
.module_path
,
427 &e
.import_directive
.subclass
);
428 resolve_error(self.resolver
,
430 ResolutionError
::UnresolvedImport(Some((&path
, &e
.help
))));
433 /// Attempts to resolve imports for the given module only.
434 fn resolve_imports_in_current_module(&mut self, errors
: &mut Vec
<ImportResolvingError
<'b
>>) {
435 let mut imports
= Vec
::new();
436 let mut unresolved_imports
= self.current_module
.unresolved_imports
.borrow_mut();
437 ::std
::mem
::swap(&mut imports
, &mut unresolved_imports
);
439 for import_directive
in imports
{
440 match self.resolve_import(&import_directive
) {
442 let (span
, help
) = match err
{
443 Some((span
, msg
)) => (span
, format
!(". {}", msg
)),
444 None
=> (import_directive
.span
, String
::new()),
446 errors
.push(ImportResolvingError
{
447 source_module
: self.current_module
,
448 import_directive
: import_directive
,
453 Indeterminate
=> unresolved_imports
.push(import_directive
),
455 // Decrement the count of unresolved imports.
456 assert
!(self.unresolved_imports
>= 1);
457 self.unresolved_imports
-= 1;
463 /// Attempts to resolve the given import. The return value indicates
464 /// failure if we're certain the name does not exist, indeterminate if we
465 /// don't know whether the name exists at the moment due to other
466 /// currently-unresolved imports, or success if we know the name exists.
467 /// If successful, the resolved bindings are written into the module.
468 fn resolve_import(&mut self, directive
: &'b ImportDirective
<'b
>) -> ResolveResult
<()> {
469 debug
!("(resolving import for module) resolving import `{}::...` in `{}`",
470 names_to_string(&directive
.module_path
),
471 module_to_string(self.current_module
));
473 let target_module
= match directive
.target_module
.get() {
474 Some(module
) => module
,
475 _
=> match self.resolve_module_path(&directive
.module_path
,
478 Success(module
) => module
,
479 Indeterminate
=> return Indeterminate
,
480 Failed(err
) => return Failed(err
),
484 directive
.target_module
.set(Some(target_module
));
485 let (source
, target
, value_determined
, type_determined
) = match directive
.subclass
{
486 SingleImport { source, target, ref value_determined, ref type_determined }
=>
487 (source
, target
, value_determined
, type_determined
),
488 GlobImport { .. }
=> return self.resolve_glob_import(target_module
, directive
),
491 // We need to resolve both namespaces for this to succeed.
492 let value_result
= self.resolve_name_in_module(target_module
, source
, ValueNS
, false, true);
493 let type_result
= self.resolve_name_in_module(target_module
, source
, TypeNS
, false, true);
495 let module
= self.current_module
;
496 let mut privacy_error
= true;
497 for &(ns
, result
, determined
) in &[(ValueNS
, &value_result
, value_determined
),
498 (TypeNS
, &type_result
, type_determined
)] {
500 Failed(..) if !determined
.get() => {
501 determined
.set(true);
502 self.update_resolution(module
, target
, ns
, |_
, resolution
| {
503 resolution
.single_imports
.directive_failed()
506 Success(binding
) if !binding
.is_importable() => {
507 let msg
= format
!("`{}` is not directly importable", target
);
508 struct_span_err
!(self.session
, directive
.span
, E0253
, "{}", &msg
)
509 .span_label(directive
.span
, &format
!("cannot be imported directly"))
511 // Do not import this illegal binding. Import a dummy binding and pretend
512 // everything is fine
513 self.import_dummy_binding(module
, directive
);
516 Success(binding
) if !self.is_accessible(binding
.vis
) => {}
517 Success(binding
) if !determined
.get() => {
518 determined
.set(true);
519 let imported_binding
= self.import(binding
, directive
);
520 let conflict
= self.try_define(module
, target
, ns
, imported_binding
);
521 if let Err(old_binding
) = conflict
{
522 let binding
= &self.import(binding
, directive
);
523 self.report_conflict(module
, target
, ns
, binding
, old_binding
);
525 privacy_error
= false;
527 Success(_
) => privacy_error
= false,
532 match (&value_result
, &type_result
) {
533 (&Indeterminate
, _
) | (_
, &Indeterminate
) => return Indeterminate
,
534 (&Failed(_
), &Failed(_
)) => {
535 let resolutions
= target_module
.resolutions
.borrow();
536 let names
= resolutions
.iter().filter_map(|(&(ref name
, _
), resolution
)| {
537 if *name
== source { return None; }
// Never suggest the same name
538 match *resolution
.borrow() {
539 NameResolution { binding: Some(_), .. }
=> Some(name
),
540 NameResolution { single_imports: SingleImports::None, .. }
=> None
,
544 let lev_suggestion
= match find_best_match_for_name(names
, &source
.as_str(), None
) {
545 Some(name
) => format
!(". Did you mean to use `{}`?", name
),
546 None
=> "".to_owned(),
548 let module_str
= module_to_string(target_module
);
549 let msg
= if &module_str
== "???" {
550 format
!("There is no `{}` in the crate root{}", source
, lev_suggestion
)
552 format
!("There is no `{}` in `{}`{}", source
, module_str
, lev_suggestion
)
554 return Failed(Some((directive
.span
, msg
)));
560 for &(ns
, result
) in &[(ValueNS
, &value_result
), (TypeNS
, &type_result
)] {
561 let binding
= match *result { Success(binding) => binding, _ => continue }
;
562 self.privacy_errors
.push(PrivacyError(directive
.span
, source
, binding
));
563 let imported_binding
= self.import(binding
, directive
);
564 let _
= self.try_define(module
, target
, ns
, imported_binding
);
568 match (&value_result
, &type_result
) {
569 (&Success(binding
), _
) if !binding
.pseudo_vis().is_at_least(directive
.vis
, self) &&
570 self.is_accessible(binding
.vis
) => {
571 let msg
= format
!("`{}` is private, and cannot be reexported", source
);
572 let note_msg
= format
!("consider marking `{}` as `pub` in the imported module",
574 struct_span_err
!(self.session
, directive
.span
, E0364
, "{}", &msg
)
575 .span_note(directive
.span
, ¬e_msg
)
579 (_
, &Success(binding
)) if !binding
.pseudo_vis().is_at_least(directive
.vis
, self) &&
580 self.is_accessible(binding
.vis
) => {
581 if binding
.is_extern_crate() {
582 let msg
= format
!("extern crate `{}` is private, and cannot be reexported \
583 (error E0364), consider declaring with `pub`",
585 self.session
.add_lint(PRIVATE_IN_PUBLIC
, directive
.id
, directive
.span
, msg
);
587 let msg
= format
!("`{}` is private, and cannot be reexported", source
);
589 format
!("consider declaring type or module `{}` with `pub`", source
);
590 struct_span_err
!(self.session
, directive
.span
, E0365
, "{}", &msg
)
591 .span_note(directive
.span
, ¬e_msg
)
599 // Record what this import resolves to for later uses in documentation,
600 // this may resolve to either a value or a type, but for documentation
601 // purposes it's good enough to just favor one over the other.
602 let def
= match type_result
.success().and_then(NameBinding
::def
) {
604 None
=> value_result
.success().and_then(NameBinding
::def
).unwrap(),
606 let path_resolution
= PathResolution
::new(def
);
607 self.def_map
.insert(directive
.id
, path_resolution
);
609 debug
!("(resolving single import) successfully resolved import");
613 // Resolves a glob import. Note that this function cannot fail; it either
614 // succeeds or bails out (as importing * from an empty module or a module
615 // that exports nothing is valid). target_module is the module we are
616 // actually importing, i.e., `foo` in `use foo::*`.
617 fn resolve_glob_import(&mut self, target_module
: Module
<'b
>, directive
: &'b ImportDirective
<'b
>)
618 -> ResolveResult
<()> {
619 if let Some(Def
::Trait(_
)) = target_module
.def
{
620 self.session
.span_err(directive
.span
, "items in traits are not importable.");
623 let module
= self.current_module
;
624 if module
.def_id() == target_module
.def_id() {
625 // This means we are trying to glob import a module into itself, and it is a no-go
626 let msg
= "Cannot glob-import a module into itself.".into();
627 return Failed(Some((directive
.span
, msg
)));
629 self.populate_module_if_necessary(target_module
);
631 if let GlobImport { is_prelude: true }
= directive
.subclass
{
632 self.prelude
= Some(target_module
);
636 // Add to target_module's glob_importers
637 target_module
.glob_importers
.borrow_mut().push((module
, directive
));
639 // Ensure that `resolutions` isn't borrowed during `try_define`,
640 // since it might get updated via a glob cycle.
641 let bindings
= target_module
.resolutions
.borrow().iter().filter_map(|(name
, resolution
)| {
642 resolution
.borrow().binding().map(|binding
| (*name
, binding
))
643 }).collect
::<Vec
<_
>>();
644 for ((name
, ns
), binding
) in bindings
{
645 if binding
.is_importable() && binding
.is_pseudo_public() {
646 let imported_binding
= self.import(binding
, directive
);
647 let _
= self.try_define(module
, name
, ns
, imported_binding
);
651 // Record the destination of this import
652 if let Some(did
) = target_module
.def_id() {
653 let resolution
= PathResolution
::new(Def
::Mod(did
));
654 self.def_map
.insert(directive
.id
, resolution
);
657 debug
!("(resolving glob import) successfully resolved import");
661 // Miscellaneous post-processing, including recording reexports, reporting conflicts,
662 // reporting the PRIVATE_IN_PUBLIC lint, and reporting unresolved imports.
663 fn finalize_resolutions_in(&mut self, module
: Module
<'b
>, report_unresolved_imports
: bool
) {
664 // Since import resolution is finished, globs will not define any more names.
665 *module
.globs
.borrow_mut() = Vec
::new();
667 let mut reexports
= Vec
::new();
668 for (&(name
, ns
), resolution
) in module
.resolutions
.borrow().iter() {
669 let resolution
= resolution
.borrow();
670 let binding
= match resolution
.binding
{
671 Some(binding
) => binding
,
676 for duplicate_glob
in resolution
.duplicate_globs
.iter() {
677 // FIXME #31337: We currently allow items to shadow glob-imported re-exports.
678 if !binding
.is_import() {
679 if let NameBindingKind
::Import { binding, .. }
= duplicate_glob
.kind
{
680 if binding
.is_import() { continue }
684 self.report_conflict(module
, name
, ns
, duplicate_glob
, binding
);
687 if binding
.vis
== ty
::Visibility
::Public
&&
688 (binding
.is_import() || binding
.is_extern_crate()) {
689 if let Some(def
) = binding
.def() {
690 reexports
.push(Export { name: name, def_id: def.def_id() }
);
694 if let NameBindingKind
::Import { binding: orig_binding, directive, .. }
= binding
.kind
{
695 if ns
== TypeNS
&& orig_binding
.is_variant() &&
696 !orig_binding
.vis
.is_at_least(binding
.vis
, self) {
697 let msg
= format
!("variant `{}` is private, and cannot be reexported \
698 (error E0364), consider declaring its enum as `pub`",
700 self.session
.add_lint(PRIVATE_IN_PUBLIC
, directive
.id
, binding
.span
, msg
);
705 if reexports
.len() > 0 {
706 if let Some(def_id
) = module
.def_id() {
707 let node_id
= self.definitions
.as_local_node_id(def_id
).unwrap();
708 self.export_map
.insert(node_id
, reexports
);
712 if report_unresolved_imports
{
713 for import
in module
.unresolved_imports
.borrow().iter() {
714 resolve_error(self.resolver
, import
.span
, ResolutionError
::UnresolvedImport(None
));
721 fn import_path_to_string(names
: &[Name
], subclass
: &ImportDirectiveSubclass
) -> String
{
722 if names
.is_empty() {
723 import_directive_subclass_to_string(subclass
)
726 names_to_string(names
),
727 import_directive_subclass_to_string(subclass
)))
732 fn import_directive_subclass_to_string(subclass
: &ImportDirectiveSubclass
) -> String
{
734 SingleImport { source, .. }
=> source
.to_string(),
735 GlobImport { .. }
=> "*".to_string(),