]> git.lizzy.rs Git - rust.git/blob - src/librustc_resolve/resolve_imports.rs
737ec71cab3da09273b69f94d3653d37674e91eb
[rust.git] / src / librustc_resolve / resolve_imports.rs
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
11 use self::ImportDirectiveSubclass::*;
12
13 use {PUBLIC, IMPORTABLE};
14 use Module;
15 use Namespace::{self, TypeNS, ValueNS};
16 use NameBindings;
17 use NamespaceResult::{BoundResult, UnboundResult, UnknownResult};
18 use NamespaceResult;
19 use NameSearchType;
20 use ResolveResult;
21 use Resolver;
22 use UseLexicalScopeFlag;
23 use {names_to_string, module_to_string};
24
25 use build_reduced_graph;
26
27 use rustc::middle::def::*;
28 use rustc::middle::privacy::*;
29
30 use syntax::ast::{DefId, NodeId, Name};
31 use syntax::attr::AttrMetaMethods;
32 use syntax::parse::token;
33 use syntax::codemap::Span;
34
35 use std::mem::replace;
36 use std::rc::Rc;
37
38
39 /// Contains data for specific types of import directives.
40 #[derive(Copy,Debug)]
41 pub enum ImportDirectiveSubclass {
42     SingleImport(Name /* target */, Name /* source */),
43     GlobImport
44 }
45
46 /// Whether an import can be shadowed by another import.
47 #[derive(Debug,PartialEq,Clone,Copy)]
48 pub enum Shadowable {
49     Always,
50     Never
51 }
52
53 /// One import directive.
54 #[derive(Debug)]
55 pub struct ImportDirective {
56     pub module_path: Vec<Name>,
57     pub subclass: ImportDirectiveSubclass,
58     pub span: Span,
59     pub id: NodeId,
60     pub is_public: bool, // see note in ImportResolution about how to use this
61     pub shadowable: Shadowable,
62 }
63
64 impl ImportDirective {
65     pub fn new(module_path: Vec<Name> ,
66            subclass: ImportDirectiveSubclass,
67            span: Span,
68            id: NodeId,
69            is_public: bool,
70            shadowable: Shadowable)
71            -> ImportDirective {
72         ImportDirective {
73             module_path: module_path,
74             subclass: subclass,
75             span: span,
76             id: id,
77             is_public: is_public,
78             shadowable: shadowable,
79         }
80     }
81 }
82
83 /// The item that an import resolves to.
84 #[derive(Clone,Debug)]
85 pub struct Target {
86     pub target_module: Rc<Module>,
87     pub bindings: Rc<NameBindings>,
88     pub shadowable: Shadowable,
89 }
90
91 impl Target {
92     pub fn new(target_module: Rc<Module>,
93            bindings: Rc<NameBindings>,
94            shadowable: Shadowable)
95            -> Target {
96         Target {
97             target_module: target_module,
98             bindings: bindings,
99             shadowable: shadowable,
100         }
101     }
102 }
103
104 /// An ImportResolution represents a particular `use` directive.
105 #[derive(Debug)]
106 pub struct ImportResolution {
107     /// Whether this resolution came from a `use` or a `pub use`. Note that this
108     /// should *not* be used whenever resolution is being performed. Privacy
109     /// testing occurs during a later phase of compilation.
110     pub is_public: bool,
111
112     // The number of outstanding references to this name. When this reaches
113     // zero, outside modules can count on the targets being correct. Before
114     // then, all bets are off; future imports could override this name.
115     // Note that this is usually either 0 or 1 - shadowing is forbidden the only
116     // way outstanding_references is > 1 in a legal program is if the name is
117     // used in both namespaces.
118     pub outstanding_references: uint,
119
120     /// The value that this `use` directive names, if there is one.
121     pub value_target: Option<Target>,
122     /// The source node of the `use` directive leading to the value target
123     /// being non-none
124     pub value_id: NodeId,
125
126     /// The type that this `use` directive names, if there is one.
127     pub type_target: Option<Target>,
128     /// The source node of the `use` directive leading to the type target
129     /// being non-none
130     pub type_id: NodeId,
131 }
132
133 impl ImportResolution {
134     pub fn new(id: NodeId, is_public: bool) -> ImportResolution {
135         ImportResolution {
136             type_id: id,
137             value_id: id,
138             outstanding_references: 0,
139             value_target: None,
140             type_target: None,
141             is_public: is_public,
142         }
143     }
144
145     pub fn target_for_namespace(&self, namespace: Namespace)
146                                 -> Option<Target> {
147         match namespace {
148             TypeNS  => self.type_target.clone(),
149             ValueNS => self.value_target.clone(),
150         }
151     }
152
153     pub fn id(&self, namespace: Namespace) -> NodeId {
154         match namespace {
155             TypeNS  => self.type_id,
156             ValueNS => self.value_id,
157         }
158     }
159
160     pub fn shadowable(&self, namespace: Namespace) -> Shadowable {
161         let target = self.target_for_namespace(namespace);
162         if target.is_none() {
163             return Shadowable::Always;
164         }
165
166         target.unwrap().shadowable
167     }
168
169     pub fn set_target_and_id(&mut self,
170                          namespace: Namespace,
171                          target: Option<Target>,
172                          id: NodeId) {
173         match namespace {
174             TypeNS  => {
175                 self.type_target = target;
176                 self.type_id = id;
177             }
178             ValueNS => {
179                 self.value_target = target;
180                 self.value_id = id;
181             }
182         }
183     }
184 }
185
186
187 struct ImportResolver<'a, 'b:'a, 'tcx:'b> {
188     resolver: &'a mut Resolver<'b, 'tcx>
189 }
190
191 impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
192     // Import resolution
193     //
194     // This is a fixed-point algorithm. We resolve imports until our efforts
195     // are stymied by an unresolved import; then we bail out of the current
196     // module and continue. We terminate successfully once no more imports
197     // remain or unsuccessfully when no forward progress in resolving imports
198     // is made.
199
200     /// Resolves all imports for the crate. This method performs the fixed-
201     /// point iteration.
202     fn resolve_imports(&mut self) {
203         let mut i = 0;
204         let mut prev_unresolved_imports = 0;
205         loop {
206             debug!("(resolving imports) iteration {}, {} imports left",
207                    i, self.resolver.unresolved_imports);
208
209             let module_root = self.resolver.graph_root.get_module();
210             self.resolve_imports_for_module_subtree(module_root.clone());
211
212             if self.resolver.unresolved_imports == 0 {
213                 debug!("(resolving imports) success");
214                 break;
215             }
216
217             if self.resolver.unresolved_imports == prev_unresolved_imports {
218                 self.resolver.report_unresolved_imports(module_root);
219                 break;
220             }
221
222             i += 1;
223             prev_unresolved_imports = self.resolver.unresolved_imports;
224         }
225     }
226
227     /// Attempts to resolve imports for the given module and all of its
228     /// submodules.
229     fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
230         debug!("(resolving imports for module subtree) resolving {}",
231                module_to_string(&*module_));
232         let orig_module = replace(&mut self.resolver.current_module, module_.clone());
233         self.resolve_imports_for_module(module_.clone());
234         self.resolver.current_module = orig_module;
235
236         build_reduced_graph::populate_module_if_necessary(self.resolver, &module_);
237         for (_, child_node) in &*module_.children.borrow() {
238             match child_node.get_module_if_available() {
239                 None => {
240                     // Nothing to do.
241                 }
242                 Some(child_module) => {
243                     self.resolve_imports_for_module_subtree(child_module);
244                 }
245             }
246         }
247
248         for (_, child_module) in &*module_.anonymous_children.borrow() {
249             self.resolve_imports_for_module_subtree(child_module.clone());
250         }
251     }
252
253     /// Attempts to resolve imports for the given module only.
254     fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
255         if module.all_imports_resolved() {
256             debug!("(resolving imports for module) all imports resolved for \
257                    {}",
258                    module_to_string(&*module));
259             return;
260         }
261
262         let imports = module.imports.borrow();
263         let import_count = imports.len();
264         while module.resolved_import_count.get() < import_count {
265             let import_index = module.resolved_import_count.get();
266             let import_directive = &(*imports)[import_index];
267             match self.resolve_import_for_module(module.clone(),
268                                                  import_directive) {
269                 ResolveResult::Failed(err) => {
270                     let (span, help) = match err {
271                         Some((span, msg)) => (span, format!(". {}", msg)),
272                         None => (import_directive.span, String::new())
273                     };
274                     let msg = format!("unresolved import `{}`{}",
275                                       import_path_to_string(
276                                           &import_directive.module_path,
277                                           import_directive.subclass),
278                                       help);
279                     self.resolver.resolve_error(span, &msg[..]);
280                 }
281                 ResolveResult::Indeterminate => break, // Bail out. We'll come around next time.
282                 ResolveResult::Success(()) => () // Good. Continue.
283             }
284
285             module.resolved_import_count
286                   .set(module.resolved_import_count.get() + 1);
287         }
288     }
289
290     /// Attempts to resolve the given import. The return value indicates
291     /// failure if we're certain the name does not exist, indeterminate if we
292     /// don't know whether the name exists at the moment due to other
293     /// currently-unresolved imports, or success if we know the name exists.
294     /// If successful, the resolved bindings are written into the module.
295     fn resolve_import_for_module(&mut self,
296                                  module_: Rc<Module>,
297                                  import_directive: &ImportDirective)
298                                  -> ResolveResult<()> {
299         let mut resolution_result = ResolveResult::Failed(None);
300         let module_path = &import_directive.module_path;
301
302         debug!("(resolving import for module) resolving import `{}::...` in `{}`",
303                names_to_string(&module_path[..]),
304                module_to_string(&*module_));
305
306         // First, resolve the module path for the directive, if necessary.
307         let container = if module_path.len() == 0 {
308             // Use the crate root.
309             Some((self.resolver.graph_root.get_module(), LastMod(AllPublic)))
310         } else {
311             match self.resolver.resolve_module_path(module_.clone(),
312                                                     &module_path[..],
313                                                     UseLexicalScopeFlag::DontUseLexicalScope,
314                                                     import_directive.span,
315                                                     NameSearchType::ImportSearch) {
316                 ResolveResult::Failed(err) => {
317                     resolution_result = ResolveResult::Failed(err);
318                     None
319                 },
320                 ResolveResult::Indeterminate => {
321                     resolution_result = ResolveResult::Indeterminate;
322                     None
323                 }
324                 ResolveResult::Success(container) => Some(container),
325             }
326         };
327
328         match container {
329             None => {}
330             Some((containing_module, lp)) => {
331                 // We found the module that the target is contained
332                 // within. Attempt to resolve the import within it.
333
334                 match import_directive.subclass {
335                     SingleImport(target, source) => {
336                         resolution_result =
337                             self.resolve_single_import(&module_,
338                                                        containing_module,
339                                                        target,
340                                                        source,
341                                                        import_directive,
342                                                        lp);
343                     }
344                     GlobImport => {
345                         resolution_result =
346                             self.resolve_glob_import(&module_,
347                                                      containing_module,
348                                                      import_directive,
349                                                      lp);
350                     }
351                 }
352             }
353         }
354
355         // Decrement the count of unresolved imports.
356         match resolution_result {
357             ResolveResult::Success(()) => {
358                 assert!(self.resolver.unresolved_imports >= 1);
359                 self.resolver.unresolved_imports -= 1;
360             }
361             _ => {
362                 // Nothing to do here; just return the error.
363             }
364         }
365
366         // Decrement the count of unresolved globs if necessary. But only if
367         // the resolution result is indeterminate -- otherwise we'll stop
368         // processing imports here. (See the loop in
369         // resolve_imports_for_module).
370
371         if !resolution_result.indeterminate() {
372             match import_directive.subclass {
373                 GlobImport => {
374                     assert!(module_.glob_count.get() >= 1);
375                     module_.glob_count.set(module_.glob_count.get() - 1);
376                 }
377                 SingleImport(..) => {
378                     // Ignore.
379                 }
380             }
381         }
382
383         return resolution_result;
384     }
385
386     fn resolve_single_import(&mut self,
387                              module_: &Module,
388                              target_module: Rc<Module>,
389                              target: Name,
390                              source: Name,
391                              directive: &ImportDirective,
392                              lp: LastPrivate)
393                              -> ResolveResult<()> {
394         debug!("(resolving single import) resolving `{}` = `{}::{}` from \
395                 `{}` id {}, last private {:?}",
396                token::get_name(target),
397                module_to_string(&*target_module),
398                token::get_name(source),
399                module_to_string(module_),
400                directive.id,
401                lp);
402
403         let lp = match lp {
404             LastMod(lp) => lp,
405             LastImport {..} => {
406                 self.resolver.session
407                     .span_bug(directive.span,
408                               "not expecting Import here, must be LastMod")
409             }
410         };
411
412         // We need to resolve both namespaces for this to succeed.
413         //
414
415         let mut value_result = UnknownResult;
416         let mut type_result = UnknownResult;
417
418         // Search for direct children of the containing module.
419         build_reduced_graph::populate_module_if_necessary(self.resolver, &target_module);
420
421         match target_module.children.borrow().get(&source) {
422             None => {
423                 // Continue.
424             }
425             Some(ref child_name_bindings) => {
426                 // pub_err makes sure we don't give the same error twice.
427                 let mut pub_err = false;
428                 if child_name_bindings.defined_in_namespace(ValueNS) {
429                     debug!("(resolving single import) found value binding");
430                     value_result = BoundResult(target_module.clone(),
431                                                (*child_name_bindings).clone());
432                     if directive.is_public && !child_name_bindings.is_public(ValueNS) {
433                         let msg = format!("`{}` is private", token::get_name(source));
434                         span_err!(self.resolver.session, directive.span, E0364, "{}", &msg);
435                         pub_err = true;
436                     }
437                 }
438                 if child_name_bindings.defined_in_namespace(TypeNS) {
439                     debug!("(resolving single import) found type binding");
440                     type_result = BoundResult(target_module.clone(),
441                                               (*child_name_bindings).clone());
442                     if !pub_err && directive.is_public && !child_name_bindings.is_public(TypeNS) {
443                         let msg = format!("`{}` is private", token::get_name(source));
444                         span_err!(self.resolver.session, directive.span, E0365, "{}", &msg);
445                     }
446                 }
447             }
448         }
449
450         // Unless we managed to find a result in both namespaces (unlikely),
451         // search imports as well.
452         let mut value_used_reexport = false;
453         let mut type_used_reexport = false;
454         match (value_result.clone(), type_result.clone()) {
455             (BoundResult(..), BoundResult(..)) => {} // Continue.
456             _ => {
457                 // If there is an unresolved glob at this point in the
458                 // containing module, bail out. We don't know enough to be
459                 // able to resolve this import.
460
461                 if target_module.glob_count.get() > 0 {
462                     debug!("(resolving single import) unresolved glob; \
463                             bailing out");
464                     return ResolveResult::Indeterminate;
465                 }
466
467                 // Now search the exported imports within the containing module.
468                 match target_module.import_resolutions.borrow().get(&source) {
469                     None => {
470                         debug!("(resolving single import) no import");
471                         // The containing module definitely doesn't have an
472                         // exported import with the name in question. We can
473                         // therefore accurately report that the names are
474                         // unbound.
475
476                         if value_result.is_unknown() {
477                             value_result = UnboundResult;
478                         }
479                         if type_result.is_unknown() {
480                             type_result = UnboundResult;
481                         }
482                     }
483                     Some(import_resolution)
484                             if import_resolution.outstanding_references == 0 => {
485
486                         fn get_binding(this: &mut Resolver,
487                                        import_resolution: &ImportResolution,
488                                        namespace: Namespace,
489                                        source: &Name)
490                                     -> NamespaceResult {
491
492                             // Import resolutions must be declared with "pub"
493                             // in order to be exported.
494                             if !import_resolution.is_public {
495                                 return UnboundResult;
496                             }
497
498                             match import_resolution.target_for_namespace(namespace) {
499                                 None => {
500                                     return UnboundResult;
501                                 }
502                                 Some(Target {
503                                     target_module,
504                                     bindings,
505                                     shadowable: _
506                                 }) => {
507                                     debug!("(resolving single import) found \
508                                             import in ns {:?}", namespace);
509                                     let id = import_resolution.id(namespace);
510                                     // track used imports and extern crates as well
511                                     this.used_imports.insert((id, namespace));
512                                     this.record_import_use(id, *source);
513                                     match target_module.def_id.get() {
514                                         Some(DefId{krate: kid, ..}) => {
515                                             this.used_crates.insert(kid);
516                                         },
517                                         _ => {}
518                                     }
519                                     return BoundResult(target_module, bindings);
520                                 }
521                             }
522                         }
523
524                         // The name is an import which has been fully
525                         // resolved. We can, therefore, just follow it.
526                         if value_result.is_unknown() {
527                             value_result = get_binding(self.resolver,
528                                                        import_resolution,
529                                                        ValueNS,
530                                                        &source);
531                             value_used_reexport = import_resolution.is_public;
532                         }
533                         if type_result.is_unknown() {
534                             type_result = get_binding(self.resolver,
535                                                       import_resolution,
536                                                       TypeNS,
537                                                       &source);
538                             type_used_reexport = import_resolution.is_public;
539                         }
540
541                     }
542                     Some(_) => {
543                         // If target_module is the same module whose import we are resolving
544                         // and there it has an unresolved import with the same name as `source`,
545                         // then the user is actually trying to import an item that is declared
546                         // in the same scope
547                         //
548                         // e.g
549                         // use self::submodule;
550                         // pub mod submodule;
551                         //
552                         // In this case we continue as if we resolved the import and let the
553                         // check_for_conflicts_between_imports_and_items call below handle
554                         // the conflict
555                         match (module_.def_id.get(),  target_module.def_id.get()) {
556                             (Some(id1), Some(id2)) if id1 == id2  => {
557                                 if value_result.is_unknown() {
558                                     value_result = UnboundResult;
559                                 }
560                                 if type_result.is_unknown() {
561                                     type_result = UnboundResult;
562                                 }
563                             }
564                             _ =>  {
565                                 // The import is unresolved. Bail out.
566                                 debug!("(resolving single import) unresolved import; \
567                                         bailing out");
568                                 return ResolveResult::Indeterminate;
569                             }
570                         }
571                     }
572                 }
573             }
574         }
575
576         let mut value_used_public = false;
577         let mut type_used_public = false;
578
579         // If we didn't find a result in the type namespace, search the
580         // external modules.
581         match type_result {
582             BoundResult(..) => {}
583             _ => {
584                 match target_module.external_module_children.borrow_mut().get(&source).cloned() {
585                     None => {} // Continue.
586                     Some(module) => {
587                         debug!("(resolving single import) found external module");
588                         // track the module as used.
589                         match module.def_id.get() {
590                             Some(DefId{krate: kid, ..}) => {
591                                 self.resolver.used_crates.insert(kid);
592                             }
593                             _ => {}
594                         }
595                         let name_bindings =
596                             Rc::new(Resolver::create_name_bindings_from_module(module));
597                         type_result = BoundResult(target_module.clone(), name_bindings);
598                         type_used_public = true;
599                     }
600                 }
601             }
602         }
603
604         // We've successfully resolved the import. Write the results in.
605         let mut import_resolutions = module_.import_resolutions.borrow_mut();
606         let import_resolution = &mut (*import_resolutions)[target];
607
608         {
609             let mut check_and_write_import = |namespace, result: &_, used_public: &mut bool| {
610                 let namespace_name = match namespace {
611                     TypeNS => "type",
612                     ValueNS => "value",
613                 };
614
615                 match *result {
616                     BoundResult(ref target_module, ref name_bindings) => {
617                         debug!("(resolving single import) found {:?} target: {:?}",
618                                namespace_name,
619                                name_bindings.def_for_namespace(namespace));
620                         self.check_for_conflicting_import(
621                             &import_resolution.target_for_namespace(namespace),
622                             directive.span,
623                             target,
624                             namespace);
625
626                         self.check_that_import_is_importable(
627                             &**name_bindings,
628                             directive.span,
629                             target,
630                             namespace);
631
632                         let target = Some(Target::new(target_module.clone(),
633                                                       name_bindings.clone(),
634                                                       directive.shadowable));
635                         import_resolution.set_target_and_id(namespace, target, directive.id);
636                         import_resolution.is_public = directive.is_public;
637                         *used_public = name_bindings.defined_in_public_namespace(namespace);
638                     }
639                     UnboundResult => { /* Continue. */ }
640                     UnknownResult => {
641                         panic!("{:?} result should be known at this point", namespace_name);
642                     }
643                 }
644             };
645             check_and_write_import(ValueNS, &value_result, &mut value_used_public);
646             check_and_write_import(TypeNS, &type_result, &mut type_used_public);
647         }
648
649         self.check_for_conflicts_between_imports_and_items(
650             module_,
651             import_resolution,
652             directive.span,
653             target);
654
655         if value_result.is_unbound() && type_result.is_unbound() {
656             let msg = format!("There is no `{}` in `{}`",
657                               token::get_name(source),
658                               module_to_string(&target_module));
659             return ResolveResult::Failed(Some((directive.span, msg)));
660         }
661         let value_used_public = value_used_reexport || value_used_public;
662         let type_used_public = type_used_reexport || type_used_public;
663
664         assert!(import_resolution.outstanding_references >= 1);
665         import_resolution.outstanding_references -= 1;
666
667         // Record what this import resolves to for later uses in documentation,
668         // this may resolve to either a value or a type, but for documentation
669         // purposes it's good enough to just favor one over the other.
670         let value_def_and_priv = import_resolution.value_target.as_ref().map(|target| {
671             let def = target.bindings.def_for_namespace(ValueNS).unwrap();
672             (def, if value_used_public { lp } else { DependsOn(def.def_id()) })
673         });
674         let type_def_and_priv = import_resolution.type_target.as_ref().map(|target| {
675             let def = target.bindings.def_for_namespace(TypeNS).unwrap();
676             (def, if type_used_public { lp } else { DependsOn(def.def_id()) })
677         });
678
679         let import_lp = LastImport {
680             value_priv: value_def_and_priv.map(|(_, p)| p),
681             value_used: Used,
682             type_priv: type_def_and_priv.map(|(_, p)| p),
683             type_used: Used
684         };
685
686         if let Some((def, _)) = value_def_and_priv {
687             self.resolver.def_map.borrow_mut().insert(directive.id, PathResolution {
688                 base_def: def,
689                 last_private: import_lp,
690                 depth: 0
691             });
692         }
693         if let Some((def, _)) = type_def_and_priv {
694             self.resolver.def_map.borrow_mut().insert(directive.id, PathResolution {
695                 base_def: def,
696                 last_private: import_lp,
697                 depth: 0
698             });
699         }
700
701         debug!("(resolving single import) successfully resolved import");
702         return ResolveResult::Success(());
703     }
704
705     // Resolves a glob import. Note that this function cannot fail; it either
706     // succeeds or bails out (as importing * from an empty module or a module
707     // that exports nothing is valid). target_module is the module we are
708     // actually importing, i.e., `foo` in `use foo::*`.
709     fn resolve_glob_import(&mut self,
710                            module_: &Module,
711                            target_module: Rc<Module>,
712                            import_directive: &ImportDirective,
713                            lp: LastPrivate)
714                            -> ResolveResult<()> {
715         let id = import_directive.id;
716         let is_public = import_directive.is_public;
717
718         // This function works in a highly imperative manner; it eagerly adds
719         // everything it can to the list of import resolutions of the module
720         // node.
721         debug!("(resolving glob import) resolving glob import {}", id);
722
723         // We must bail out if the node has unresolved imports of any kind
724         // (including globs).
725         if !(*target_module).all_imports_resolved() {
726             debug!("(resolving glob import) target module has unresolved \
727                     imports; bailing out");
728             return ResolveResult::Indeterminate;
729         }
730
731         assert_eq!(target_module.glob_count.get(), 0);
732
733         // Add all resolved imports from the containing module.
734         let import_resolutions = target_module.import_resolutions.borrow();
735         for (ident, target_import_resolution) in &*import_resolutions {
736             debug!("(resolving glob import) writing module resolution \
737                     {} into `{}`",
738                    token::get_name(*ident),
739                    module_to_string(module_));
740
741             if !target_import_resolution.is_public {
742                 debug!("(resolving glob import) nevermind, just kidding");
743                 continue
744             }
745
746             // Here we merge two import resolutions.
747             let mut import_resolutions = module_.import_resolutions.borrow_mut();
748             match import_resolutions.get_mut(ident) {
749                 Some(dest_import_resolution) => {
750                     // Merge the two import resolutions at a finer-grained
751                     // level.
752
753                     match target_import_resolution.value_target {
754                         None => {
755                             // Continue.
756                         }
757                         Some(ref value_target) => {
758                             self.check_for_conflicting_import(&dest_import_resolution.value_target,
759                                                               import_directive.span,
760                                                               *ident,
761                                                               ValueNS);
762                             dest_import_resolution.value_target = Some(value_target.clone());
763                         }
764                     }
765                     match target_import_resolution.type_target {
766                         None => {
767                             // Continue.
768                         }
769                         Some(ref type_target) => {
770                             self.check_for_conflicting_import(&dest_import_resolution.type_target,
771                                                               import_directive.span,
772                                                               *ident,
773                                                               TypeNS);
774                             dest_import_resolution.type_target = Some(type_target.clone());
775                         }
776                     }
777                     dest_import_resolution.is_public = is_public;
778                     continue;
779                 }
780                 None => {}
781             }
782
783             // Simple: just copy the old import resolution.
784             let mut new_import_resolution = ImportResolution::new(id, is_public);
785             new_import_resolution.value_target =
786                 target_import_resolution.value_target.clone();
787             new_import_resolution.type_target =
788                 target_import_resolution.type_target.clone();
789
790             import_resolutions.insert(*ident, new_import_resolution);
791         }
792
793         // Add all children from the containing module.
794         build_reduced_graph::populate_module_if_necessary(self.resolver, &target_module);
795
796         for (&name, name_bindings) in &*target_module.children.borrow() {
797             self.merge_import_resolution(module_,
798                                          target_module.clone(),
799                                          import_directive,
800                                          name,
801                                          name_bindings.clone());
802
803         }
804
805         // Add external module children from the containing module.
806         for (&name, module) in &*target_module.external_module_children.borrow() {
807             let name_bindings =
808                 Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
809             self.merge_import_resolution(module_,
810                                          target_module.clone(),
811                                          import_directive,
812                                          name,
813                                          name_bindings);
814         }
815
816         // Record the destination of this import
817         if let Some(did) = target_module.def_id.get() {
818             self.resolver.def_map.borrow_mut().insert(id, PathResolution {
819                 base_def: DefMod(did),
820                 last_private: lp,
821                 depth: 0
822             });
823         }
824
825         debug!("(resolving glob import) successfully resolved import");
826         return ResolveResult::Success(());
827     }
828
829     fn merge_import_resolution(&mut self,
830                                module_: &Module,
831                                containing_module: Rc<Module>,
832                                import_directive: &ImportDirective,
833                                name: Name,
834                                name_bindings: Rc<NameBindings>) {
835         let id = import_directive.id;
836         let is_public = import_directive.is_public;
837
838         let mut import_resolutions = module_.import_resolutions.borrow_mut();
839         let dest_import_resolution = import_resolutions.entry(name).get().unwrap_or_else(
840             |vacant_entry| {
841                 // Create a new import resolution from this child.
842                 vacant_entry.insert(ImportResolution::new(id, is_public))
843             });
844
845         debug!("(resolving glob import) writing resolution `{}` in `{}` \
846                to `{}`",
847                &token::get_name(name),
848                module_to_string(&*containing_module),
849                module_to_string(module_));
850
851         // Merge the child item into the import resolution.
852         {
853             let mut merge_child_item = |namespace| {
854                 if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
855                     let namespace_name = match namespace {
856                         TypeNS => "type",
857                         ValueNS => "value",
858                     };
859                     debug!("(resolving glob import) ... for {} target", namespace_name);
860                     if dest_import_resolution.shadowable(namespace) == Shadowable::Never {
861                         let msg = format!("a {} named `{}` has already been imported \
862                                            in this module",
863                                           namespace_name,
864                                           &token::get_name(name));
865                         span_err!(self.resolver.session, import_directive.span, E0251, "{}", msg);
866                     } else {
867                         let target = Target::new(containing_module.clone(),
868                                                  name_bindings.clone(),
869                                                  import_directive.shadowable);
870                         dest_import_resolution.set_target_and_id(namespace,
871                                                                  Some(target),
872                                                                  id);
873                     }
874                 }
875             };
876             merge_child_item(ValueNS);
877             merge_child_item(TypeNS);
878         }
879
880         dest_import_resolution.is_public = is_public;
881
882         self.check_for_conflicts_between_imports_and_items(
883             module_,
884             dest_import_resolution,
885             import_directive.span,
886             name);
887     }
888
889     /// Checks that imported names and items don't have the same name.
890     fn check_for_conflicting_import(&mut self,
891                                     target: &Option<Target>,
892                                     import_span: Span,
893                                     name: Name,
894                                     namespace: Namespace) {
895         debug!("check_for_conflicting_import: {}; target exists: {}",
896                &token::get_name(name),
897                target.is_some());
898
899         match *target {
900             Some(ref target) if target.shadowable != Shadowable::Always => {
901                 let msg = format!("a {} named `{}` has already been imported \
902                                    in this module",
903                                   match namespace {
904                                     TypeNS => "type",
905                                     ValueNS => "value",
906                                   },
907                                   &token::get_name(name));
908                 span_err!(self.resolver.session, import_span, E0252, "{}", &msg[..]);
909             }
910             Some(_) | None => {}
911         }
912     }
913
914     /// Checks that an import is actually importable
915     fn check_that_import_is_importable(&mut self,
916                                        name_bindings: &NameBindings,
917                                        import_span: Span,
918                                        name: Name,
919                                        namespace: Namespace) {
920         if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
921             let msg = format!("`{}` is not directly importable",
922                               token::get_name(name));
923             span_err!(self.resolver.session, import_span, E0253, "{}", &msg[..]);
924         }
925     }
926
927     /// Checks that imported names and items don't have the same name.
928     fn check_for_conflicts_between_imports_and_items(&mut self,
929                                                      module: &Module,
930                                                      import_resolution:
931                                                      &ImportResolution,
932                                                      import_span: Span,
933                                                      name: Name) {
934         // First, check for conflicts between imports and `extern crate`s.
935         if module.external_module_children
936                  .borrow()
937                  .contains_key(&name) {
938             match import_resolution.type_target {
939                 Some(ref target) if target.shadowable != Shadowable::Always => {
940                     let msg = format!("import `{0}` conflicts with imported \
941                                        crate in this module \
942                                        (maybe you meant `use {0}::*`?)",
943                                       &token::get_name(name));
944                     span_err!(self.resolver.session, import_span, E0254, "{}", &msg[..]);
945                 }
946                 Some(_) | None => {}
947             }
948         }
949
950         // Check for item conflicts.
951         let children = module.children.borrow();
952         let name_bindings = match children.get(&name) {
953             None => {
954                 // There can't be any conflicts.
955                 return
956             }
957             Some(ref name_bindings) => (*name_bindings).clone(),
958         };
959
960         match import_resolution.value_target {
961             Some(ref target) if target.shadowable != Shadowable::Always => {
962                 if let Some(ref value) = *name_bindings.value_def.borrow() {
963                     span_err!(self.resolver.session, import_span, E0255,
964                               "import `{}` conflicts with value in this module",
965                               &token::get_name(name));
966                     if let Some(span) = value.value_span {
967                         self.resolver.session.span_note(span, "conflicting value here");
968                     }
969                 }
970             }
971             Some(_) | None => {}
972         }
973
974         match import_resolution.type_target {
975             Some(ref target) if target.shadowable != Shadowable::Always => {
976                 if let Some(ref ty) = *name_bindings.type_def.borrow() {
977                     let (what, note) = if ty.module_def.is_some() {
978                         ("existing submodule", "note conflicting module here")
979                     } else {
980                         ("type in this module", "note conflicting type here")
981                     };
982                     span_err!(self.resolver.session, import_span, E0256,
983                               "import `{}` conflicts with {}",
984                               &token::get_name(name), what);
985                     if let Some(span) = ty.type_span {
986                         self.resolver.session.span_note(span, note);
987                     }
988                 }
989             }
990             Some(_) | None => {}
991         }
992     }
993 }
994
995 fn import_path_to_string(names: &[Name],
996                          subclass: ImportDirectiveSubclass)
997                          -> String {
998     if names.is_empty() {
999         import_directive_subclass_to_string(subclass)
1000     } else {
1001         (format!("{}::{}",
1002                  names_to_string(names),
1003                  import_directive_subclass_to_string(subclass))).to_string()
1004     }
1005 }
1006
1007 fn import_directive_subclass_to_string(subclass: ImportDirectiveSubclass) -> String {
1008     match subclass {
1009         SingleImport(_, source) => {
1010             token::get_name(source).to_string()
1011         }
1012         GlobImport => "*".to_string()
1013     }
1014 }
1015
1016 pub fn resolve_imports(resolver: &mut Resolver) {
1017     let mut import_resolver = ImportResolver {
1018         resolver: resolver,
1019     };
1020     import_resolver.resolve_imports();
1021 }