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
::*;
15 use Namespace
::{self, TypeNS, ValueNS}
;
16 use {NameBinding, NameBindingKind, PrivacyError}
;
20 use UseLexicalScopeFlag
::DontUseLexicalScope
;
21 use {names_to_string, module_to_string}
;
22 use {resolve_error, ResolutionError}
;
25 use rustc
::hir
::def
::*;
27 use syntax
::ast
::{NodeId, Name}
;
28 use syntax
::attr
::AttrMetaMethods
;
29 use syntax
::codemap
::Span
;
30 use syntax
::util
::lev_distance
::find_best_match_for_name
;
32 use std
::mem
::replace
;
33 use std
::cell
::{Cell, RefCell}
;
35 /// Contains data for specific types of import directives.
36 #[derive(Clone, Debug)]
37 pub enum ImportDirectiveSubclass
{
41 type_determined
: Cell
<bool
>,
42 value_determined
: Cell
<bool
>,
47 impl ImportDirectiveSubclass
{
48 pub fn single(target
: Name
, source
: Name
) -> Self {
52 type_determined
: Cell
::new(false),
53 value_determined
: Cell
::new(false),
58 /// One import directive.
59 #[derive(Debug,Clone)]
60 pub struct ImportDirective
<'a
> {
61 module_path
: Vec
<Name
>,
62 target_module
: Cell
<Option
<Module
<'a
>>>, // the resolution of `module_path`
63 subclass
: ImportDirectiveSubclass
,
66 is_public
: bool
, // see note in ImportResolutionPerNamespace about how to use this
70 impl<'a
> ImportDirective
<'a
> {
71 // Given the binding to which this directive resolves in a particular namespace,
72 // this returns the binding for the name this directive defines in that namespace.
73 fn import(&self, binding
: &'a NameBinding
<'a
>, privacy_error
: Option
<Box
<PrivacyError
<'a
>>>)
75 let mut modifiers
= match self.is_public
{
76 true => DefModifiers
::PUBLIC
| DefModifiers
::IMPORTABLE
,
77 false => DefModifiers
::empty(),
79 if let GlobImport
= self.subclass
{
80 modifiers
= modifiers
| DefModifiers
::GLOB_IMPORTED
;
84 kind
: NameBindingKind
::Import
{
87 privacy_error
: privacy_error
,
89 span
: Some(self.span
),
95 #[derive(Clone, Default)]
96 /// Records information about the resolution of a name in a namespace of a module.
97 pub struct NameResolution
<'a
> {
98 /// The single imports that define the name in the namespace.
99 single_imports
: SingleImports
<'a
>,
100 /// The least shadowable known binding for this name, or None if there are no known bindings.
101 pub binding
: Option
<&'a NameBinding
<'a
>>,
102 duplicate_globs
: Vec
<&'a NameBinding
<'a
>>,
105 #[derive(Clone, Debug)]
106 enum SingleImports
<'a
> {
107 /// No single imports can define the name in the namespace.
109 /// Only the given single import can define the name in the namespace.
110 MaybeOne(&'a ImportDirective
<'a
>),
111 /// At least one single import will define the name in the namespace.
115 impl<'a
> Default
for SingleImports
<'a
> {
116 fn default() -> Self {
121 impl<'a
> SingleImports
<'a
> {
122 fn add_directive(&mut self, directive
: &'a ImportDirective
<'a
>) {
124 SingleImports
::None
=> *self = SingleImports
::MaybeOne(directive
),
125 // If two single imports can define the name in the namespace, we can assume that at
126 // least one of them will define it since otherwise both would have to define only one
127 // namespace, leading to a duplicate error.
128 SingleImports
::MaybeOne(_
) => *self = SingleImports
::AtLeastOne
,
129 SingleImports
::AtLeastOne
=> {}
133 fn directive_failed(&mut self) {
135 SingleImports
::None
=> unreachable
!(),
136 SingleImports
::MaybeOne(_
) => *self = SingleImports
::None
,
137 SingleImports
::AtLeastOne
=> {}
142 impl<'a
> NameResolution
<'a
> {
143 fn try_define(&mut self, binding
: &'a NameBinding
<'a
>) -> Result
<(), &'a NameBinding
<'a
>> {
144 if let Some(old_binding
) = self.binding
{
145 if binding
.defined_with(DefModifiers
::GLOB_IMPORTED
) {
146 self.duplicate_globs
.push(binding
);
147 } else if old_binding
.defined_with(DefModifiers
::GLOB_IMPORTED
) {
148 self.duplicate_globs
.push(old_binding
);
149 self.binding
= Some(binding
);
151 return Err(old_binding
);
154 self.binding
= Some(binding
);
160 // Returns the binding for the name if it is known or None if it not known.
161 fn binding(&self) -> Option
<&'a NameBinding
<'a
>> {
162 self.binding
.and_then(|binding
| match self.single_imports
{
163 SingleImports
::None
=> Some(binding
),
164 _
if !binding
.defined_with(DefModifiers
::GLOB_IMPORTED
) => Some(binding
),
165 _
=> None
, // The binding could be shadowed by a single import, so it is not known.
169 // Returns Some(the resolution of the name), or None if the resolution depends
170 // on whether more globs can define the name.
171 fn try_result(&self, ns
: Namespace
, allow_private_imports
: bool
)
172 -> Option
<ResolveResult
<&'a NameBinding
<'a
>>> {
174 Some(binding
) if !binding
.defined_with(DefModifiers
::GLOB_IMPORTED
) =>
175 return Some(Success(binding
)),
176 _
=> {}
// Items and single imports are not shadowable
179 // Check if a single import can still define the name.
180 match self.single_imports
{
181 SingleImports
::None
=> {}
,
182 SingleImports
::AtLeastOne
=> return Some(Indeterminate
),
183 SingleImports
::MaybeOne(directive
) => {
184 // If (1) we don't allow private imports, (2) no public single import can define
185 // the name, and (3) no public glob has defined the name, the resolution depends
186 // on whether more globs can define the name.
187 if !allow_private_imports
&& !directive
.is_public
&&
188 !self.binding
.map(NameBinding
::is_public
).unwrap_or(false) {
192 let target_module
= match directive
.target_module
.get() {
193 Some(target_module
) => target_module
,
194 None
=> return Some(Indeterminate
),
196 let name
= match directive
.subclass
{
197 SingleImport { source, .. }
=> source
,
198 GlobImport
=> unreachable
!(),
200 match target_module
.resolve_name(name
, ns
, false) {
202 _
=> return Some(Indeterminate
),
207 self.binding
.map(Success
)
210 fn report_conflicts
<F
: FnMut(&NameBinding
, &NameBinding
)>(&self, mut report
: F
) {
211 let binding
= match self.binding
{
212 Some(binding
) => binding
,
216 for duplicate_glob
in self.duplicate_globs
.iter() {
217 // FIXME #31337: We currently allow items to shadow glob-imported re-exports.
218 if !binding
.is_import() {
219 if let NameBindingKind
::Import { binding, .. }
= duplicate_glob
.kind
{
220 if binding
.is_import() { continue }
224 report(duplicate_glob
, binding
);
229 impl<'a
> ::ModuleS
<'a
> {
230 fn resolution(&self, name
: Name
, ns
: Namespace
) -> &'a RefCell
<NameResolution
<'a
>> {
231 *self.resolutions
.borrow_mut().entry((name
, ns
))
232 .or_insert_with(|| self.arenas
.alloc_name_resolution())
235 pub fn resolve_name(&self, name
: Name
, ns
: Namespace
, allow_private_imports
: bool
)
236 -> ResolveResult
<&'a NameBinding
<'a
>> {
237 let resolution
= self.resolution(name
, ns
);
238 let resolution
= match resolution
.borrow_state() {
239 ::std
::cell
::BorrowState
::Unused
=> resolution
.borrow_mut(),
240 _
=> return Failed(None
), // This happens when there is a cycle of imports
243 if let Some(result
) = resolution
.try_result(ns
, allow_private_imports
) {
244 // If the resolution doesn't depend on glob definability, check privacy and return.
245 return result
.and_then(|binding
| {
246 let allowed
= allow_private_imports
|| !binding
.is_import() || binding
.is_public();
247 if allowed { Success(binding) }
else { Failed(None) }
251 // Check if the globs are determined
252 for directive
in self.globs
.borrow().iter() {
253 if !allow_private_imports
&& !directive
.is_public { continue }
254 match directive
.target_module
.get() {
255 None
=> return Indeterminate
,
256 Some(target_module
) => match target_module
.resolve_name(name
, ns
, false) {
257 Indeterminate
=> return Indeterminate
,
266 // Invariant: this may not be called until import resolution is complete.
267 pub fn resolve_name_in_lexical_scope(&self, name
: Name
, ns
: Namespace
)
268 -> Option
<&'a NameBinding
<'a
>> {
269 self.resolution(name
, ns
).borrow().binding
270 .or_else(|| self.prelude
.borrow().and_then(|prelude
| {
271 prelude
.resolve_name(name
, ns
, false).success()
275 // Define the name or return the existing binding if there is a collision.
276 pub fn try_define_child(&self, name
: Name
, ns
: Namespace
, binding
: NameBinding
<'a
>)
277 -> Result
<(), &'a NameBinding
<'a
>> {
278 self.update_resolution(name
, ns
, |resolution
| {
279 resolution
.try_define(self.arenas
.alloc_name_binding(binding
))
283 pub fn add_import_directive(&self,
284 module_path
: Vec
<Name
>,
285 subclass
: ImportDirectiveSubclass
,
290 let directive
= self.arenas
.alloc_import_directive(ImportDirective
{
291 module_path
: module_path
,
292 target_module
: Cell
::new(None
),
296 is_public
: is_public
,
297 is_prelude
: is_prelude
,
300 self.unresolved_imports
.borrow_mut().push(directive
);
301 match directive
.subclass
{
302 SingleImport { target, .. }
=> {
303 for &ns
in &[ValueNS
, TypeNS
] {
304 self.resolution(target
, ns
).borrow_mut().single_imports
305 .add_directive(directive
);
308 // We don't add prelude imports to the globs since they only affect lexical scopes,
309 // which are not relevant to import resolution.
310 GlobImport
if directive
.is_prelude
=> {}
311 GlobImport
=> self.globs
.borrow_mut().push(directive
),
315 // Use `update` to mutate the resolution for the name.
316 // If the resolution becomes a success, define it in the module's glob importers.
317 fn update_resolution
<T
, F
>(&self, name
: Name
, ns
: Namespace
, update
: F
) -> T
318 where F
: FnOnce(&mut NameResolution
<'a
>) -> T
320 // Ensure that `resolution` isn't borrowed during `define_in_glob_importers`,
321 // where it might end up getting re-defined via a glob cycle.
322 let (new_binding
, t
) = {
323 let mut resolution
= &mut *self.resolution(name
, ns
).borrow_mut();
324 let was_known
= resolution
.binding().is_some();
326 let t
= update(resolution
);
328 if was_known { return t; }
329 match resolution
.binding() {
330 Some(binding
) => (binding
, t
),
335 self.define_in_glob_importers(name
, ns
, new_binding
);
339 fn define_in_glob_importers(&self, name
: Name
, ns
: Namespace
, binding
: &'a NameBinding
<'a
>) {
340 if !binding
.defined_with(DefModifiers
::PUBLIC
| DefModifiers
::IMPORTABLE
) { return }
341 for &(importer
, directive
) in self.glob_importers
.borrow_mut().iter() {
342 let _
= importer
.try_define_child(name
, ns
, directive
.import(binding
, None
));
347 struct ImportResolvingError
<'a
> {
348 /// Module where the error happened
349 source_module
: Module
<'a
>,
350 import_directive
: &'a ImportDirective
<'a
>,
355 struct ImportResolver
<'a
, 'b
: 'a
, 'tcx
: 'b
> {
356 resolver
: &'a
mut Resolver
<'b
, 'tcx
>,
359 impl<'a
, 'b
:'a
, 'tcx
:'b
> ImportResolver
<'a
, 'b
, 'tcx
> {
362 // This is a fixed-point algorithm. We resolve imports until our efforts
363 // are stymied by an unresolved import; then we bail out of the current
364 // module and continue. We terminate successfully once no more imports
365 // remain or unsuccessfully when no forward progress in resolving imports
368 /// Resolves all imports for the crate. This method performs the fixed-
370 fn resolve_imports(&mut self) {
372 let mut prev_unresolved_imports
= 0;
373 let mut errors
= Vec
::new();
376 debug
!("(resolving imports) iteration {}, {} imports left",
378 self.resolver
.unresolved_imports
);
380 self.resolve_imports_for_module_subtree(self.resolver
.graph_root
, &mut errors
);
382 if self.resolver
.unresolved_imports
== 0 {
383 debug
!("(resolving imports) success");
384 self.finalize_resolutions(self.resolver
.graph_root
, false);
388 if self.resolver
.unresolved_imports
== prev_unresolved_imports
{
390 // Report unresolved imports only if no hard error was already reported
391 // to avoid generating multiple errors on the same import.
392 // Imports that are still indeterminate at this point are actually blocked
393 // by errored imports, so there is no point reporting them.
394 self.finalize_resolutions(self.resolver
.graph_root
, errors
.len() == 0);
396 self.import_resolving_error(e
)
402 prev_unresolved_imports
= self.resolver
.unresolved_imports
;
406 /// Resolves an `ImportResolvingError` into the correct enum discriminant
407 /// and passes that on to `resolve_error`.
408 fn import_resolving_error(&self, e
: ImportResolvingError
<'b
>) {
409 // If it's a single failed import then create a "fake" import
410 // resolution for it so that later resolve stages won't complain.
411 if let SingleImport { target, .. }
= e
.import_directive
.subclass
{
412 let dummy_binding
= self.resolver
.arenas
.alloc_name_binding(NameBinding
{
413 modifiers
: DefModifiers
::GLOB_IMPORTED
,
414 kind
: NameBindingKind
::Def(Def
::Err
),
417 let dummy_binding
= e
.import_directive
.import(dummy_binding
, None
);
419 let _
= e
.source_module
.try_define_child(target
, ValueNS
, dummy_binding
.clone());
420 let _
= e
.source_module
.try_define_child(target
, TypeNS
, dummy_binding
);
423 let path
= import_path_to_string(&e
.import_directive
.module_path
,
424 &e
.import_directive
.subclass
);
426 resolve_error(self.resolver
,
428 ResolutionError
::UnresolvedImport(Some((&path
, &e
.help
))));
431 /// Attempts to resolve imports for the given module and all of its
433 fn resolve_imports_for_module_subtree(&mut self,
435 errors
: &mut Vec
<ImportResolvingError
<'b
>>) {
436 debug
!("(resolving imports for module subtree) resolving {}",
437 module_to_string(&module_
));
438 let orig_module
= replace(&mut self.resolver
.current_module
, module_
);
439 self.resolve_imports_in_current_module(errors
);
440 self.resolver
.current_module
= orig_module
;
442 for (_
, child_module
) in module_
.module_children
.borrow().iter() {
443 self.resolve_imports_for_module_subtree(child_module
, errors
);
447 /// Attempts to resolve imports for the given module only.
448 fn resolve_imports_in_current_module(&mut self, errors
: &mut Vec
<ImportResolvingError
<'b
>>) {
449 let mut imports
= Vec
::new();
450 let mut unresolved_imports
= self.resolver
.current_module
.unresolved_imports
.borrow_mut();
451 ::std
::mem
::swap(&mut imports
, &mut unresolved_imports
);
453 for import_directive
in imports
{
454 match self.resolve_import(&import_directive
) {
456 let (span
, help
) = match err
{
457 Some((span
, msg
)) => (span
, format
!(". {}", msg
)),
458 None
=> (import_directive
.span
, String
::new()),
460 errors
.push(ImportResolvingError
{
461 source_module
: self.resolver
.current_module
,
462 import_directive
: import_directive
,
467 Indeterminate
=> unresolved_imports
.push(import_directive
),
469 // Decrement the count of unresolved imports.
470 assert
!(self.resolver
.unresolved_imports
>= 1);
471 self.resolver
.unresolved_imports
-= 1;
477 /// Attempts to resolve the given import. The return value indicates
478 /// failure if we're certain the name does not exist, indeterminate if we
479 /// don't know whether the name exists at the moment due to other
480 /// currently-unresolved imports, or success if we know the name exists.
481 /// If successful, the resolved bindings are written into the module.
482 fn resolve_import(&mut self, directive
: &'b ImportDirective
<'b
>) -> ResolveResult
<()> {
483 debug
!("(resolving import for module) resolving import `{}::...` in `{}`",
484 names_to_string(&directive
.module_path
),
485 module_to_string(self.resolver
.current_module
));
487 let target_module
= match directive
.target_module
.get() {
488 Some(module
) => module
,
489 _
=> match self.resolver
.resolve_module_path(&directive
.module_path
,
492 Success(module
) => module
,
493 Indeterminate
=> return Indeterminate
,
494 Failed(err
) => return Failed(err
),
498 directive
.target_module
.set(Some(target_module
));
499 let (source
, target
, value_determined
, type_determined
) = match directive
.subclass
{
500 SingleImport { source, target, ref value_determined, ref type_determined }
=>
501 (source
, target
, value_determined
, type_determined
),
502 GlobImport
=> return self.resolve_glob_import(target_module
, directive
),
505 // We need to resolve both namespaces for this to succeed.
507 self.resolver
.resolve_name_in_module(target_module
, source
, ValueNS
, false, true);
509 self.resolver
.resolve_name_in_module(target_module
, source
, TypeNS
, false, true);
511 let module_
= self.resolver
.current_module
;
512 for &(ns
, result
, determined
) in &[(ValueNS
, &value_result
, value_determined
),
513 (TypeNS
, &type_result
, type_determined
)] {
514 if determined
.get() { continue }
515 if let Indeterminate
= *result { continue }
517 determined
.set(true);
518 if let Success(binding
) = *result
{
519 if !binding
.defined_with(DefModifiers
::IMPORTABLE
) {
520 let msg
= format
!("`{}` is not directly importable", target
);
521 span_err
!(self.resolver
.session
, directive
.span
, E0253
, "{}", &msg
);
524 let privacy_error
= if !self.resolver
.is_visible(binding
, target_module
) {
525 Some(Box
::new(PrivacyError(directive
.span
, source
, binding
)))
530 let imported_binding
= directive
.import(binding
, privacy_error
);
531 let conflict
= module_
.try_define_child(target
, ns
, imported_binding
);
532 if let Err(old_binding
) = conflict
{
533 let binding
= &directive
.import(binding
, None
);
534 self.resolver
.report_conflict(module_
, target
, ns
, binding
, old_binding
);
537 module_
.update_resolution(target
, ns
, |resolution
| {
538 resolution
.single_imports
.directive_failed();
543 match (&value_result
, &type_result
) {
544 (&Indeterminate
, _
) | (_
, &Indeterminate
) => return Indeterminate
,
545 (&Failed(_
), &Failed(_
)) => {
546 let resolutions
= target_module
.resolutions
.borrow();
547 let names
= resolutions
.iter().filter_map(|(&(ref name
, _
), resolution
)| {
548 match *resolution
.borrow() {
549 NameResolution { binding: Some(_), .. }
=> Some(name
),
550 NameResolution { single_imports: SingleImports::None, .. }
=> None
,
554 let lev_suggestion
= match find_best_match_for_name(names
, &source
.as_str(), None
) {
555 Some(name
) => format
!(". Did you mean to use `{}`?", name
),
556 None
=> "".to_owned(),
558 let msg
= format
!("There is no `{}` in `{}`{}",
560 module_to_string(target_module
), lev_suggestion
);
561 return Failed(Some((directive
.span
, msg
)));
566 match (&value_result
, &type_result
) {
567 (&Success(name_binding
), _
) if !name_binding
.is_import() &&
568 directive
.is_public
&&
569 !name_binding
.is_public() => {
570 let msg
= format
!("`{}` is private, and cannot be reexported", source
);
571 let note_msg
= format
!("consider marking `{}` as `pub` in the imported module",
573 struct_span_err
!(self.resolver
.session
, directive
.span
, E0364
, "{}", &msg
)
574 .span_note(directive
.span
, ¬e_msg
)
578 (_
, &Success(name_binding
)) if !name_binding
.is_import() &&
579 directive
.is_public
&&
580 !name_binding
.is_public() => {
581 if name_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.resolver
.session
.add_lint(lint
::builtin
::PRIVATE_IN_PUBLIC
,
590 let msg
= format
!("`{}` is private, and cannot be reexported", source
);
592 format
!("consider declaring type or module `{}` with `pub`", source
);
593 struct_span_err
!(self.resolver
.session
, directive
.span
, E0365
, "{}", &msg
)
594 .span_note(directive
.span
, ¬e_msg
)
602 // Report a privacy error here if all successful namespaces are privacy errors.
603 let mut privacy_error
= None
;
604 for &ns
in &[ValueNS
, TypeNS
] {
605 privacy_error
= match module_
.resolve_name(target
, ns
, true) {
606 Success(&NameBinding
{
607 kind
: NameBindingKind
::Import { ref privacy_error, .. }
, ..
608 }) => privacy_error
.as_ref().map(|error
| (**error
).clone()),
611 if privacy_error
.is_none() { break }
613 privacy_error
.map(|error
| self.resolver
.privacy_errors
.push(error
));
615 // Record what this import resolves to for later uses in documentation,
616 // this may resolve to either a value or a type, but for documentation
617 // purposes it's good enough to just favor one over the other.
618 let def
= match type_result
.success().and_then(NameBinding
::def
) {
620 None
=> value_result
.success().and_then(NameBinding
::def
).unwrap(),
622 let path_resolution
= PathResolution { base_def: def, depth: 0 }
;
623 self.resolver
.def_map
.borrow_mut().insert(directive
.id
, path_resolution
);
625 debug
!("(resolving single import) successfully resolved import");
629 // Resolves a glob import. Note that this function cannot fail; it either
630 // succeeds or bails out (as importing * from an empty module or a module
631 // that exports nothing is valid). target_module is the module we are
632 // actually importing, i.e., `foo` in `use foo::*`.
633 fn resolve_glob_import(&mut self, target_module
: Module
<'b
>, directive
: &'b ImportDirective
<'b
>)
634 -> ResolveResult
<()> {
635 if let Some(Def
::Trait(_
)) = target_module
.def
{
636 self.resolver
.session
.span_err(directive
.span
, "items in traits are not importable.");
639 let module_
= self.resolver
.current_module
;
640 if module_
.def_id() == target_module
.def_id() {
641 // This means we are trying to glob import a module into itself, and it is a no-go
642 let msg
= "Cannot glob-import a module into itself.".into();
643 return Failed(Some((directive
.span
, msg
)));
645 self.resolver
.populate_module_if_necessary(target_module
);
647 if directive
.is_prelude
{
648 *module_
.prelude
.borrow_mut() = Some(target_module
);
652 // Add to target_module's glob_importers
653 target_module
.glob_importers
.borrow_mut().push((module_
, directive
));
655 // Ensure that `resolutions` isn't borrowed during `try_define_child`,
656 // since it might get updated via a glob cycle.
657 let bindings
= target_module
.resolutions
.borrow().iter().filter_map(|(name
, resolution
)| {
658 resolution
.borrow().binding().map(|binding
| (*name
, binding
))
659 }).collect
::<Vec
<_
>>();
660 for ((name
, ns
), binding
) in bindings
{
661 if binding
.defined_with(DefModifiers
::IMPORTABLE
| DefModifiers
::PUBLIC
) {
662 let _
= module_
.try_define_child(name
, ns
, directive
.import(binding
, None
));
666 // Record the destination of this import
667 if let Some(did
) = target_module
.def_id() {
668 self.resolver
.def_map
.borrow_mut().insert(directive
.id
,
670 base_def
: Def
::Mod(did
),
675 debug
!("(resolving glob import) successfully resolved import");
679 // Miscellaneous post-processing, including recording reexports, recording shadowed traits,
680 // reporting conflicts, reporting the PRIVATE_IN_PUBLIC lint, and reporting unresolved imports.
681 fn finalize_resolutions(&mut self, module
: Module
<'b
>, report_unresolved_imports
: bool
) {
682 // Since import resolution is finished, globs will not define any more names.
683 *module
.globs
.borrow_mut() = Vec
::new();
685 let mut reexports
= Vec
::new();
686 for (&(name
, ns
), resolution
) in module
.resolutions
.borrow().iter() {
687 let resolution
= resolution
.borrow();
688 resolution
.report_conflicts(|b1
, b2
| {
689 self.resolver
.report_conflict(module
, name
, ns
, b1
, b2
)
692 let binding
= match resolution
.binding
{
693 Some(binding
) => binding
,
697 if binding
.is_public() && (binding
.is_import() || binding
.is_extern_crate()) {
698 if let Some(def
) = binding
.def() {
699 reexports
.push(Export { name: name, def_id: def.def_id() }
);
703 if let NameBindingKind
::Import { binding: orig_binding, id, .. }
= binding
.kind
{
704 if ns
== TypeNS
&& binding
.is_public() &&
705 orig_binding
.defined_with(DefModifiers
::PRIVATE_VARIANT
) {
706 let msg
= format
!("variant `{}` is private, and cannot be reexported \
707 (error E0364), consider declaring its enum as `pub`",
709 let lint
= lint
::builtin
::PRIVATE_IN_PUBLIC
;
710 self.resolver
.session
.add_lint(lint
, id
, binding
.span
.unwrap(), msg
);
715 if reexports
.len() > 0 {
716 if let Some(def_id
) = module
.def_id() {
717 let node_id
= self.resolver
.ast_map
.as_local_node_id(def_id
).unwrap();
718 self.resolver
.export_map
.insert(node_id
, reexports
);
722 if report_unresolved_imports
{
723 for import
in module
.unresolved_imports
.borrow().iter() {
724 resolve_error(self.resolver
, import
.span
, ResolutionError
::UnresolvedImport(None
));
729 for (_
, child
) in module
.module_children
.borrow().iter() {
730 self.finalize_resolutions(child
, report_unresolved_imports
);
735 fn import_path_to_string(names
: &[Name
], subclass
: &ImportDirectiveSubclass
) -> String
{
736 if names
.is_empty() {
737 import_directive_subclass_to_string(subclass
)
740 names_to_string(names
),
741 import_directive_subclass_to_string(subclass
)))
746 fn import_directive_subclass_to_string(subclass
: &ImportDirectiveSubclass
) -> String
{
748 SingleImport { source, .. }
=> source
.to_string(),
749 GlobImport
=> "*".to_string(),
753 pub fn resolve_imports(resolver
: &mut Resolver
) {
754 let mut import_resolver
= ImportResolver { resolver: resolver }
;
755 import_resolver
.resolve_imports();