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