1 // Copyright 2012-2014 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 #[allow(non_camel_case_types)];
13 use driver::session::Session;
14 use metadata::csearch;
15 use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
16 use middle::lang_items::LanguageItems;
17 use middle::lint::{UnnecessaryQualification, UnusedImports};
18 use middle::pat_util::pat_bindings;
22 use syntax::ast_util::{def_id_of_def, local_def};
23 use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
24 use syntax::ext::mtwt;
25 use syntax::parse::token::special_idents;
26 use syntax::parse::token;
27 use syntax::print::pprust::path_to_str;
28 use syntax::codemap::{Span, DUMMY_SP, Pos};
29 use syntax::opt_vec::OptVec;
31 use syntax::visit::Visitor;
33 use std::cell::{Cell, RefCell};
35 use std::mem::replace;
36 use collections::{HashMap, HashSet};
39 pub type DefMap = @RefCell<HashMap<NodeId,Def>>;
43 binding_mode: BindingMode,
46 // Map from the name in a pattern to its binding mode.
47 type BindingMap = HashMap<Name,binding_info>;
49 // Trait method resolution
50 pub type TraitMap = HashMap<NodeId, ~[DefId]>;
52 // This is the replacement export map. It maps a module to all of the exports
54 pub type ExportMap2 = @RefCell<HashMap<NodeId, ~[Export2]>>;
57 name: ~str, // The name of the target.
58 def_id: DefId, // The definition of the target.
61 // This set contains all exported definitions from external crates. The set does
62 // not contain any entries from local crates.
63 pub type ExternalExports = HashSet<DefId>;
66 pub type LastPrivateMap = HashMap<NodeId, LastPrivate>;
68 pub enum LastPrivate {
70 // `use` directives (imports) can refer to two separate definitions in the
71 // type and value namespaces. We record here the last private node for each
72 // and whether the import is in fact used for each.
73 // If the Option<PrivateDep> fields are None, it means there is no defintion
75 LastImport{value_priv: Option<PrivateDep>,
76 value_used: ImportUse,
77 type_priv: Option<PrivateDep>,
78 type_used: ImportUse},
86 // How an import is used.
89 Unused, // The import is not used.
90 Used, // The import is used.
94 fn or(self, other: LastPrivate) -> LastPrivate {
96 (me, LastMod(AllPublic)) => me,
103 enum PatternBindingMode {
105 LocalIrrefutableMode,
106 ArgumentIrrefutableMode,
109 #[deriving(Eq, Hash)]
116 enum NamespaceError {
123 /// A NamespaceResult represents the result of resolving an import in
124 /// a particular namespace. The result is either definitely-resolved,
125 /// definitely- unresolved, or unknown.
126 enum NamespaceResult {
127 /// Means that resolve hasn't gathered enough information yet to determine
128 /// whether the name is bound in this namespace. (That is, it hasn't
129 /// resolved all `use` directives yet.)
131 /// Means that resolve has determined that the name is definitely
132 /// not bound in the namespace.
134 /// Means that resolve has determined that the name is bound in the Module
135 /// argument, and specified by the NameBindings argument.
136 BoundResult(@Module, @NameBindings)
139 impl NamespaceResult {
140 fn is_unknown(&self) -> bool {
142 UnknownResult => true,
148 enum NameDefinition {
149 NoNameDefinition, //< The name was unbound.
150 ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
151 ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
154 impl Visitor<()> for Resolver {
155 fn visit_item(&mut self, item: &Item, _: ()) {
156 self.resolve_item(item);
158 fn visit_arm(&mut self, arm: &Arm, _: ()) {
159 self.resolve_arm(arm);
161 fn visit_block(&mut self, block: &Block, _: ()) {
162 self.resolve_block(block);
164 fn visit_expr(&mut self, expr: &Expr, _: ()) {
165 self.resolve_expr(expr);
167 fn visit_local(&mut self, local: &Local, _: ()) {
168 self.resolve_local(local);
170 fn visit_ty(&mut self, ty: &Ty, _: ()) {
171 self.resolve_type(ty);
175 /// Contains data for specific types of import directives.
176 enum ImportDirectiveSubclass {
177 SingleImport(Ident /* target */, Ident /* source */),
181 /// The context that we thread through while building the reduced graph.
183 enum ReducedGraphParent {
184 ModuleReducedGraphParent(@Module)
187 impl ReducedGraphParent {
188 fn module(&self) -> @Module {
190 ModuleReducedGraphParent(m) => {
197 enum ResolveResult<T> {
198 Failed, // Failed to resolve the name.
199 Indeterminate, // Couldn't determine due to unresolved globs.
200 Success(T) // Successfully resolved the import.
203 impl<T> ResolveResult<T> {
204 fn indeterminate(&self) -> bool {
205 match *self { Indeterminate => true, _ => false }
209 enum TypeParameters<'a> {
210 NoTypeParameters, //< No type parameters.
211 HasTypeParameters(&'a Generics, //< Type parameters.
212 NodeId, //< ID of the enclosing item
214 // The index to start numbering the type parameters at.
215 // This is zero if this is the outermost set of type
216 // parameters, or equal to the number of outer type
217 // parameters. For example, if we have:
220 // fn method<U>() { ... }
223 // The index at the method site will be 1, because the
224 // outer T had index 0.
227 // The kind of the rib used for type parameters.
231 // The rib kind controls the translation of argument or local definitions
232 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
235 // No translation needs to be applied.
238 // We passed through a function scope at the given node ID. Translate
239 // upvars as appropriate.
240 FunctionRibKind(NodeId /* func id */, NodeId /* body id */),
242 // We passed through an impl or trait and are now in one of its
243 // methods. Allow references to ty params that impl or trait
244 // binds. Disallow any other upvars (including other ty params that are
246 // parent; method itself
247 MethodRibKind(NodeId, MethodSort),
249 // We passed through a function *item* scope. Disallow upvars.
250 OpaqueFunctionRibKind,
252 // We're in a constant item. Can't refer to dynamic stuff.
256 // Methods can be required or provided. Required methods only occur in traits.
262 enum UseLexicalScopeFlag {
267 enum SearchThroughModulesFlag {
268 DontSearchThroughModules,
272 enum ModulePrefixResult {
274 PrefixFound(@Module, uint)
278 enum NameSearchType {
279 /// We're doing a name search in order to resolve a `use` directive.
282 /// We're doing a name search in order to resolve a path type, a path
283 /// expression, or a path pattern.
287 enum BareIdentifierPatternResolution {
288 FoundStructOrEnumVariant(Def, LastPrivate),
289 FoundConst(Def, LastPrivate),
290 BareIdentifierPatternUnresolved
293 // Specifies how duplicates should be handled when adding a child item if
294 // another item exists with the same name in some namespace.
296 enum DuplicateCheckingMode {
297 ForbidDuplicateModules,
298 ForbidDuplicateTypes,
299 ForbidDuplicateValues,
300 ForbidDuplicateTypesAndValues,
306 bindings: RefCell<HashMap<Name, DefLike>>,
311 fn new(kind: RibKind) -> Rib {
313 bindings: RefCell::new(HashMap::new()),
319 /// One import directive.
320 struct ImportDirective {
321 module_path: ~[Ident],
322 subclass: @ImportDirectiveSubclass,
325 is_public: bool, // see note in ImportResolution about how to use this
328 impl ImportDirective {
329 fn new(module_path: ~[Ident],
330 subclass: @ImportDirectiveSubclass,
336 module_path: module_path,
340 is_public: is_public,
345 /// The item that an import resolves to.
348 target_module: @Module,
349 bindings: @NameBindings,
353 fn new(target_module: @Module, bindings: @NameBindings) -> Target {
355 target_module: target_module,
361 /// An ImportResolution represents a particular `use` directive.
362 struct ImportResolution {
363 /// Whether this resolution came from a `use` or a `pub use`. Note that this
364 /// should *not* be used whenever resolution is being performed, this is
365 /// only looked at for glob imports statements currently. Privacy testing
366 /// occurs during a later phase of compilation.
367 is_public: Cell<bool>,
369 // The number of outstanding references to this name. When this reaches
370 // zero, outside modules can count on the targets being correct. Before
371 // then, all bets are off; future imports could override this name.
372 outstanding_references: Cell<uint>,
374 /// The value that this `use` directive names, if there is one.
375 value_target: RefCell<Option<Target>>,
376 /// The source node of the `use` directive leading to the value target
378 value_id: Cell<NodeId>,
380 /// The type that this `use` directive names, if there is one.
381 type_target: RefCell<Option<Target>>,
382 /// The source node of the `use` directive leading to the type target
384 type_id: Cell<NodeId>,
387 impl ImportResolution {
388 fn new(id: NodeId, is_public: bool) -> ImportResolution {
390 type_id: Cell::new(id),
391 value_id: Cell::new(id),
392 outstanding_references: Cell::new(0),
393 value_target: RefCell::new(None),
394 type_target: RefCell::new(None),
395 is_public: Cell::new(is_public),
399 fn target_for_namespace(&self, namespace: Namespace)
402 TypeNS => return self.type_target.get(),
403 ValueNS => return self.value_target.get(),
407 fn id(&self, namespace: Namespace) -> NodeId {
409 TypeNS => self.type_id.get(),
410 ValueNS => self.value_id.get(),
415 /// The link from a module up to its nearest parent node.
418 ModuleParentLink(@Module, Ident),
419 BlockParentLink(@Module, NodeId)
422 /// The type of module this is.
432 /// One node in the tree of modules.
434 parent_link: ParentLink,
435 def_id: Cell<Option<DefId>>,
436 kind: Cell<ModuleKind>,
439 children: RefCell<HashMap<Name, @NameBindings>>,
440 imports: RefCell<~[@ImportDirective]>,
442 // The external module children of this node that were declared with
444 external_module_children: RefCell<HashMap<Name, @Module>>,
446 // The anonymous children of this node. Anonymous children are pseudo-
447 // modules that are implicitly created around items contained within
450 // For example, if we have this:
458 // There will be an anonymous module created around `g` with the ID of the
459 // entry block for `f`.
460 anonymous_children: RefCell<HashMap<NodeId,@Module>>,
462 // The status of resolving each import in this module.
463 import_resolutions: RefCell<HashMap<Name, @ImportResolution>>,
465 // The number of unresolved globs that this module exports.
466 glob_count: Cell<uint>,
468 // The index of the import we're resolving.
469 resolved_import_count: Cell<uint>,
471 // Whether this module is populated. If not populated, any attempt to
472 // access the children must be preceded with a
473 // `populate_module_if_necessary` call.
474 populated: Cell<bool>,
478 fn new(parent_link: ParentLink,
479 def_id: Option<DefId>,
485 parent_link: parent_link,
486 def_id: Cell::new(def_id),
487 kind: Cell::new(kind),
488 is_public: is_public,
489 children: RefCell::new(HashMap::new()),
490 imports: RefCell::new(~[]),
491 external_module_children: RefCell::new(HashMap::new()),
492 anonymous_children: RefCell::new(HashMap::new()),
493 import_resolutions: RefCell::new(HashMap::new()),
494 glob_count: Cell::new(0),
495 resolved_import_count: Cell::new(0),
496 populated: Cell::new(!external),
500 fn all_imports_resolved(&self) -> bool {
501 let mut imports = self.imports.borrow_mut();
502 return imports.get().len() == self.resolved_import_count.get();
506 // Records a possibly-private type definition.
509 is_public: bool, // see note in ImportResolution about how to use this
510 module_def: Option<@Module>,
511 type_def: Option<Def>,
512 type_span: Option<Span>
515 // Records a possibly-private value definition.
518 is_public: bool, // see note in ImportResolution about how to use this
520 value_span: Option<Span>,
523 // Records the definitions (at most one for each namespace) that a name is
525 struct NameBindings {
526 type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
527 value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
530 /// Ways in which a trait can be referenced
531 enum TraitReferenceType {
532 TraitImplementation, // impl SomeTrait for T { ... }
533 TraitDerivation, // trait T : SomeTrait { ... }
534 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
538 /// Creates a new module in this set of name bindings.
539 fn define_module(&self,
540 parent_link: ParentLink,
541 def_id: Option<DefId>,
546 // Merges the module with the existing type def or creates a new one.
547 let module_ = @Module::new(parent_link, def_id, kind, external,
549 match self.type_def.get() {
551 self.type_def.set(Some(TypeNsDef {
552 is_public: is_public,
553 module_def: Some(module_),
559 self.type_def.set(Some(TypeNsDef {
560 is_public: is_public,
561 module_def: Some(module_),
563 type_def: type_def.type_def
569 /// Sets the kind of the module, creating a new one if necessary.
570 fn set_module_kind(&self,
571 parent_link: ParentLink,
572 def_id: Option<DefId>,
577 match self.type_def.get() {
579 let module = @Module::new(parent_link, def_id, kind,
580 external, is_public);
581 self.type_def.set(Some(TypeNsDef {
582 is_public: is_public,
583 module_def: Some(module),
589 match type_def.module_def {
591 let module = @Module::new(parent_link,
596 self.type_def.set(Some(TypeNsDef {
597 is_public: is_public,
598 module_def: Some(module),
599 type_def: type_def.type_def,
603 Some(module_def) => module_def.kind.set(kind),
609 /// Records a type definition.
610 fn define_type(&self, def: Def, sp: Span, is_public: bool) {
611 // Merges the type with the existing type def or creates a new one.
612 match self.type_def.get() {
614 self.type_def.set(Some(TypeNsDef {
618 is_public: is_public,
622 self.type_def.set(Some(TypeNsDef {
625 module_def: type_def.module_def,
626 is_public: is_public,
632 /// Records a value definition.
633 fn define_value(&self, def: Def, sp: Span, is_public: bool) {
634 self.value_def.set(Some(ValueNsDef {
636 value_span: Some(sp),
637 is_public: is_public,
641 /// Returns the module node if applicable.
642 fn get_module_if_available(&self) -> Option<@Module> {
643 let type_def = self.type_def.borrow();
644 match *type_def.get() {
645 Some(ref type_def) => (*type_def).module_def,
651 * Returns the module node. Fails if this node does not have a module
654 fn get_module(&self) -> @Module {
655 match self.get_module_if_available() {
657 fail!("get_module called on a node with no module \
660 Some(module_def) => module_def
664 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
666 TypeNS => return self.type_def.get().is_some(),
667 ValueNS => return self.value_def.get().is_some()
671 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
673 TypeNS => match self.type_def.get() {
674 Some(def) => def.is_public, None => false
676 ValueNS => match self.value_def.get() {
677 Some(def) => def.is_public, None => false
682 fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
685 match self.type_def.get() {
688 match type_def.type_def {
689 Some(type_def) => Some(type_def),
691 match type_def.module_def {
693 match module.def_id.get() {
694 Some(did) => Some(DefMod(did)),
706 match self.value_def.get() {
708 Some(value_def) => Some(value_def.def)
714 fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
715 if self.defined_in_namespace(namespace) {
718 match self.type_def.get() {
720 Some(type_def) => type_def.type_span
724 match self.value_def.get() {
726 Some(value_def) => value_def.value_span
736 fn NameBindings() -> NameBindings {
738 type_def: RefCell::new(None),
739 value_def: RefCell::new(None),
743 /// Interns the names of the primitive types.
744 struct PrimitiveTypeTable {
745 primitive_types: HashMap<Name, PrimTy>,
748 impl PrimitiveTypeTable {
749 fn intern(&mut self, string: &str, primitive_type: PrimTy) {
750 self.primitive_types.insert(token::intern(string), primitive_type);
754 fn PrimitiveTypeTable() -> PrimitiveTypeTable {
755 let mut table = PrimitiveTypeTable {
756 primitive_types: HashMap::new()
759 table.intern("bool", TyBool);
760 table.intern("char", TyChar);
761 table.intern("f32", TyFloat(TyF32));
762 table.intern("f64", TyFloat(TyF64));
763 table.intern("int", TyInt(TyI));
764 table.intern("i8", TyInt(TyI8));
765 table.intern("i16", TyInt(TyI16));
766 table.intern("i32", TyInt(TyI32));
767 table.intern("i64", TyInt(TyI64));
768 table.intern("str", TyStr);
769 table.intern("uint", TyUint(TyU));
770 table.intern("u8", TyUint(TyU8));
771 table.intern("u16", TyUint(TyU16));
772 table.intern("u32", TyUint(TyU32));
773 table.intern("u64", TyUint(TyU64));
779 fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
782 ModuleError => "module",
784 ValueError => "value",
788 fn Resolver(session: Session,
789 lang_items: @LanguageItems,
790 crate_span: Span) -> Resolver {
791 let graph_root = @NameBindings();
793 graph_root.define_module(NoParentLink,
794 Some(DefId { krate: 0, node: 0 }),
800 let current_module = graph_root.get_module();
802 let this = Resolver {
804 lang_items: lang_items,
806 // The outermost module has def ID 0; this is not reflected in the
809 graph_root: graph_root,
811 method_map: @RefCell::new(HashMap::new()),
812 structs: HashSet::new(),
814 unresolved_imports: 0,
816 current_module: current_module,
817 value_ribs: @RefCell::new(~[]),
818 type_ribs: @RefCell::new(~[]),
819 label_ribs: @RefCell::new(~[]),
821 current_trait_refs: None,
823 self_ident: special_idents::self_,
824 type_self_ident: special_idents::type_self,
826 primitive_type_table: @PrimitiveTypeTable(),
828 namespaces: ~[ TypeNS, ValueNS ],
830 def_map: @RefCell::new(HashMap::new()),
831 export_map2: @RefCell::new(HashMap::new()),
832 trait_map: HashMap::new(),
833 used_imports: HashSet::new(),
834 external_exports: HashSet::new(),
835 last_private: HashMap::new(),
843 /// The main resolver class.
846 lang_items: @LanguageItems,
848 graph_root: @NameBindings,
850 method_map: @RefCell<HashMap<Name, HashSet<DefId>>>,
851 structs: HashSet<DefId>,
853 // The number of imports that are currently unresolved.
854 unresolved_imports: uint,
856 // The module that represents the current item scope.
857 current_module: @Module,
859 // The current set of local scopes, for values.
860 // FIXME #4948: Reuse ribs to avoid allocation.
861 value_ribs: @RefCell<~[@Rib]>,
863 // The current set of local scopes, for types.
864 type_ribs: @RefCell<~[@Rib]>,
866 // The current set of local scopes, for labels.
867 label_ribs: @RefCell<~[@Rib]>,
869 // The trait that the current context can refer to.
870 current_trait_refs: Option<~[DefId]>,
872 // The ident for the keyword "self".
874 // The ident for the non-keyword "Self".
875 type_self_ident: Ident,
877 // The idents for the primitive types.
878 primitive_type_table: @PrimitiveTypeTable,
880 // The four namespaces.
881 namespaces: ~[Namespace],
884 export_map2: ExportMap2,
886 external_exports: ExternalExports,
887 last_private: LastPrivateMap,
889 // Whether or not to print error messages. Can be set to true
890 // when getting additional info for error message suggestions,
891 // so as to avoid printing duplicate errors
894 used_imports: HashSet<(NodeId, Namespace)>,
897 struct BuildReducedGraphVisitor<'a> {
898 resolver: &'a mut Resolver,
901 impl<'a> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a> {
903 fn visit_item(&mut self, item: &Item, context: ReducedGraphParent) {
904 let p = self.resolver.build_reduced_graph_for_item(item, context);
905 visit::walk_item(self, item, p);
908 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem,
909 context: ReducedGraphParent) {
910 self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
913 let mut v = BuildReducedGraphVisitor{ resolver: r };
914 visit::walk_foreign_item(&mut v, foreign_item, c);
918 fn visit_view_item(&mut self, view_item: &ViewItem, context: ReducedGraphParent) {
919 self.resolver.build_reduced_graph_for_view_item(view_item, context);
922 fn visit_block(&mut self, block: &Block, context: ReducedGraphParent) {
923 let np = self.resolver.build_reduced_graph_for_block(block, context);
924 visit::walk_block(self, block, np);
929 struct UnusedImportCheckVisitor<'a> { resolver: &'a mut Resolver }
931 impl<'a> Visitor<()> for UnusedImportCheckVisitor<'a> {
932 fn visit_view_item(&mut self, vi: &ViewItem, _: ()) {
933 self.resolver.check_for_item_unused_imports(vi);
934 visit::walk_view_item(self, vi, ());
939 /// The main name resolution procedure.
940 fn resolve(&mut self, krate: &ast::Crate) {
941 self.build_reduced_graph(krate);
942 self.session.abort_if_errors();
944 self.resolve_imports();
945 self.session.abort_if_errors();
947 self.record_exports();
948 self.session.abort_if_errors();
950 self.resolve_crate(krate);
951 self.session.abort_if_errors();
953 self.check_for_unused_imports(krate);
957 // Reduced graph building
959 // Here we build the "reduced graph": the graph of the module tree without
960 // any imports resolved.
963 /// Constructs the reduced graph for the entire crate.
964 fn build_reduced_graph(&mut self, krate: &ast::Crate) {
966 ModuleReducedGraphParent(self.graph_root.get_module());
968 let mut visitor = BuildReducedGraphVisitor { resolver: self, };
969 visit::walk_crate(&mut visitor, krate, initial_parent);
972 /// Returns the current module tracked by the reduced graph parent.
973 fn get_module_from_parent(&mut self,
974 reduced_graph_parent: ReducedGraphParent)
976 match reduced_graph_parent {
977 ModuleReducedGraphParent(module_) => {
984 * Adds a new child item to the module definition of the parent node and
985 * returns its corresponding name bindings as well as the current parent.
986 * Or, if we're inside a block, creates (or reuses) an anonymous module
987 * corresponding to the innermost block ID and returns the name bindings
988 * as well as the newly-created parent.
990 * If this node does not have a module definition and we are not inside
993 fn add_child(&mut self,
995 reduced_graph_parent: ReducedGraphParent,
996 duplicate_checking_mode: DuplicateCheckingMode,
997 // For printing errors
999 -> (@NameBindings, ReducedGraphParent) {
1000 // If this is the immediate descendant of a module, then we add the
1001 // child name directly. Otherwise, we create or reuse an anonymous
1002 // module and add the child to that.
1005 match reduced_graph_parent {
1006 ModuleReducedGraphParent(parent_module) => {
1007 module_ = parent_module;
1011 // Add or reuse the child.
1012 let new_parent = ModuleReducedGraphParent(module_);
1014 let children = module_.children.borrow();
1015 children.get().find_copy(&name.name)
1019 let child = @NameBindings();
1020 let mut children = module_.children.borrow_mut();
1021 children.get().insert(name.name, child);
1022 return (child, new_parent);
1025 // Enforce the duplicate checking mode:
1027 // * If we're requesting duplicate module checking, check that
1028 // there isn't a module in the module with the same name.
1030 // * If we're requesting duplicate type checking, check that
1031 // there isn't a type in the module with the same name.
1033 // * If we're requesting duplicate value checking, check that
1034 // there isn't a value in the module with the same name.
1036 // * If we're requesting duplicate type checking and duplicate
1037 // value checking, check that there isn't a duplicate type
1038 // and a duplicate value with the same name.
1040 // * If no duplicate checking was requested at all, do
1043 let mut duplicate_type = NoError;
1044 let ns = match duplicate_checking_mode {
1045 ForbidDuplicateModules => {
1046 if child.get_module_if_available().is_some() {
1047 duplicate_type = ModuleError;
1051 ForbidDuplicateTypes => {
1052 match child.def_for_namespace(TypeNS) {
1053 Some(DefMod(_)) | None => {}
1054 Some(_) => duplicate_type = TypeError
1058 ForbidDuplicateValues => {
1059 if child.defined_in_namespace(ValueNS) {
1060 duplicate_type = ValueError;
1064 ForbidDuplicateTypesAndValues => {
1066 match child.def_for_namespace(TypeNS) {
1067 Some(DefMod(_)) | None => {}
1070 duplicate_type = TypeError;
1073 if child.defined_in_namespace(ValueNS) {
1074 duplicate_type = ValueError;
1079 OverwriteDuplicates => None
1081 if duplicate_type != NoError {
1082 // Return an error here by looking up the namespace that
1083 // had the duplicate.
1084 let ns = ns.unwrap();
1085 self.resolve_error(sp,
1086 format!("duplicate definition of {} `{}`",
1087 namespace_error_to_str(duplicate_type),
1088 token::get_ident(name)));
1090 let r = child.span_for_namespace(ns);
1091 for sp in r.iter() {
1092 self.session.span_note(*sp,
1093 format!("first definition of {} `{}` here",
1094 namespace_error_to_str(duplicate_type),
1095 token::get_ident(name)));
1099 return (child, new_parent);
1104 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1105 // If the block has view items, we need an anonymous module.
1106 if block.view_items.len() > 0 {
1110 // Check each statement.
1111 for statement in block.stmts.iter() {
1112 match statement.node {
1113 StmtDecl(declaration, _) => {
1114 match declaration.node {
1129 // If we found neither view items nor items, we don't need to create
1130 // an anonymous module.
1135 fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Ident)
1138 ModuleReducedGraphParent(module_) => {
1139 return ModuleParentLink(module_, name);
1144 /// Constructs the reduced graph for one item.
1145 fn build_reduced_graph_for_item(&mut self,
1147 parent: ReducedGraphParent)
1148 -> ReducedGraphParent
1150 let ident = item.ident;
1152 let is_public = item.vis == ast::Public;
1156 let (name_bindings, new_parent) =
1157 self.add_child(ident, parent, ForbidDuplicateModules, sp);
1159 let parent_link = self.get_parent_link(new_parent, ident);
1160 let def_id = DefId { krate: 0, node: item.id };
1161 name_bindings.define_module(parent_link,
1165 item.vis == ast::Public,
1168 ModuleReducedGraphParent(name_bindings.get_module())
1171 ItemForeignMod(..) => parent,
1173 // These items live in the value namespace.
1174 ItemStatic(_, m, _) => {
1175 let (name_bindings, _) =
1176 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1177 let mutbl = m == ast::MutMutable;
1179 name_bindings.define_value
1180 (DefStatic(local_def(item.id), mutbl), sp, is_public);
1183 ItemFn(_, purity, _, _, _) => {
1184 let (name_bindings, new_parent) =
1185 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1187 let def = DefFn(local_def(item.id), purity);
1188 name_bindings.define_value(def, sp, is_public);
1192 // These items live in the type namespace.
1194 let (name_bindings, _) =
1195 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1197 name_bindings.define_type
1198 (DefTy(local_def(item.id)), sp, is_public);
1202 ItemEnum(ref enum_definition, _) => {
1203 let (name_bindings, new_parent) =
1204 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1206 name_bindings.define_type
1207 (DefTy(local_def(item.id)), sp, is_public);
1209 for &variant in (*enum_definition).variants.iter() {
1210 self.build_reduced_graph_for_variant(
1219 // These items live in both the type and value namespaces.
1220 ItemStruct(struct_def, _) => {
1221 // Adding to both Type and Value namespaces or just Type?
1222 let (forbid, ctor_id) = match struct_def.ctor_id {
1223 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1224 None => (ForbidDuplicateTypes, None)
1227 let (name_bindings, new_parent) = self.add_child(ident, parent, forbid, sp);
1229 // Define a name in the type namespace.
1230 name_bindings.define_type(DefTy(local_def(item.id)), sp, is_public);
1232 // If this is a newtype or unit-like struct, define a name
1233 // in the value namespace as well
1234 ctor_id.while_some(|cid| {
1235 name_bindings.define_value(DefStruct(local_def(cid)), sp,
1240 // Record the def ID of this struct.
1241 self.structs.insert(local_def(item.id));
1246 ItemImpl(_, None, ty, ref methods) => {
1247 // If this implements an anonymous trait, then add all the
1248 // methods within to a new module, if the type was defined
1249 // within this module.
1251 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1252 // should modify anonymous traits to only be implementable in
1253 // the same module that declared the type.
1255 // Create the module and add all methods.
1257 TyPath(ref path, _, _) if path.segments.len() == 1 => {
1258 let name = path_to_ident(path);
1260 let existing_parent_opt = {
1261 let children = parent.module().children.borrow();
1262 children.get().find_copy(&name.name)
1264 let new_parent = match existing_parent_opt {
1265 // It already exists
1266 Some(child) if child.get_module_if_available()
1268 child.get_module().kind.get() ==
1270 ModuleReducedGraphParent(child.get_module())
1272 // Create the module
1274 let (name_bindings, new_parent) =
1275 self.add_child(name,
1277 ForbidDuplicateModules,
1281 self.get_parent_link(new_parent, ident);
1282 let def_id = local_def(item.id);
1285 !name_bindings.defined_in_namespace(ns) ||
1286 name_bindings.defined_in_public_namespace(ns);
1288 name_bindings.define_module(parent_link,
1295 ModuleReducedGraphParent(
1296 name_bindings.get_module())
1300 // For each method...
1301 for method in methods.iter() {
1302 // Add the method to the module.
1303 let ident = method.ident;
1304 let (method_name_bindings, _) =
1305 self.add_child(ident,
1307 ForbidDuplicateValues,
1309 let def = match method.explicit_self.node {
1311 // Static methods become
1312 // `def_static_method`s.
1313 DefStaticMethod(local_def(method.id),
1319 // Non-static methods become
1321 DefMethod(local_def(method.id), None)
1325 let is_public = method.vis == ast::Public;
1326 method_name_bindings.define_value(def,
1337 ItemImpl(_, Some(_), _, _) => parent,
1339 ItemTrait(_, _, ref methods) => {
1340 let (name_bindings, new_parent) =
1341 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1343 // Add all the methods within to a new module.
1344 let parent_link = self.get_parent_link(parent, ident);
1345 name_bindings.define_module(parent_link,
1346 Some(local_def(item.id)),
1349 item.vis == ast::Public,
1351 let module_parent = ModuleReducedGraphParent(name_bindings.
1354 // Add the names of all the methods to the trait info.
1355 let mut method_names = HashMap::new();
1356 for method in methods.iter() {
1357 let ty_m = trait_method_to_ty_method(method);
1359 let ident = ty_m.ident;
1361 // Add it as a name in the trait module.
1362 let def = match ty_m.explicit_self.node {
1364 // Static methods become `def_static_method`s.
1365 DefStaticMethod(local_def(ty_m.id),
1366 FromTrait(local_def(item.id)),
1370 // Non-static methods become `def_method`s.
1371 DefMethod(local_def(ty_m.id),
1372 Some(local_def(item.id)))
1376 let (method_name_bindings, _) =
1377 self.add_child(ident,
1379 ForbidDuplicateValues,
1381 method_name_bindings.define_value(def, ty_m.span, true);
1383 // Add it to the trait info if not static.
1384 match ty_m.explicit_self.node {
1387 method_names.insert(ident.name, ());
1392 let def_id = local_def(item.id);
1393 for (name, _) in method_names.iter() {
1394 let mut method_map = self.method_map.borrow_mut();
1395 if !method_map.get().contains_key(name) {
1396 method_map.get().insert(*name, HashSet::new());
1398 match method_map.get().find_mut(name) {
1399 Some(s) => { s.insert(def_id); },
1400 _ => fail!("can't happen"),
1404 name_bindings.define_type(DefTrait(def_id), sp, is_public);
1407 ItemMac(..) => parent
1411 // Constructs the reduced graph for one variant. Variants exist in the
1412 // type and/or value namespaces.
1413 fn build_reduced_graph_for_variant(&mut self,
1416 parent: ReducedGraphParent,
1417 parent_public: bool) {
1418 let ident = variant.node.name;
1419 // FIXME: this is unfortunate to have to do this privacy calculation
1420 // here. This should be living in middle::privacy, but it's
1421 // necessary to keep around in some form becaues of glob imports...
1422 let is_public = parent_public && variant.node.vis != ast::Private;
1424 match variant.node.kind {
1425 TupleVariantKind(_) => {
1426 let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues,
1428 child.define_value(DefVariant(item_id,
1429 local_def(variant.node.id), false),
1430 variant.span, is_public);
1432 StructVariantKind(_) => {
1433 let (child, _) = self.add_child(ident, parent, ForbidDuplicateTypesAndValues,
1435 child.define_type(DefVariant(item_id,
1436 local_def(variant.node.id), true),
1437 variant.span, is_public);
1438 self.structs.insert(local_def(variant.node.id));
1443 /// Constructs the reduced graph for one 'view item'. View items consist
1444 /// of imports and use directives.
1445 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1446 parent: ReducedGraphParent) {
1447 match view_item.node {
1448 ViewItemUse(ref view_paths) => {
1449 for view_path in view_paths.iter() {
1450 // Extract and intern the module part of the path. For
1451 // globs and lists, the path is found directly in the AST;
1452 // for simple paths we have to munge the path a little.
1454 let mut module_path = ~[];
1455 match view_path.node {
1456 ViewPathSimple(_, ref full_path, _) => {
1457 let path_len = full_path.segments.len();
1458 assert!(path_len != 0);
1460 for (i, segment) in full_path.segments
1463 if i != path_len - 1 {
1464 module_path.push(segment.identifier)
1469 ViewPathGlob(ref module_ident_path, _) |
1470 ViewPathList(ref module_ident_path, _, _) => {
1471 for segment in module_ident_path.segments.iter() {
1472 module_path.push(segment.identifier)
1477 // Build up the import directives.
1478 let module_ = self.get_module_from_parent(parent);
1479 let is_public = view_item.vis == ast::Public;
1480 match view_path.node {
1481 ViewPathSimple(binding, ref full_path, id) => {
1483 full_path.segments.last().unwrap().identifier;
1484 let subclass = @SingleImport(binding,
1486 self.build_import_directive(module_,
1493 ViewPathList(_, ref source_idents, _) => {
1494 for source_ident in source_idents.iter() {
1495 let name = source_ident.node.name;
1496 let subclass = @SingleImport(name, name);
1497 self.build_import_directive(
1499 module_path.clone(),
1502 source_ident.node.id,
1506 ViewPathGlob(_, id) => {
1507 self.build_import_directive(module_,
1518 ViewItemExternMod(name, _, node_id) => {
1519 // n.b. we don't need to look at the path option here, because cstore already did
1520 match self.session.cstore.find_extern_mod_stmt_cnum(node_id) {
1522 let def_id = DefId { krate: crate_id, node: 0 };
1523 self.external_exports.insert(def_id);
1524 let parent_link = ModuleParentLink
1525 (self.get_module_from_parent(parent), name);
1526 let external_module = @Module::new(parent_link,
1533 let mut external_module_children =
1534 parent.module().external_module_children.borrow_mut();
1535 external_module_children.get().insert(
1540 self.build_reduced_graph_for_external_crate(
1543 None => {} // Ignore.
1549 /// Constructs the reduced graph for one foreign item.
1550 fn build_reduced_graph_for_foreign_item(&mut self,
1551 foreign_item: &ForeignItem,
1552 parent: ReducedGraphParent,
1554 ReducedGraphParent|) {
1555 let name = foreign_item.ident;
1556 let is_public = foreign_item.vis == ast::Public;
1557 let (name_bindings, new_parent) =
1558 self.add_child(name, parent, ForbidDuplicateValues,
1561 match foreign_item.node {
1562 ForeignItemFn(_, ref generics) => {
1563 let def = DefFn(local_def(foreign_item.id), UnsafeFn);
1564 name_bindings.define_value(def, foreign_item.span, is_public);
1566 self.with_type_parameter_rib(
1567 HasTypeParameters(generics,
1571 |this| f(this, new_parent));
1573 ForeignItemStatic(_, m) => {
1574 let def = DefStatic(local_def(foreign_item.id), m);
1575 name_bindings.define_value(def, foreign_item.span, is_public);
1582 fn build_reduced_graph_for_block(&mut self,
1584 parent: ReducedGraphParent)
1585 -> ReducedGraphParent
1587 if self.block_needs_anonymous_module(block) {
1588 let block_id = block.id;
1590 debug!("(building reduced graph for block) creating a new \
1591 anonymous module for block {}",
1594 let parent_module = self.get_module_from_parent(parent);
1595 let new_module = @Module::new(
1596 BlockParentLink(parent_module, block_id),
1598 AnonymousModuleKind,
1602 let mut anonymous_children = parent_module.anonymous_children
1604 anonymous_children.get().insert(block_id, new_module);
1605 ModuleReducedGraphParent(new_module)
1612 fn handle_external_def(&mut self,
1615 child_name_bindings: @NameBindings,
1618 new_parent: ReducedGraphParent) {
1619 debug!("(building reduced graph for \
1620 external crate) building external def, priv {:?}",
1622 let is_public = vis == ast::Public;
1623 let is_exported = is_public && match new_parent {
1624 ModuleReducedGraphParent(module) => {
1625 match module.def_id.get() {
1627 Some(did) => self.external_exports.contains(&did)
1632 self.external_exports.insert(def_id_of_def(def));
1635 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1637 match child_name_bindings.type_def.get() {
1638 Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1639 debug!("(building reduced graph for external crate) \
1640 already created module");
1641 module_def.def_id.set(Some(def_id));
1644 debug!("(building reduced graph for \
1645 external crate) building module \
1647 let parent_link = self.get_parent_link(new_parent, ident);
1649 child_name_bindings.define_module(parent_link,
1662 DefMod(_) | DefForeignMod(_) => {}
1663 DefVariant(_, variant_id, is_struct) => {
1664 debug!("(building reduced graph for external crate) building \
1667 // We assume the parent is visible, or else we wouldn't have seen
1668 // it. Also variants are public-by-default if the parent was also
1670 let is_public = vis != ast::Private;
1672 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1673 self.structs.insert(variant_id);
1675 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1678 DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
1679 debug!("(building reduced graph for external \
1680 crate) building value (fn/static) {}", final_ident);
1681 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1683 DefTrait(def_id) => {
1684 debug!("(building reduced graph for external \
1685 crate) building type {}", final_ident);
1687 // If this is a trait, add all the method names
1688 // to the trait info.
1690 let method_def_ids =
1691 csearch::get_trait_method_def_ids(self.session.cstore, def_id);
1692 let mut interned_method_names = HashSet::new();
1693 for &method_def_id in method_def_ids.iter() {
1694 let (method_name, explicit_self) =
1695 csearch::get_method_name_and_explicit_self(self.session.cstore,
1698 debug!("(building reduced graph for \
1699 external crate) ... adding \
1701 token::get_ident(method_name));
1703 // Add it to the trait info if not static.
1704 if explicit_self != SelfStatic {
1705 interned_method_names.insert(method_name.name);
1708 self.external_exports.insert(method_def_id);
1711 for name in interned_method_names.iter() {
1712 let mut method_map = self.method_map.borrow_mut();
1713 if !method_map.get().contains_key(name) {
1714 method_map.get().insert(*name, HashSet::new());
1716 match method_map.get().find_mut(name) {
1717 Some(s) => { s.insert(def_id); },
1718 _ => fail!("can't happen"),
1722 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1724 // Define a module if necessary.
1725 let parent_link = self.get_parent_link(new_parent, ident);
1726 child_name_bindings.set_module_kind(parent_link,
1734 debug!("(building reduced graph for external \
1735 crate) building type {}", final_ident);
1737 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1739 DefStruct(def_id) => {
1740 debug!("(building reduced graph for external \
1741 crate) building type and value for {}",
1743 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1744 if csearch::get_struct_fields(self.session.cstore, def_id).len() == 0 {
1745 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1747 self.structs.insert(def_id);
1750 debug!("(building reduced graph for external crate) \
1751 ignoring {:?}", def);
1752 // Ignored; handled elsewhere.
1754 DefArg(..) | DefLocal(..) | DefPrimTy(..) |
1755 DefTyParam(..) | DefBinding(..) |
1756 DefUse(..) | DefUpvar(..) | DefRegion(..) |
1757 DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
1758 fail!("didn't expect `{:?}`", def);
1763 /// Builds the reduced graph for a single item in an external crate.
1764 fn build_reduced_graph_for_external_crate_def(&mut self,
1768 visibility: Visibility) {
1771 // Add the new child item, if necessary.
1773 DefForeignMod(def_id) => {
1774 // Foreign modules have no names. Recur and populate
1776 csearch::each_child_of_item(self.session.cstore,
1781 self.build_reduced_graph_for_external_crate_def(
1789 let (child_name_bindings, new_parent) =
1790 self.add_child(ident,
1791 ModuleReducedGraphParent(root),
1792 OverwriteDuplicates,
1795 self.handle_external_def(def,
1797 child_name_bindings,
1798 token::get_ident(ident).get(),
1805 // We only process static methods of impls here.
1806 match csearch::get_type_name_if_impl(self.session.cstore, def) {
1808 Some(final_ident) => {
1809 let static_methods_opt =
1810 csearch::get_static_methods_if_impl(self.session.cstore, def);
1811 match static_methods_opt {
1812 Some(ref static_methods) if
1813 static_methods.len() >= 1 => {
1814 debug!("(building reduced graph for \
1815 external crate) processing \
1816 static methods for type name {}",
1817 token::get_ident(final_ident));
1819 let (child_name_bindings, new_parent) =
1822 ModuleReducedGraphParent(root),
1823 OverwriteDuplicates,
1826 // Process the static methods. First,
1827 // create the module.
1829 match child_name_bindings.type_def.get() {
1831 module_def: Some(module_def),
1834 // We already have a module. This
1836 type_module = module_def;
1838 // Mark it as an impl module if
1840 type_module.kind.set(ImplModuleKind);
1844 self.get_parent_link(new_parent,
1846 child_name_bindings.define_module(
1854 child_name_bindings.
1859 // Add each static method to the module.
1861 ModuleReducedGraphParent(type_module);
1862 for static_method_info in
1863 static_methods.iter() {
1864 let ident = static_method_info.ident;
1865 debug!("(building reduced graph for \
1866 external crate) creating \
1867 static method '{}'",
1868 token::get_ident(ident));
1870 let (method_name_bindings, _) =
1871 self.add_child(ident,
1873 OverwriteDuplicates,
1876 static_method_info.def_id,
1877 static_method_info.purity);
1879 method_name_bindings.define_value(
1881 visibility == ast::Public);
1885 // Otherwise, do nothing.
1886 Some(_) | None => {}
1892 debug!("(building reduced graph for external crate) \
1898 /// Builds the reduced graph rooted at the given external module.
1899 fn populate_external_module(&mut self, module: @Module) {
1900 debug!("(populating external module) attempting to populate {}",
1901 self.module_to_str(module));
1903 let def_id = match module.def_id.get() {
1905 debug!("(populating external module) ... no def ID!");
1908 Some(def_id) => def_id,
1911 csearch::each_child_of_item(self.session.cstore,
1913 |def_like, child_ident, visibility| {
1914 debug!("(populating external module) ... found ident: {}",
1915 token::get_ident(child_ident));
1916 self.build_reduced_graph_for_external_crate_def(module,
1921 module.populated.set(true)
1924 /// Ensures that the reduced graph rooted at the given external module
1925 /// is built, building it if it is not.
1926 fn populate_module_if_necessary(&mut self, module: @Module) {
1927 if !module.populated.get() {
1928 self.populate_external_module(module)
1930 assert!(module.populated.get())
1933 /// Builds the reduced graph rooted at the 'use' directive for an external
1935 fn build_reduced_graph_for_external_crate(&mut self,
1937 csearch::each_top_level_item_of_crate(self.session.cstore,
1942 |def_like, ident, visibility| {
1943 self.build_reduced_graph_for_external_crate_def(root,
1950 /// Creates and adds an import directive to the given module.
1951 fn build_import_directive(&mut self,
1953 module_path: ~[Ident],
1954 subclass: @ImportDirectiveSubclass,
1958 let directive = @ImportDirective::new(module_path,
1963 let mut imports = module_.imports.borrow_mut();
1964 imports.get().push(directive);
1967 // Bump the reference count on the name. Or, if this is a glob, set
1968 // the appropriate flag.
1971 SingleImport(target, _) => {
1972 debug!("(building import directive) building import \
1974 self.idents_to_str(directive.module_path),
1975 token::get_ident(target));
1977 let mut import_resolutions = module_.import_resolutions
1979 match import_resolutions.get().find(&target.name) {
1980 Some(&resolution) => {
1981 debug!("(building import directive) bumping \
1983 resolution.outstanding_references.set(
1984 resolution.outstanding_references.get() + 1);
1986 // the source of this name is different now
1987 resolution.type_id.set(id);
1988 resolution.value_id.set(id);
1991 debug!("(building import directive) creating new");
1992 let resolution = @ImportResolution::new(id, is_public);
1993 resolution.outstanding_references.set(1);
1994 import_resolutions.get().insert(target.name,
2000 // Set the glob flag. This tells us that we don't know the
2001 // module's exports ahead of time.
2003 module_.glob_count.set(module_.glob_count.get() + 1);
2007 self.unresolved_imports += 1;
2010 // Import resolution
2012 // This is a fixed-point algorithm. We resolve imports until our efforts
2013 // are stymied by an unresolved import; then we bail out of the current
2014 // module and continue. We terminate successfully once no more imports
2015 // remain or unsuccessfully when no forward progress in resolving imports
2018 /// Resolves all imports for the crate. This method performs the fixed-
2019 /// point iteration.
2020 fn resolve_imports(&mut self) {
2022 let mut prev_unresolved_imports = 0;
2024 debug!("(resolving imports) iteration {}, {} imports left",
2025 i, self.unresolved_imports);
2027 let module_root = self.graph_root.get_module();
2028 self.resolve_imports_for_module_subtree(module_root);
2030 if self.unresolved_imports == 0 {
2031 debug!("(resolving imports) success");
2035 if self.unresolved_imports == prev_unresolved_imports {
2036 self.report_unresolved_imports(module_root);
2041 prev_unresolved_imports = self.unresolved_imports;
2045 /// Attempts to resolve imports for the given module and all of its
2047 fn resolve_imports_for_module_subtree(&mut self,
2049 debug!("(resolving imports for module subtree) resolving {}",
2050 self.module_to_str(module_));
2051 self.resolve_imports_for_module(module_);
2053 self.populate_module_if_necessary(module_);
2055 let children = module_.children.borrow();
2056 for (_, &child_node) in children.get().iter() {
2057 match child_node.get_module_if_available() {
2061 Some(child_module) => {
2062 self.resolve_imports_for_module_subtree(child_module);
2068 let anonymous_children = module_.anonymous_children.borrow();
2069 for (_, &child_module) in anonymous_children.get().iter() {
2070 self.resolve_imports_for_module_subtree(child_module);
2074 /// Attempts to resolve imports for the given module only.
2075 fn resolve_imports_for_module(&mut self, module: @Module) {
2076 if module.all_imports_resolved() {
2077 debug!("(resolving imports for module) all imports resolved for \
2079 self.module_to_str(module));
2083 let mut imports = module.imports.borrow_mut();
2084 let import_count = imports.get().len();
2085 while module.resolved_import_count.get() < import_count {
2086 let import_index = module.resolved_import_count.get();
2087 let import_directive = imports.get()[import_index];
2088 match self.resolve_import_for_module(module, import_directive) {
2090 // We presumably emitted an error. Continue.
2091 let msg = format!("failed to resolve import `{}`",
2092 self.import_path_to_str(
2093 import_directive.module_path,
2094 *import_directive.subclass));
2095 self.resolve_error(import_directive.span, msg);
2098 // Bail out. We'll come around next time.
2106 module.resolved_import_count
2107 .set(module.resolved_import_count.get() + 1);
2111 fn idents_to_str(&mut self, idents: &[Ident]) -> ~str {
2112 let mut first = true;
2113 let mut result = ~"";
2114 for ident in idents.iter() {
2118 result.push_str("::")
2120 result.push_str(token::get_ident(*ident).get());
2125 fn path_idents_to_str(&mut self, path: &Path) -> ~str {
2126 let identifiers: ~[ast::Ident] = path.segments
2128 .map(|seg| seg.identifier)
2130 self.idents_to_str(identifiers)
2133 fn import_directive_subclass_to_str(&mut self,
2134 subclass: ImportDirectiveSubclass)
2137 SingleImport(_, source) => {
2138 token::get_ident(source).get().to_str()
2144 fn import_path_to_str(&mut self,
2146 subclass: ImportDirectiveSubclass)
2148 if idents.is_empty() {
2149 self.import_directive_subclass_to_str(subclass)
2152 self.idents_to_str(idents),
2153 self.import_directive_subclass_to_str(subclass)))
2157 /// Attempts to resolve the given import. The return value indicates
2158 /// failure if we're certain the name does not exist, indeterminate if we
2159 /// don't know whether the name exists at the moment due to other
2160 /// currently-unresolved imports, or success if we know the name exists.
2161 /// If successful, the resolved bindings are written into the module.
2162 fn resolve_import_for_module(&mut self,
2164 import_directive: @ImportDirective)
2165 -> ResolveResult<()> {
2166 let mut resolution_result = Failed;
2167 let module_path = &import_directive.module_path;
2169 debug!("(resolving import for module) resolving import `{}::...` in \
2171 self.idents_to_str(*module_path),
2172 self.module_to_str(module_));
2174 // First, resolve the module path for the directive, if necessary.
2175 let container = if module_path.len() == 0 {
2176 // Use the crate root.
2177 Some((self.graph_root.get_module(), LastMod(AllPublic)))
2179 match self.resolve_module_path(module_,
2181 DontUseLexicalScope,
2182 import_directive.span,
2187 resolution_result = Indeterminate;
2190 Success(container) => Some(container),
2196 Some((containing_module, lp)) => {
2197 // We found the module that the target is contained
2198 // within. Attempt to resolve the import within it.
2200 match *import_directive.subclass {
2201 SingleImport(target, source) => {
2203 self.resolve_single_import(module_,
2212 self.resolve_glob_import(module_,
2214 import_directive.id,
2215 import_directive.is_public,
2222 // Decrement the count of unresolved imports.
2223 match resolution_result {
2225 assert!(self.unresolved_imports >= 1);
2226 self.unresolved_imports -= 1;
2229 // Nothing to do here; just return the error.
2233 // Decrement the count of unresolved globs if necessary. But only if
2234 // the resolution result is indeterminate -- otherwise we'll stop
2235 // processing imports here. (See the loop in
2236 // resolve_imports_for_module.)
2238 if !resolution_result.indeterminate() {
2239 match *import_directive.subclass {
2241 assert!(module_.glob_count.get() >= 1);
2242 module_.glob_count.set(module_.glob_count.get() - 1);
2244 SingleImport(..) => {
2250 return resolution_result;
2253 fn create_name_bindings_from_module(module: @Module) -> NameBindings {
2255 type_def: RefCell::new(Some(TypeNsDef {
2257 module_def: Some(module),
2261 value_def: RefCell::new(None),
2265 fn resolve_single_import(&mut self,
2267 containing_module: @Module,
2270 directive: &ImportDirective,
2272 -> ResolveResult<()> {
2273 debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2274 `{}` id {}, last private {:?}",
2275 token::get_ident(target),
2276 self.module_to_str(containing_module),
2277 token::get_ident(source),
2278 self.module_to_str(module_),
2284 LastImport{..} => self.session.span_bug(directive.span,
2285 "Not expecting Import here, must be LastMod"),
2288 // We need to resolve both namespaces for this to succeed.
2291 let mut value_result = UnknownResult;
2292 let mut type_result = UnknownResult;
2294 // Search for direct children of the containing module.
2295 self.populate_module_if_necessary(containing_module);
2298 let children = containing_module.children.borrow();
2299 match children.get().find(&source.name) {
2303 Some(child_name_bindings) => {
2304 if child_name_bindings.defined_in_namespace(ValueNS) {
2305 value_result = BoundResult(containing_module,
2306 *child_name_bindings);
2308 if child_name_bindings.defined_in_namespace(TypeNS) {
2309 type_result = BoundResult(containing_module,
2310 *child_name_bindings);
2316 // Unless we managed to find a result in both namespaces (unlikely),
2317 // search imports as well.
2318 let mut value_used_reexport = false;
2319 let mut type_used_reexport = false;
2320 match (value_result, type_result) {
2321 (BoundResult(..), BoundResult(..)) => {} // Continue.
2323 // If there is an unresolved glob at this point in the
2324 // containing module, bail out. We don't know enough to be
2325 // able to resolve this import.
2327 if containing_module.glob_count.get() > 0 {
2328 debug!("(resolving single import) unresolved glob; \
2330 return Indeterminate;
2333 // Now search the exported imports within the containing
2336 let import_resolutions = containing_module.import_resolutions
2338 match import_resolutions.get().find(&source.name) {
2340 // The containing module definitely doesn't have an
2341 // exported import with the name in question. We can
2342 // therefore accurately report that the names are
2345 if value_result.is_unknown() {
2346 value_result = UnboundResult;
2348 if type_result.is_unknown() {
2349 type_result = UnboundResult;
2352 Some(import_resolution)
2353 if import_resolution.outstanding_references.get()
2356 fn get_binding(this: &mut Resolver,
2357 import_resolution: @ImportResolution,
2358 namespace: Namespace)
2359 -> NamespaceResult {
2361 // Import resolutions must be declared with "pub"
2362 // in order to be exported.
2363 if !import_resolution.is_public.get() {
2364 return UnboundResult;
2367 match (*import_resolution).
2368 target_for_namespace(namespace) {
2370 return UnboundResult;
2373 let id = import_resolution.id(namespace);
2374 this.used_imports.insert((id, namespace));
2375 return BoundResult(target.target_module,
2381 // The name is an import which has been fully
2382 // resolved. We can, therefore, just follow it.
2383 if value_result.is_unknown() {
2384 value_result = get_binding(self, *import_resolution,
2386 value_used_reexport = import_resolution.is_public.get();
2388 if type_result.is_unknown() {
2389 type_result = get_binding(self, *import_resolution,
2391 type_used_reexport = import_resolution.is_public.get();
2396 // The import is unresolved. Bail out.
2397 debug!("(resolving single import) unresolved import; \
2399 return Indeterminate;
2405 // If we didn't find a result in the type namespace, search the
2406 // external modules.
2407 let mut value_used_public = false;
2408 let mut type_used_public = false;
2410 BoundResult(..) => {}
2413 let mut external_module_children =
2414 containing_module.external_module_children
2416 external_module_children.get().find_copy(&source.name)
2419 None => {} // Continue.
2422 @Resolver::create_name_bindings_from_module(
2424 type_result = BoundResult(containing_module,
2426 type_used_public = true;
2432 // We've successfully resolved the import. Write the results in.
2433 let import_resolution = {
2434 let import_resolutions = module_.import_resolutions.borrow();
2435 assert!(import_resolutions.get().contains_key(&target.name));
2436 import_resolutions.get().get_copy(&target.name)
2439 match value_result {
2440 BoundResult(target_module, name_bindings) => {
2441 debug!("(resolving single import) found value target");
2442 import_resolution.value_target.set(
2443 Some(Target::new(target_module, name_bindings)));
2444 import_resolution.value_id.set(directive.id);
2445 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2447 UnboundResult => { /* Continue. */ }
2449 fail!("value result should be known at this point");
2453 BoundResult(target_module, name_bindings) => {
2454 debug!("(resolving single import) found type target: {:?}",
2455 {name_bindings.type_def.get().unwrap().type_def});
2456 import_resolution.type_target.set(
2457 Some(Target::new(target_module, name_bindings)));
2458 import_resolution.type_id.set(directive.id);
2459 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2461 UnboundResult => { /* Continue. */ }
2463 fail!("type result should be known at this point");
2467 if import_resolution.value_target.get().is_none() &&
2468 import_resolution.type_target.get().is_none() {
2469 let msg = format!("unresolved import: there is no \
2471 token::get_ident(source),
2472 self.module_to_str(containing_module));
2473 self.resolve_error(directive.span, msg);
2476 let value_used_public = value_used_reexport || value_used_public;
2477 let type_used_public = type_used_reexport || type_used_public;
2479 assert!(import_resolution.outstanding_references.get() >= 1);
2480 import_resolution.outstanding_references.set(
2481 import_resolution.outstanding_references.get() - 1);
2483 // record what this import resolves to for later uses in documentation,
2484 // this may resolve to either a value or a type, but for documentation
2485 // purposes it's good enough to just favor one over the other.
2486 let value_private = match import_resolution.value_target.get() {
2488 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2489 let mut def_map = self.def_map.borrow_mut();
2490 def_map.get().insert(directive.id, def);
2491 let did = def_id_of_def(def);
2492 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2494 // AllPublic here and below is a dummy value, it should never be used because
2495 // _exists is false.
2498 let type_private = match import_resolution.type_target.get() {
2500 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2501 let mut def_map = self.def_map.borrow_mut();
2502 def_map.get().insert(directive.id, def);
2503 let did = def_id_of_def(def);
2504 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2509 self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2511 type_priv: type_private,
2514 debug!("(resolving single import) successfully resolved import");
2518 // Resolves a glob import. Note that this function cannot fail; it either
2519 // succeeds or bails out (as importing * from an empty module or a module
2520 // that exports nothing is valid).
2521 fn resolve_glob_import(&mut self,
2523 containing_module: @Module,
2527 -> ResolveResult<()> {
2528 // This function works in a highly imperative manner; it eagerly adds
2529 // everything it can to the list of import resolutions of the module
2531 debug!("(resolving glob import) resolving glob import {}", id);
2533 // We must bail out if the node has unresolved imports of any kind
2534 // (including globs).
2535 if !(*containing_module).all_imports_resolved() {
2536 debug!("(resolving glob import) target module has unresolved \
2537 imports; bailing out");
2538 return Indeterminate;
2541 assert_eq!(containing_module.glob_count.get(), 0);
2543 // Add all resolved imports from the containing module.
2544 let import_resolutions = containing_module.import_resolutions
2546 for (ident, target_import_resolution) in import_resolutions.get()
2548 debug!("(resolving glob import) writing module resolution \
2550 target_import_resolution.type_target.get().is_none(),
2551 self.module_to_str(module_));
2553 if !target_import_resolution.is_public.get() {
2554 debug!("(resolving glob import) nevermind, just kidding");
2558 // Here we merge two import resolutions.
2559 let mut import_resolutions = module_.import_resolutions
2561 match import_resolutions.get().find(ident) {
2563 // Simple: just copy the old import resolution.
2564 let new_import_resolution =
2565 @ImportResolution::new(id, is_public);
2566 new_import_resolution.value_target.set(
2567 target_import_resolution.value_target.get());
2568 new_import_resolution.type_target.set(
2569 target_import_resolution.type_target.get());
2571 import_resolutions.get().insert
2572 (*ident, new_import_resolution);
2574 Some(&dest_import_resolution) => {
2575 // Merge the two import resolutions at a finer-grained
2578 match target_import_resolution.value_target.get() {
2582 Some(value_target) => {
2583 dest_import_resolution.value_target.set(
2584 Some(value_target));
2587 match target_import_resolution.type_target.get() {
2591 Some(type_target) => {
2592 dest_import_resolution.type_target.set(
2596 dest_import_resolution.is_public.set(is_public);
2601 // Add all children from the containing module.
2602 self.populate_module_if_necessary(containing_module);
2605 let children = containing_module.children.borrow();
2606 for (&name, name_bindings) in children.get().iter() {
2607 self.merge_import_resolution(module_, containing_module,
2609 name, *name_bindings);
2613 // Add external module children from the containing module.
2615 let external_module_children =
2616 containing_module.external_module_children.borrow();
2617 for (&name, module) in external_module_children.get().iter() {
2619 @Resolver::create_name_bindings_from_module(*module);
2620 self.merge_import_resolution(module_, containing_module,
2622 name, name_bindings);
2626 // Record the destination of this import
2627 match containing_module.def_id.get() {
2629 let mut def_map = self.def_map.borrow_mut();
2630 def_map.get().insert(id, DefMod(did));
2631 self.last_private.insert(id, lp);
2636 debug!("(resolving glob import) successfully resolved import");
2640 fn merge_import_resolution(&mut self,
2642 containing_module: @Module,
2646 name_bindings: @NameBindings) {
2647 let dest_import_resolution;
2648 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2649 match import_resolutions.get().find(&name) {
2651 // Create a new import resolution from this child.
2652 dest_import_resolution =
2653 @ImportResolution::new(id, is_public);
2654 import_resolutions.get().insert(name,
2655 dest_import_resolution);
2657 Some(&existing_import_resolution) => {
2658 dest_import_resolution = existing_import_resolution;
2662 debug!("(resolving glob import) writing resolution `{}` in `{}` \
2664 token::get_name(name).get().to_str(),
2665 self.module_to_str(containing_module),
2666 self.module_to_str(module_));
2668 // Merge the child item into the import resolution.
2669 if name_bindings.defined_in_public_namespace(ValueNS) {
2670 debug!("(resolving glob import) ... for value target");
2671 dest_import_resolution.value_target.set(
2672 Some(Target::new(containing_module, name_bindings)));
2673 dest_import_resolution.value_id.set(id);
2675 if name_bindings.defined_in_public_namespace(TypeNS) {
2676 debug!("(resolving glob import) ... for type target");
2677 dest_import_resolution.type_target.set(
2678 Some(Target::new(containing_module, name_bindings)));
2679 dest_import_resolution.type_id.set(id);
2681 dest_import_resolution.is_public.set(is_public);
2684 /// Resolves the given module path from the given root `module_`.
2685 fn resolve_module_path_from_root(&mut self,
2687 module_path: &[Ident],
2690 name_search_type: NameSearchType,
2692 -> ResolveResult<(@Module, LastPrivate)> {
2693 let mut search_module = module_;
2694 let mut index = index;
2695 let module_path_len = module_path.len();
2696 let mut closest_private = lp;
2698 // Resolve the module part of the path. This does not involve looking
2699 // upward though scope chains; we simply resolve names directly in
2700 // modules as we go.
2701 while index < module_path_len {
2702 let name = module_path[index];
2703 match self.resolve_name_in_module(search_module,
2708 let segment_name = token::get_ident(name);
2709 let module_name = self.module_to_str(search_module);
2710 if "???" == module_name {
2713 hi: span.lo + Pos::from_uint(segment_name.get().len()),
2714 expn_info: span.expn_info,
2716 self.resolve_error(span,
2717 format!("unresolved import. maybe \
2718 a missing `extern crate \
2723 self.resolve_error(span, format!("unresolved import: could not find `{}` in \
2724 `{}`.", segment_name, module_name));
2728 debug!("(resolving module path for import) module \
2729 resolution is indeterminate: {}",
2730 token::get_ident(name));
2731 return Indeterminate;
2733 Success((target, used_proxy)) => {
2734 // Check to see whether there are type bindings, and, if
2735 // so, whether there is a module within.
2736 match target.bindings.type_def.get() {
2738 match type_def.module_def {
2741 self.resolve_error(span, format!("not a module `{}`",
2742 token::get_ident(name)));
2745 Some(module_def) => {
2746 // If we're doing the search for an
2747 // import, do not allow traits and impls
2749 match (name_search_type,
2750 module_def.kind.get()) {
2751 (ImportSearch, TraitModuleKind) |
2752 (ImportSearch, ImplModuleKind) => {
2755 "cannot import from a trait \
2756 or type implementation");
2760 search_module = module_def;
2762 // Keep track of the closest
2763 // private module used when
2764 // resolving this import chain.
2766 !search_module.is_public {
2767 match search_module.def_id
2771 LastMod(DependsOn(did));
2782 // There are no type bindings at all.
2783 self.resolve_error(span,
2784 format!("not a module `{}`",
2785 token::get_ident(name)));
2795 return Success((search_module, closest_private));
2798 /// Attempts to resolve the module part of an import directive or path
2799 /// rooted at the given module.
2801 /// On success, returns the resolved module, and the closest *private*
2802 /// module found to the destination when resolving this path.
2803 fn resolve_module_path(&mut self,
2805 module_path: &[Ident],
2806 use_lexical_scope: UseLexicalScopeFlag,
2808 name_search_type: NameSearchType)
2809 -> ResolveResult<(@Module, LastPrivate)> {
2810 let module_path_len = module_path.len();
2811 assert!(module_path_len > 0);
2813 debug!("(resolving module path for import) processing `{}` rooted at \
2815 self.idents_to_str(module_path),
2816 self.module_to_str(module_));
2818 // Resolve the module prefix, if any.
2819 let module_prefix_result = self.resolve_module_prefix(module_,
2825 match module_prefix_result {
2827 let mpath = self.idents_to_str(module_path);
2828 match mpath.rfind(':') {
2830 self.resolve_error(span, format!("unresolved import: could not find `{}` \
2832 // idx +- 1 to account for the colons
2834 mpath.slice_from(idx + 1),
2835 mpath.slice_to(idx - 1)));
2842 debug!("(resolving module path for import) indeterminate; \
2844 return Indeterminate;
2846 Success(NoPrefixFound) => {
2847 // There was no prefix, so we're considering the first element
2848 // of the path. How we handle this depends on whether we were
2849 // instructed to use lexical scope or not.
2850 match use_lexical_scope {
2851 DontUseLexicalScope => {
2852 // This is a crate-relative path. We will start the
2853 // resolution process at index zero.
2854 search_module = self.graph_root.get_module();
2856 last_private = LastMod(AllPublic);
2858 UseLexicalScope => {
2859 // This is not a crate-relative path. We resolve the
2860 // first component of the path in the current lexical
2861 // scope and then proceed to resolve below that.
2862 let result = self.resolve_module_in_lexical_scope(
2867 self.resolve_error(span, "unresolved name");
2871 debug!("(resolving module path for import) \
2872 indeterminate; bailing");
2873 return Indeterminate;
2875 Success(containing_module) => {
2876 search_module = containing_module;
2878 last_private = LastMod(AllPublic);
2884 Success(PrefixFound(containing_module, index)) => {
2885 search_module = containing_module;
2886 start_index = index;
2887 last_private = LastMod(DependsOn(containing_module.def_id
2893 self.resolve_module_path_from_root(search_module,
2901 /// Invariant: This must only be called during main resolution, not during
2902 /// import resolution.
2903 fn resolve_item_in_lexical_scope(&mut self,
2906 namespace: Namespace,
2907 search_through_modules:
2908 SearchThroughModulesFlag)
2909 -> ResolveResult<(Target, bool)> {
2910 debug!("(resolving item in lexical scope) resolving `{}` in \
2911 namespace {:?} in `{}`",
2912 token::get_ident(name),
2914 self.module_to_str(module_));
2916 // The current module node is handled specially. First, check for
2917 // its immediate children.
2918 self.populate_module_if_necessary(module_);
2921 let children = module_.children.borrow();
2922 match children.get().find(&name.name) {
2924 if name_bindings.defined_in_namespace(namespace) => {
2925 debug!("top name bindings succeeded");
2926 return Success((Target::new(module_, *name_bindings),
2929 Some(_) | None => { /* Not found; continue. */ }
2933 // Now check for its import directives. We don't have to have resolved
2934 // all its imports in the usual way; this is because chains of
2935 // adjacent import statements are processed as though they mutated the
2937 let import_resolutions = module_.import_resolutions.borrow();
2938 match import_resolutions.get().find(&name.name) {
2940 // Not found; continue.
2942 Some(import_resolution) => {
2943 match (*import_resolution).target_for_namespace(namespace) {
2945 // Not found; continue.
2946 debug!("(resolving item in lexical scope) found \
2947 import resolution, but not in namespace {:?}",
2951 debug!("(resolving item in lexical scope) using \
2952 import resolution");
2953 self.used_imports.insert((import_resolution.id(namespace), namespace));
2954 return Success((target, false));
2960 // Search for external modules.
2961 if namespace == TypeNS {
2963 let external_module_children =
2964 module_.external_module_children.borrow();
2965 external_module_children.get().find_copy(&name.name)
2971 @Resolver::create_name_bindings_from_module(module);
2972 debug!("lower name bindings succeeded");
2973 return Success((Target::new(module_, name_bindings), false));
2978 // Finally, proceed up the scope chain looking for parent modules.
2979 let mut search_module = module_;
2981 // Go to the next parent.
2982 match search_module.parent_link {
2984 // No more parents. This module was unresolved.
2985 debug!("(resolving item in lexical scope) unresolved \
2989 ModuleParentLink(parent_module_node, _) => {
2990 match search_through_modules {
2991 DontSearchThroughModules => {
2992 match search_module.kind.get() {
2993 NormalModuleKind => {
2994 // We stop the search here.
2995 debug!("(resolving item in lexical \
2996 scope) unresolved module: not \
2997 searching through module \
3004 AnonymousModuleKind => {
3005 search_module = parent_module_node;
3009 SearchThroughModules => {
3010 search_module = parent_module_node;
3014 BlockParentLink(parent_module_node, _) => {
3015 search_module = parent_module_node;
3019 // Resolve the name in the parent module.
3020 match self.resolve_name_in_module(search_module,
3025 // Continue up the search chain.
3028 // We couldn't see through the higher scope because of an
3029 // unresolved import higher up. Bail.
3031 debug!("(resolving item in lexical scope) indeterminate \
3032 higher scope; bailing");
3033 return Indeterminate;
3035 Success((target, used_reexport)) => {
3036 // We found the module.
3037 debug!("(resolving item in lexical scope) found name \
3039 return Success((target, used_reexport));
3045 /// Resolves a module name in the current lexical scope.
3046 fn resolve_module_in_lexical_scope(&mut self,
3049 -> ResolveResult<@Module> {
3050 // If this module is an anonymous module, resolve the item in the
3051 // lexical scope. Otherwise, resolve the item from the crate root.
3052 let resolve_result = self.resolve_item_in_lexical_scope(
3053 module_, name, TypeNS, DontSearchThroughModules);
3054 match resolve_result {
3055 Success((target, _)) => {
3056 let bindings = &*target.bindings;
3057 match bindings.type_def.get() {
3059 match type_def.module_def {
3061 error!("!!! (resolving module in lexical \
3062 scope) module wasn't actually a \
3066 Some(module_def) => {
3067 return Success(module_def);
3072 error!("!!! (resolving module in lexical scope) module
3073 wasn't actually a module!");
3079 debug!("(resolving module in lexical scope) indeterminate; \
3081 return Indeterminate;
3084 debug!("(resolving module in lexical scope) failed to \
3091 /// Returns the nearest normal module parent of the given module.
3092 fn get_nearest_normal_module_parent(&mut self, module_: @Module)
3093 -> Option<@Module> {
3094 let mut module_ = module_;
3096 match module_.parent_link {
3097 NoParentLink => return None,
3098 ModuleParentLink(new_module, _) |
3099 BlockParentLink(new_module, _) => {
3100 match new_module.kind.get() {
3101 NormalModuleKind => return Some(new_module),
3105 AnonymousModuleKind => module_ = new_module,
3112 /// Returns the nearest normal module parent of the given module, or the
3113 /// module itself if it is a normal module.
3114 fn get_nearest_normal_module_parent_or_self(&mut self, module_: @Module)
3116 match module_.kind.get() {
3117 NormalModuleKind => return module_,
3121 AnonymousModuleKind => {
3122 match self.get_nearest_normal_module_parent(module_) {
3124 Some(new_module) => new_module
3130 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3131 /// (b) some chain of `super::`.
3132 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3133 fn resolve_module_prefix(&mut self,
3135 module_path: &[Ident])
3136 -> ResolveResult<ModulePrefixResult> {
3137 // Start at the current module if we see `self` or `super`, or at the
3138 // top of the crate otherwise.
3139 let mut containing_module;
3141 let first_module_path_string = token::get_ident(module_path[0]);
3142 if "self" == first_module_path_string.get() {
3144 self.get_nearest_normal_module_parent_or_self(module_);
3146 } else if "super" == first_module_path_string.get() {
3148 self.get_nearest_normal_module_parent_or_self(module_);
3149 i = 0; // We'll handle `super` below.
3151 return Success(NoPrefixFound);
3154 // Now loop through all the `super`s we find.
3155 while i < module_path.len() {
3156 let string = token::get_ident(module_path[i]);
3157 if "super" != string.get() {
3160 debug!("(resolving module prefix) resolving `super` at {}",
3161 self.module_to_str(containing_module));
3162 match self.get_nearest_normal_module_parent(containing_module) {
3163 None => return Failed,
3164 Some(new_module) => {
3165 containing_module = new_module;
3171 debug!("(resolving module prefix) finished resolving prefix at {}",
3172 self.module_to_str(containing_module));
3174 return Success(PrefixFound(containing_module, i));
3177 /// Attempts to resolve the supplied name in the given module for the
3178 /// given namespace. If successful, returns the target corresponding to
3181 /// The boolean returned on success is an indicator of whether this lookup
3182 /// passed through a public re-export proxy.
3183 fn resolve_name_in_module(&mut self,
3186 namespace: Namespace,
3187 name_search_type: NameSearchType)
3188 -> ResolveResult<(Target, bool)> {
3189 debug!("(resolving name in module) resolving `{}` in `{}`",
3190 token::get_ident(name),
3191 self.module_to_str(module_));
3193 // First, check the direct children of the module.
3194 self.populate_module_if_necessary(module_);
3197 let children = module_.children.borrow();
3198 match children.get().find(&name.name) {
3200 if name_bindings.defined_in_namespace(namespace) => {
3201 debug!("(resolving name in module) found node as child");
3202 return Success((Target::new(module_, *name_bindings),
3211 // Next, check the module's imports if necessary.
3213 // If this is a search of all imports, we should be done with glob
3214 // resolution at this point.
3215 if name_search_type == PathSearch {
3216 assert_eq!(module_.glob_count.get(), 0);
3219 // Check the list of resolved imports.
3220 let import_resolutions = module_.import_resolutions.borrow();
3221 match import_resolutions.get().find(&name.name) {
3222 Some(import_resolution) => {
3223 if import_resolution.is_public.get() &&
3224 import_resolution.outstanding_references.get() != 0 {
3225 debug!("(resolving name in module) import \
3226 unresolved; bailing out");
3227 return Indeterminate;
3229 match import_resolution.target_for_namespace(namespace) {
3231 debug!("(resolving name in module) name found, \
3232 but not in namespace {:?}",
3236 debug!("(resolving name in module) resolved to \
3238 self.used_imports.insert((import_resolution.id(namespace), namespace));
3239 return Success((target, true));
3243 None => {} // Continue.
3246 // Finally, search through external children.
3247 if namespace == TypeNS {
3249 let external_module_children =
3250 module_.external_module_children.borrow();
3251 external_module_children.get().find_copy(&name.name)
3257 @Resolver::create_name_bindings_from_module(module);
3258 return Success((Target::new(module_, name_bindings), false));
3263 // We're out of luck.
3264 debug!("(resolving name in module) failed to resolve `{}`",
3265 token::get_ident(name));
3269 fn report_unresolved_imports(&mut self, module_: @Module) {
3270 let index = module_.resolved_import_count.get();
3271 let mut imports = module_.imports.borrow_mut();
3272 let import_count = imports.get().len();
3273 if index != import_count {
3274 let sn = self.session
3276 .span_to_snippet(imports.get()[index].span)
3278 if sn.contains("::") {
3279 self.resolve_error(imports.get()[index].span,
3280 "unresolved import");
3282 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3283 sn.slice(0, sn.len()));
3284 self.resolve_error(imports.get()[index].span, err);
3288 // Descend into children and anonymous children.
3289 self.populate_module_if_necessary(module_);
3292 let children = module_.children.borrow();
3293 for (_, &child_node) in children.get().iter() {
3294 match child_node.get_module_if_available() {
3298 Some(child_module) => {
3299 self.report_unresolved_imports(child_module);
3305 let anonymous_children = module_.anonymous_children.borrow();
3306 for (_, &module_) in anonymous_children.get().iter() {
3307 self.report_unresolved_imports(module_);
3313 // This pass simply determines what all "export" keywords refer to and
3314 // writes the results into the export map.
3316 // FIXME #4953 This pass will be removed once exports change to per-item.
3317 // Then this operation can simply be performed as part of item (or import)
3320 fn record_exports(&mut self) {
3321 let root_module = self.graph_root.get_module();
3322 self.record_exports_for_module_subtree(root_module);
3325 fn record_exports_for_module_subtree(&mut self,
3327 // If this isn't a local krate, then bail out. We don't need to record
3328 // exports for nonlocal crates.
3330 match module_.def_id.get() {
3331 Some(def_id) if def_id.krate == LOCAL_CRATE => {
3333 debug!("(recording exports for module subtree) recording \
3334 exports for local module `{}`",
3335 self.module_to_str(module_));
3338 // Record exports for the root module.
3339 debug!("(recording exports for module subtree) recording \
3340 exports for root module `{}`",
3341 self.module_to_str(module_));
3345 debug!("(recording exports for module subtree) not recording \
3347 self.module_to_str(module_));
3352 self.record_exports_for_module(module_);
3353 self.populate_module_if_necessary(module_);
3356 let children = module_.children.borrow();
3357 for (_, &child_name_bindings) in children.get().iter() {
3358 match child_name_bindings.get_module_if_available() {
3362 Some(child_module) => {
3363 self.record_exports_for_module_subtree(child_module);
3369 let anonymous_children = module_.anonymous_children.borrow();
3370 for (_, &child_module) in anonymous_children.get().iter() {
3371 self.record_exports_for_module_subtree(child_module);
3375 fn record_exports_for_module(&mut self, module_: @Module) {
3376 let mut exports2 = ~[];
3378 self.add_exports_for_module(&mut exports2, module_);
3379 match module_.def_id.get() {
3381 let mut export_map2 = self.export_map2.borrow_mut();
3382 export_map2.get().insert(def_id.node, exports2);
3383 debug!("(computing exports) writing exports for {} (some)",
3390 fn add_exports_of_namebindings(&mut self,
3391 exports2: &mut ~[Export2],
3393 namebindings: @NameBindings,
3395 match namebindings.def_for_namespace(ns) {
3397 let name = token::get_name(name);
3398 debug!("(computing exports) YES: export '{}' => {:?}",
3399 name, def_id_of_def(d));
3400 exports2.push(Export2 {
3401 name: name.get().to_str(),
3402 def_id: def_id_of_def(d)
3406 debug!("(computing exports) NO: {:?}", d_opt);
3411 fn add_exports_for_module(&mut self,
3412 exports2: &mut ~[Export2],
3414 let import_resolutions = module_.import_resolutions.borrow();
3415 for (name, importresolution) in import_resolutions.get().iter() {
3416 if !importresolution.is_public.get() {
3419 let xs = [TypeNS, ValueNS];
3420 for &ns in xs.iter() {
3421 match importresolution.target_for_namespace(ns) {
3423 debug!("(computing exports) maybe export '{}'",
3424 token::get_name(*name));
3425 self.add_exports_of_namebindings(exports2,
3438 // We maintain a list of value ribs and type ribs.
3440 // Simultaneously, we keep track of the current position in the module
3441 // graph in the `current_module` pointer. When we go to resolve a name in
3442 // the value or type namespaces, we first look through all the ribs and
3443 // then query the module graph. When we resolve a name in the module
3444 // namespace, we can skip all the ribs (since nested modules are not
3445 // allowed within blocks in Rust) and jump straight to the current module
3448 // Named implementations are handled separately. When we find a method
3449 // call, we consult the module node to find all of the implementations in
3450 // scope. This information is lazily cached in the module node. We then
3451 // generate a fake "implementation scope" containing all the
3452 // implementations thus found, for compatibility with old resolve pass.
3454 fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
3455 let orig_module = self.current_module;
3457 // Move down in the graph.
3463 self.populate_module_if_necessary(orig_module);
3465 let children = orig_module.children.borrow();
3466 match children.get().find(&name.name) {
3468 debug!("!!! (with scope) didn't find `{}` in `{}`",
3469 token::get_ident(name),
3470 self.module_to_str(orig_module));
3472 Some(name_bindings) => {
3473 match (*name_bindings).get_module_if_available() {
3475 debug!("!!! (with scope) didn't find module \
3477 token::get_ident(name),
3478 self.module_to_str(orig_module));
3481 self.current_module = module_;
3491 self.current_module = orig_module;
3494 /// Wraps the given definition in the appropriate number of `def_upvar`
3496 fn upvarify(&mut self,
3501 -> Option<DefLike> {
3506 DlDef(d @ DefLocal(..)) | DlDef(d @ DefUpvar(..)) |
3507 DlDef(d @ DefArg(..)) | DlDef(d @ DefBinding(..)) => {
3509 is_ty_param = false;
3511 DlDef(d @ DefTyParam(..)) => {
3516 return Some(def_like);
3520 let mut rib_index = rib_index + 1;
3521 while rib_index < ribs.len() {
3522 match ribs[rib_index].kind {
3524 // Nothing to do. Continue.
3526 FunctionRibKind(function_id, body_id) => {
3528 def = DefUpvar(def_id_of_def(def).node,
3534 MethodRibKind(item_id, _) => {
3535 // If the def is a ty param, and came from the parent
3538 DefTyParam(did, _) if {
3539 let def_map = self.def_map.borrow();
3540 def_map.get().find(&did.node).map(|x| *x)
3541 == Some(DefTyParamBinder(item_id))
3547 // This was an attempt to access an upvar inside a
3548 // named function item. This is not allowed, so we
3553 "can't capture dynamic environment in a fn item; \
3554 use the || { ... } closure form instead");
3556 // This was an attempt to use a type parameter outside
3559 self.resolve_error(span,
3560 "attempt to use a type \
3561 argument out of scope");
3568 OpaqueFunctionRibKind => {
3570 // This was an attempt to access an upvar inside a
3571 // named function item. This is not allowed, so we
3576 "can't capture dynamic environment in a fn item; \
3577 use the || { ... } closure form instead");
3579 // This was an attempt to use a type parameter outside
3582 self.resolve_error(span,
3583 "attempt to use a type \
3584 argument out of scope");
3589 ConstantItemRibKind => {
3592 self.resolve_error(span,
3593 "cannot use an outer type \
3594 parameter in this context");
3596 // Still doesn't deal with upvars
3597 self.resolve_error(span,
3598 "attempt to use a non-constant \
3599 value in a constant");
3608 return Some(DlDef(def));
3611 fn search_ribs(&mut self,
3615 -> Option<DefLike> {
3616 // FIXME #4950: This should not use a while loop.
3617 // FIXME #4950: Try caching?
3619 let mut i = ribs.len();
3623 let bindings = ribs[i].bindings.borrow();
3624 bindings.get().find_copy(&name)
3628 return self.upvarify(ribs, i, def_like, span);
3639 fn resolve_crate(&mut self, krate: &ast::Crate) {
3640 debug!("(resolving crate) starting");
3642 visit::walk_crate(self, krate, ());
3645 fn resolve_item(&mut self, item: &Item) {
3646 debug!("(resolving item) resolving {}",
3647 token::get_ident(item.ident));
3651 // enum item: resolve all the variants' discrs,
3652 // then resolve the ty params
3653 ItemEnum(ref enum_def, ref generics) => {
3654 for variant in (*enum_def).variants.iter() {
3655 for dis_expr in variant.node.disr_expr.iter() {
3656 // resolve the discriminator expr
3658 self.with_constant_rib(|this| {
3659 this.resolve_expr(*dis_expr);
3664 // n.b. the discr expr gets visted twice.
3665 // but maybe it's okay since the first time will signal an
3666 // error if there is one? -- tjc
3667 self.with_type_parameter_rib(HasTypeParameters(generics,
3672 visit::walk_item(this, item, ());
3676 ItemTy(_, ref generics) => {
3677 self.with_type_parameter_rib(HasTypeParameters(generics,
3682 visit::walk_item(this, item, ());
3686 ItemImpl(ref generics,
3687 ref implemented_traits,
3690 self.resolve_implementation(item.id,
3694 methods.as_slice());
3697 ItemTrait(ref generics, ref traits, ref methods) => {
3698 // Create a new rib for the self type.
3699 let self_type_rib = @Rib::new(NormalRibKind);
3701 let mut type_ribs = self.type_ribs.borrow_mut();
3702 type_ribs.get().push(self_type_rib);
3704 // plain insert (no renaming)
3705 let name = self.type_self_ident.name;
3707 let mut bindings = self_type_rib.bindings.borrow_mut();
3708 bindings.get().insert(name, DlDef(DefSelfTy(item.id)));
3711 // Create a new rib for the trait-wide type parameters.
3712 self.with_type_parameter_rib(HasTypeParameters(generics,
3717 this.resolve_type_parameters(&generics.ty_params);
3719 // Resolve derived traits.
3720 for trt in traits.iter() {
3721 this.resolve_trait_reference(item.id, trt, TraitDerivation);
3724 for method in (*methods).iter() {
3725 // Create a new rib for the method-specific type
3728 // FIXME #4951: Do we need a node ID here?
3731 ast::Required(ref ty_m) => {
3732 this.with_type_parameter_rib
3733 (HasTypeParameters(&ty_m.generics,
3735 generics.ty_params.len(),
3736 MethodRibKind(item.id, Required)),
3739 // Resolve the method-specific type
3741 this.resolve_type_parameters(
3742 &ty_m.generics.ty_params);
3744 for argument in ty_m.decl.inputs.iter() {
3745 this.resolve_type(argument.ty);
3748 this.resolve_type(ty_m.decl.output);
3751 ast::Provided(m) => {
3752 this.resolve_method(MethodRibKind(item.id,
3755 generics.ty_params.len())
3761 let mut type_ribs = self.type_ribs.borrow_mut();
3762 type_ribs.get().pop();
3765 ItemStruct(ref struct_def, ref generics) => {
3766 self.resolve_struct(item.id,
3768 struct_def.fields.as_slice());
3771 ItemMod(ref module_) => {
3772 self.with_scope(Some(item.ident), |this| {
3773 this.resolve_module(module_, item.span, item.ident,
3778 ItemForeignMod(ref foreign_module) => {
3779 self.with_scope(Some(item.ident), |this| {
3780 for foreign_item in foreign_module.items.iter() {
3781 match foreign_item.node {
3782 ForeignItemFn(_, ref generics) => {
3783 this.with_type_parameter_rib(
3785 generics, foreign_item.id, 0,
3787 |this| visit::walk_foreign_item(this,
3791 ForeignItemStatic(..) => {
3792 visit::walk_foreign_item(this,
3801 ItemFn(fn_decl, _, _, ref generics, block) => {
3802 self.resolve_function(OpaqueFunctionRibKind,
3808 OpaqueFunctionRibKind),
3813 self.with_constant_rib(|this| {
3814 visit::walk_item(this, item, ());
3819 // do nothing, these are just around to be encoded
3824 fn with_type_parameter_rib(&mut self,
3825 type_parameters: TypeParameters,
3826 f: |&mut Resolver|) {
3827 match type_parameters {
3828 HasTypeParameters(generics, node_id, initial_index,
3831 let function_type_rib = @Rib::new(rib_kind);
3833 let mut type_ribs = self.type_ribs.borrow_mut();
3834 type_ribs.get().push(function_type_rib);
3837 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
3838 let ident = type_parameter.ident;
3839 debug!("with_type_parameter_rib: {} {}", node_id,
3841 let def_like = DlDef(DefTyParam
3842 (local_def(type_parameter.id),
3843 index + initial_index));
3844 // Associate this type parameter with
3845 // the item that bound it
3846 self.record_def(type_parameter.id,
3847 (DefTyParamBinder(node_id), LastMod(AllPublic)));
3848 // plain insert (no renaming)
3849 let mut bindings = function_type_rib.bindings
3851 bindings.get().insert(ident.name, def_like);
3855 NoTypeParameters => {
3862 match type_parameters {
3863 HasTypeParameters(..) => {
3864 let mut type_ribs = self.type_ribs.borrow_mut();
3865 type_ribs.get().pop();
3868 NoTypeParameters => {
3874 fn with_label_rib(&mut self, f: |&mut Resolver|) {
3876 let mut label_ribs = self.label_ribs.borrow_mut();
3877 label_ribs.get().push(@Rib::new(NormalRibKind));
3883 let mut label_ribs = self.label_ribs.borrow_mut();
3884 label_ribs.get().pop();
3888 fn with_constant_rib(&mut self, f: |&mut Resolver|) {
3890 let mut value_ribs = self.value_ribs.borrow_mut();
3891 let mut type_ribs = self.type_ribs.borrow_mut();
3892 value_ribs.get().push(@Rib::new(ConstantItemRibKind));
3893 type_ribs.get().push(@Rib::new(ConstantItemRibKind));
3897 let mut value_ribs = self.value_ribs.borrow_mut();
3898 let mut type_ribs = self.type_ribs.borrow_mut();
3899 type_ribs.get().pop();
3900 value_ribs.get().pop();
3904 fn resolve_function(&mut self,
3906 optional_declaration: Option<P<FnDecl>>,
3907 type_parameters: TypeParameters,
3909 // Create a value rib for the function.
3910 let function_value_rib = @Rib::new(rib_kind);
3912 let mut value_ribs = self.value_ribs.borrow_mut();
3913 value_ribs.get().push(function_value_rib);
3916 // Create a label rib for the function.
3918 let mut label_ribs = self.label_ribs.borrow_mut();
3919 let function_label_rib = @Rib::new(rib_kind);
3920 label_ribs.get().push(function_label_rib);
3923 // If this function has type parameters, add them now.
3924 self.with_type_parameter_rib(type_parameters, |this| {
3925 // Resolve the type parameters.
3926 match type_parameters {
3927 NoTypeParameters => {
3930 HasTypeParameters(ref generics, _, _, _) => {
3931 this.resolve_type_parameters(&generics.ty_params);
3935 // Add each argument to the rib.
3936 match optional_declaration {
3940 Some(declaration) => {
3941 for argument in declaration.inputs.iter() {
3942 let binding_mode = ArgumentIrrefutableMode;
3943 this.resolve_pattern(argument.pat,
3947 this.resolve_type(argument.ty);
3949 debug!("(resolving function) recorded argument");
3952 this.resolve_type(declaration.output);
3956 // Resolve the function body.
3957 this.resolve_block(block);
3959 debug!("(resolving function) leaving function");
3962 let mut label_ribs = self.label_ribs.borrow_mut();
3963 label_ribs.get().pop();
3965 let mut value_ribs = self.value_ribs.borrow_mut();
3966 value_ribs.get().pop();
3969 fn resolve_type_parameters(&mut self,
3970 type_parameters: &OptVec<TyParam>) {
3971 for type_parameter in type_parameters.iter() {
3972 for bound in type_parameter.bounds.iter() {
3973 self.resolve_type_parameter_bound(type_parameter.id, bound);
3975 match type_parameter.default {
3976 Some(ty) => self.resolve_type(ty),
3982 fn resolve_type_parameter_bound(&mut self,
3984 type_parameter_bound: &TyParamBound) {
3985 match *type_parameter_bound {
3986 TraitTyParamBound(ref tref) => {
3987 self.resolve_trait_reference(id, tref, TraitBoundingTypeParameter)
3989 RegionTyParamBound => {}
3993 fn resolve_trait_reference(&mut self,
3995 trait_reference: &TraitRef,
3996 reference_type: TraitReferenceType) {
3997 match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
3999 let path_str = self.path_idents_to_str(&trait_reference.path);
4000 let usage_str = match reference_type {
4001 TraitBoundingTypeParameter => "bound type parameter with",
4002 TraitImplementation => "implement",
4003 TraitDerivation => "derive"
4006 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
4007 self.resolve_error(trait_reference.path.span, msg);
4010 debug!("(resolving trait) found trait def: {:?}", def);
4011 self.record_def(trait_reference.ref_id, def);
4016 fn resolve_struct(&mut self,
4018 generics: &Generics,
4019 fields: &[StructField]) {
4020 let mut ident_map: HashMap<ast::Ident, &StructField> = HashMap::new();
4021 for field in fields.iter() {
4022 match field.node.kind {
4023 NamedField(ident, _) => {
4024 match ident_map.find(&ident) {
4025 Some(&prev_field) => {
4026 let ident_str = token::get_ident(ident);
4027 self.resolve_error(field.span,
4028 format!("field `{}` is already declared", ident_str));
4029 self.session.span_note(prev_field.span,
4030 "previously declared here");
4033 ident_map.insert(ident, field);
4041 // If applicable, create a rib for the type parameters.
4042 self.with_type_parameter_rib(HasTypeParameters(generics,
4045 OpaqueFunctionRibKind),
4047 // Resolve the type parameters.
4048 this.resolve_type_parameters(&generics.ty_params);
4051 for field in fields.iter() {
4052 this.resolve_type(field.node.ty);
4057 // Does this really need to take a RibKind or is it always going
4058 // to be NormalRibKind?
4059 fn resolve_method(&mut self,
4062 outer_type_parameter_count: uint) {
4063 let method_generics = &method.generics;
4064 let type_parameters =
4065 HasTypeParameters(method_generics,
4067 outer_type_parameter_count,
4070 self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
4073 fn resolve_implementation(&mut self,
4075 generics: &Generics,
4076 opt_trait_reference: &Option<TraitRef>,
4078 methods: &[@Method]) {
4079 // If applicable, create a rib for the type parameters.
4080 let outer_type_parameter_count = generics.ty_params.len();
4081 self.with_type_parameter_rib(HasTypeParameters(generics,
4086 // Resolve the type parameters.
4087 this.resolve_type_parameters(&generics.ty_params);
4089 // Resolve the trait reference, if necessary.
4090 let original_trait_refs;
4091 match opt_trait_reference {
4092 &Some(ref trait_reference) => {
4093 this.resolve_trait_reference(id, trait_reference,
4094 TraitImplementation);
4096 // Record the current set of trait references.
4097 let mut new_trait_refs = ~[];
4099 let def_map = this.def_map.borrow();
4100 let r = def_map.get().find(&trait_reference.ref_id);
4101 for &def in r.iter() {
4102 new_trait_refs.push(def_id_of_def(*def));
4105 original_trait_refs = Some(replace(
4106 &mut this.current_trait_refs,
4107 Some(new_trait_refs)));
4110 original_trait_refs = None;
4114 // Resolve the self type.
4115 this.resolve_type(self_type);
4117 for method in methods.iter() {
4118 // We also need a new scope for the method-specific
4120 this.resolve_method(MethodRibKind(
4122 Provided(method.id)),
4124 outer_type_parameter_count);
4126 let borrowed_type_parameters = &method.tps;
4127 self.resolve_function(MethodRibKind(
4129 Provided(method.id)),
4132 (borrowed_type_parameters,
4134 outer_type_parameter_count,
4140 // Restore the original trait references.
4141 match original_trait_refs {
4142 Some(r) => { this.current_trait_refs = r; }
4148 fn resolve_module(&mut self, module: &Mod, _span: Span,
4149 _name: Ident, id: NodeId) {
4150 // Write the implementations in scope into the module metadata.
4151 debug!("(resolving module) resolving module ID {}", id);
4152 visit::walk_mod(self, module, ());
4155 fn resolve_local(&mut self, local: &Local) {
4156 // Resolve the type.
4157 self.resolve_type(local.ty);
4159 // Resolve the initializer, if necessary.
4164 Some(initializer) => {
4165 self.resolve_expr(initializer);
4169 // Resolve the pattern.
4170 self.resolve_pattern(local.pat, LocalIrrefutableMode, None);
4173 // build a map from pattern identifiers to binding-info's.
4174 // this is done hygienically. This could arise for a macro
4175 // that expands into an or-pattern where one 'x' was from the
4176 // user and one 'x' came from the macro.
4177 fn binding_mode_map(&mut self, pat: @Pat) -> BindingMap {
4178 let mut result = HashMap::new();
4179 pat_bindings(self.def_map, pat, |binding_mode, _id, sp, path| {
4180 let name = mtwt::resolve(path_to_ident(path));
4182 binding_info {span: sp,
4183 binding_mode: binding_mode});
4188 // check that all of the arms in an or-pattern have exactly the
4189 // same set of bindings, with the same binding modes for each.
4190 fn check_consistent_bindings(&mut self, arm: &Arm) {
4191 if arm.pats.len() == 0 {
4194 let map_0 = self.binding_mode_map(*arm.pats.get(0));
4195 for (i, p) in arm.pats.iter().enumerate() {
4196 let map_i = self.binding_mode_map(*p);
4198 for (&key, &binding_0) in map_0.iter() {
4199 match map_i.find(&key) {
4203 format!("variable `{}` from pattern \\#1 is \
4204 not bound in pattern \\#{}",
4205 token::get_name(key),
4208 Some(binding_i) => {
4209 if binding_0.binding_mode != binding_i.binding_mode {
4212 format!("variable `{}` is bound with different \
4213 mode in pattern \\#{} than in pattern \\#1",
4214 token::get_name(key),
4221 for (&key, &binding) in map_i.iter() {
4222 if !map_0.contains_key(&key) {
4225 format!("variable `{}` from pattern \\#{} is \
4226 not bound in pattern \\#1",
4227 token::get_name(key),
4234 fn resolve_arm(&mut self, arm: &Arm) {
4236 let mut value_ribs = self.value_ribs.borrow_mut();
4237 value_ribs.get().push(@Rib::new(NormalRibKind));
4240 let mut bindings_list = HashMap::new();
4241 for pattern in arm.pats.iter() {
4242 self.resolve_pattern(*pattern,
4244 Some(&mut bindings_list));
4247 // This has to happen *after* we determine which
4248 // pat_idents are variants
4249 self.check_consistent_bindings(arm);
4251 visit::walk_expr_opt(self, arm.guard, ());
4252 self.resolve_expr(arm.body);
4254 let mut value_ribs = self.value_ribs.borrow_mut();
4255 value_ribs.get().pop();
4258 fn resolve_block(&mut self, block: &Block) {
4259 debug!("(resolving block) entering block");
4261 let mut value_ribs = self.value_ribs.borrow_mut();
4262 value_ribs.get().push(@Rib::new(NormalRibKind));
4265 // Move down in the graph, if there's an anonymous module rooted here.
4266 let orig_module = self.current_module;
4267 let anonymous_children = self.current_module
4270 match anonymous_children.get().find(&block.id) {
4271 None => { /* Nothing to do. */ }
4272 Some(&anonymous_module) => {
4273 debug!("(resolving block) found anonymous module, moving \
4275 self.current_module = anonymous_module;
4279 // Descend into the block.
4280 visit::walk_block(self, block, ());
4283 self.current_module = orig_module;
4285 let mut value_ribs = self.value_ribs.borrow_mut();
4286 value_ribs.get().pop();
4287 debug!("(resolving block) leaving block");
4290 fn resolve_type(&mut self, ty: &Ty) {
4292 // Like path expressions, the interpretation of path types depends
4293 // on whether the path has multiple elements in it or not.
4295 TyPath(ref path, ref bounds, path_id) => {
4296 // This is a path in the type namespace. Walk through scopes
4297 // scopes looking for it.
4298 let mut result_def = None;
4300 // First, check to see whether the name is a primitive type.
4301 if path.segments.len() == 1 {
4302 let id = path.segments.last().unwrap().identifier;
4304 match self.primitive_type_table
4308 Some(&primitive_type) => {
4310 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4314 .any(|s| !s.lifetimes.is_empty()) {
4315 self.session.span_err(path.span,
4316 "lifetime parameters \
4317 are not allowed on \
4319 } else if path.segments
4321 .any(|s| s.types.len() > 0) {
4322 self.session.span_err(path.span,
4323 "type parameters are \
4324 not allowed on this \
4336 match self.resolve_path(ty.id, path, TypeNS, true) {
4338 debug!("(resolving type) resolved `{}` to \
4340 token::get_ident(path.segments
4344 result_def = Some(def);
4351 Some(_) => {} // Continue.
4356 // Write the result into the def map.
4357 debug!("(resolving type) writing resolution for `{}` \
4359 self.path_idents_to_str(path),
4361 self.record_def(path_id, def);
4364 let msg = format!("use of undeclared type name `{}`",
4365 self.path_idents_to_str(path));
4366 self.resolve_error(ty.span, msg);
4370 bounds.as_ref().map(|bound_vec| {
4371 for bound in bound_vec.iter() {
4372 self.resolve_type_parameter_bound(ty.id, bound);
4378 c.bounds.as_ref().map(|bounds| {
4379 for bound in bounds.iter() {
4380 self.resolve_type_parameter_bound(ty.id, bound);
4383 visit::walk_ty(self, ty, ());
4387 // Just resolve embedded types.
4388 visit::walk_ty(self, ty, ());
4393 fn resolve_pattern(&mut self,
4395 mode: PatternBindingMode,
4396 // Maps idents to the node ID for the (outermost)
4397 // pattern that binds them
4398 mut bindings_list: Option<&mut HashMap<Name,NodeId>>) {
4399 let pat_id = pattern.id;
4400 walk_pat(pattern, |pattern| {
4401 match pattern.node {
4402 PatIdent(binding_mode, ref path, _)
4403 if !path.global && path.segments.len() == 1 => {
4405 // The meaning of pat_ident with no type parameters
4406 // depends on whether an enum variant or unit-like struct
4407 // with that name is in scope. The probing lookup has to
4408 // be careful not to emit spurious errors. Only matching
4409 // patterns (match) can match nullary variants or
4410 // unit-like structs. For binding patterns (let), matching
4411 // such a value is simply disallowed (since it's rarely
4414 let ident = path.segments.get(0).identifier;
4415 let renamed = mtwt::resolve(ident);
4417 match self.resolve_bare_identifier_pattern(ident) {
4418 FoundStructOrEnumVariant(def, lp)
4419 if mode == RefutableMode => {
4420 debug!("(resolving pattern) resolving `{}` to \
4421 struct or enum variant",
4422 token::get_name(renamed));
4424 self.enforce_default_binding_mode(
4428 self.record_def(pattern.id, (def, lp));
4430 FoundStructOrEnumVariant(..) => {
4431 self.resolve_error(pattern.span,
4432 format!("declaration of `{}` \
4434 variant or unit-like \
4436 token::get_name(renamed)));
4438 FoundConst(def, lp) if mode == RefutableMode => {
4439 debug!("(resolving pattern) resolving `{}` to \
4441 token::get_name(renamed));
4443 self.enforce_default_binding_mode(
4447 self.record_def(pattern.id, (def, lp));
4450 self.resolve_error(pattern.span,
4451 "only irrefutable patterns \
4454 BareIdentifierPatternUnresolved => {
4455 debug!("(resolving pattern) binding `{}`",
4456 token::get_name(renamed));
4458 let def = match mode {
4460 // For pattern arms, we must use
4461 // `def_binding` definitions.
4463 DefBinding(pattern.id, binding_mode)
4465 LocalIrrefutableMode => {
4466 // But for locals, we use `def_local`.
4467 DefLocal(pattern.id, binding_mode)
4469 ArgumentIrrefutableMode => {
4470 // And for function arguments, `def_arg`.
4471 DefArg(pattern.id, binding_mode)
4475 // Record the definition so that later passes
4476 // will be able to distinguish variants from
4477 // locals in patterns.
4479 self.record_def(pattern.id, (def, LastMod(AllPublic)));
4481 // Add the binding to the local ribs, if it
4482 // doesn't already exist in the bindings list. (We
4483 // must not add it if it's in the bindings list
4484 // because that breaks the assumptions later
4485 // passes make about or-patterns.)
4487 match bindings_list {
4488 Some(ref mut bindings_list)
4489 if !bindings_list.contains_key(&renamed) => {
4490 let this = &mut *self;
4492 let mut value_ribs =
4493 this.value_ribs.borrow_mut();
4494 let last_rib = value_ribs.get()[
4495 value_ribs.get().len() - 1];
4497 last_rib.bindings.borrow_mut();
4498 bindings.get().insert(renamed,
4501 bindings_list.insert(renamed, pat_id);
4503 Some(ref mut b) => {
4504 if b.find(&renamed) == Some(&pat_id) {
4505 // Then this is a duplicate variable
4506 // in the same disjunct, which is an
4508 self.resolve_error(pattern.span,
4509 format!("identifier `{}` is bound more \
4510 than once in the same pattern",
4511 path_to_str(path)));
4513 // Not bound in the same pattern: do nothing
4516 let this = &mut *self;
4518 let mut value_ribs =
4519 this.value_ribs.borrow_mut();
4520 let last_rib = value_ribs.get()[
4521 value_ribs.get().len() - 1];
4523 last_rib.bindings.borrow_mut();
4524 bindings.get().insert(renamed,
4532 // Check the types in the path pattern.
4533 for &ty in path.segments
4535 .flat_map(|seg| seg.types.iter()) {
4536 self.resolve_type(ty);
4540 PatIdent(binding_mode, ref path, _) => {
4541 // This must be an enum variant, struct, or constant.
4542 match self.resolve_path(pat_id, path, ValueNS, false) {
4543 Some(def @ (DefVariant(..), _)) |
4544 Some(def @ (DefStruct(..), _)) => {
4545 self.record_def(pattern.id, def);
4547 Some(def @ (DefStatic(..), _)) => {
4548 self.enforce_default_binding_mode(
4552 self.record_def(pattern.id, def);
4557 format!("`{}` is not an enum variant or constant",
4559 path.segments.last().unwrap().identifier)))
4562 self.resolve_error(path.span,
4563 "unresolved enum variant");
4567 // Check the types in the path pattern.
4568 for &ty in path.segments
4570 .flat_map(|s| s.types.iter()) {
4571 self.resolve_type(ty);
4575 PatEnum(ref path, _) => {
4576 // This must be an enum variant, struct or const.
4577 match self.resolve_path(pat_id, path, ValueNS, false) {
4578 Some(def @ (DefFn(..), _)) |
4579 Some(def @ (DefVariant(..), _)) |
4580 Some(def @ (DefStruct(..), _)) |
4581 Some(def @ (DefStatic(..), _)) => {
4582 self.record_def(pattern.id, def);
4585 self.resolve_error(path.span,
4586 format!("`{}` is not an enum variant, struct or const",
4587 token::get_ident(path.segments
4592 self.resolve_error(path.span,
4593 format!("unresolved enum variant, struct or const `{}`",
4594 token::get_ident(path.segments
4600 // Check the types in the path pattern.
4601 for &ty in path.segments
4603 .flat_map(|s| s.types.iter()) {
4604 self.resolve_type(ty);
4609 self.resolve_expr(expr);
4612 PatRange(first_expr, last_expr) => {
4613 self.resolve_expr(first_expr);
4614 self.resolve_expr(last_expr);
4617 PatStruct(ref path, _, _) => {
4618 match self.resolve_path(pat_id, path, TypeNS, false) {
4619 Some((DefTy(class_id), lp))
4620 if self.structs.contains(&class_id) => {
4621 let class_def = DefStruct(class_id);
4622 self.record_def(pattern.id, (class_def, lp));
4624 Some(definition @ (DefStruct(class_id), _)) => {
4625 assert!(self.structs.contains(&class_id));
4626 self.record_def(pattern.id, definition);
4628 Some(definition @ (DefVariant(_, variant_id, _), _))
4629 if self.structs.contains(&variant_id) => {
4630 self.record_def(pattern.id, definition);
4633 debug!("(resolving pattern) didn't find struct \
4634 def: {:?}", result);
4635 let msg = format!("`{}` does not name a structure",
4636 self.path_idents_to_str(path));
4637 self.resolve_error(path.span, msg);
4650 fn resolve_bare_identifier_pattern(&mut self, name: Ident)
4652 BareIdentifierPatternResolution {
4653 match self.resolve_item_in_lexical_scope(self.current_module,
4656 SearchThroughModules) {
4657 Success((target, _)) => {
4658 debug!("(resolve bare identifier pattern) succeeded in \
4659 finding {} at {:?}",
4660 token::get_ident(name),
4661 target.bindings.value_def.get());
4662 match target.bindings.value_def.get() {
4664 fail!("resolved name in the value namespace to a \
4665 set of name bindings with no def?!");
4668 // For the two success cases, this lookup can be
4669 // considered as not having a private component because
4670 // the lookup happened only within the current module.
4672 def @ DefVariant(..) | def @ DefStruct(..) => {
4673 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
4675 def @ DefStatic(_, false) => {
4676 return FoundConst(def, LastMod(AllPublic));
4679 return BareIdentifierPatternUnresolved;
4687 fail!("unexpected indeterminate result");
4691 debug!("(resolve bare identifier pattern) failed to find {}",
4692 token::get_ident(name));
4693 return BareIdentifierPatternUnresolved;
4698 /// If `check_ribs` is true, checks the local definitions first; i.e.
4699 /// doesn't skip straight to the containing module.
4700 fn resolve_path(&mut self,
4703 namespace: Namespace,
4704 check_ribs: bool) -> Option<(Def, LastPrivate)> {
4705 // First, resolve the types.
4706 for &ty in path.segments.iter().flat_map(|s| s.types.iter()) {
4707 self.resolve_type(ty);
4711 return self.resolve_crate_relative_path(path, namespace);
4714 let unqualified_def =
4715 self.resolve_identifier(path.segments
4722 if path.segments.len() > 1 {
4723 let def = self.resolve_module_relative_path(path, namespace);
4724 match (def, unqualified_def) {
4725 (Some((d, _)), Some((ud, _))) if d == ud => {
4726 self.session.add_lint(UnnecessaryQualification,
4729 ~"unnecessary qualification");
4737 return unqualified_def;
4740 // resolve a single identifier (used as a varref)
4741 fn resolve_identifier(&mut self,
4743 namespace: Namespace,
4746 -> Option<(Def, LastPrivate)> {
4748 match self.resolve_identifier_in_local_ribs(identifier,
4752 return Some((def, LastMod(AllPublic)));
4760 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
4764 // FIXME #4952: Merge me with resolve_name_in_module?
4765 fn resolve_definition_of_name_in_module(&mut self,
4766 containing_module: @Module,
4768 namespace: Namespace)
4770 // First, search children.
4771 self.populate_module_if_necessary(containing_module);
4774 let children = containing_module.children.borrow();
4775 match children.get().find(&name.name) {
4776 Some(child_name_bindings) => {
4777 match child_name_bindings.def_for_namespace(namespace) {
4779 // Found it. Stop the search here.
4780 let p = child_name_bindings.defined_in_public_namespace(
4782 let lp = if p {LastMod(AllPublic)} else {
4783 LastMod(DependsOn(def_id_of_def(def)))
4785 return ChildNameDefinition(def, lp);
4794 // Next, search import resolutions.
4795 let import_resolutions = containing_module.import_resolutions
4797 match import_resolutions.get().find(&name.name) {
4798 Some(import_resolution) if import_resolution.is_public.get() => {
4799 match (*import_resolution).target_for_namespace(namespace) {
4801 match target.bindings.def_for_namespace(namespace) {
4804 let id = import_resolution.id(namespace);
4805 self.used_imports.insert((id, namespace));
4806 return ImportNameDefinition(def, LastMod(AllPublic));
4809 // This can happen with external impls, due to
4810 // the imperfect way we read the metadata.
4817 Some(..) | None => {} // Continue.
4820 // Finally, search through external children.
4821 if namespace == TypeNS {
4823 let external_module_children =
4824 containing_module.external_module_children.borrow();
4825 external_module_children.get().find_copy(&name.name)
4830 match module.def_id.get() {
4831 None => {} // Continue.
4833 let lp = if module.is_public {LastMod(AllPublic)} else {
4834 LastMod(DependsOn(def_id))
4836 return ChildNameDefinition(DefMod(def_id), lp);
4843 return NoNameDefinition;
4846 // resolve a "module-relative" path, e.g. a::b::c
4847 fn resolve_module_relative_path(&mut self,
4849 namespace: Namespace)
4850 -> Option<(Def, LastPrivate)> {
4851 let module_path_idents = path.segments.init().map(|ps| ps.identifier);
4853 let containing_module;
4855 match self.resolve_module_path(self.current_module,
4861 let msg = format!("use of undeclared module `{}`",
4862 self.idents_to_str(module_path_idents));
4863 self.resolve_error(path.span, msg);
4868 fail!("indeterminate unexpected");
4871 Success((resulting_module, resulting_last_private)) => {
4872 containing_module = resulting_module;
4873 last_private = resulting_last_private;
4877 let ident = path.segments.last().unwrap().identifier;
4878 let def = match self.resolve_definition_of_name_in_module(containing_module,
4881 NoNameDefinition => {
4882 // We failed to resolve the name. Report an error.
4885 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4886 (def, last_private.or(lp))
4889 match containing_module.kind.get() {
4890 TraitModuleKind | ImplModuleKind => {
4891 let method_map = self.method_map.borrow();
4892 match method_map.get().find(&ident.name) {
4894 match containing_module.def_id.get() {
4895 Some(def_id) if s.contains(&def_id) => {
4896 debug!("containing module was a trait or impl \
4897 and name was a method -> not resolved");
4911 /// Invariant: This must be called only during main resolution, not during
4912 /// import resolution.
4913 fn resolve_crate_relative_path(&mut self,
4915 namespace: Namespace)
4916 -> Option<(Def, LastPrivate)> {
4917 let module_path_idents = path.segments.init().map(|ps| ps.identifier);
4919 let root_module = self.graph_root.get_module();
4921 let containing_module;
4923 match self.resolve_module_path_from_root(root_module,
4928 LastMod(AllPublic)) {
4930 let msg = format!("use of undeclared module `::{}`",
4931 self.idents_to_str(module_path_idents));
4932 self.resolve_error(path.span, msg);
4937 fail!("indeterminate unexpected");
4940 Success((resulting_module, resulting_last_private)) => {
4941 containing_module = resulting_module;
4942 last_private = resulting_last_private;
4946 let name = path.segments.last().unwrap().identifier;
4947 match self.resolve_definition_of_name_in_module(containing_module,
4950 NoNameDefinition => {
4951 // We failed to resolve the name. Report an error.
4954 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4955 return Some((def, last_private.or(lp)));
4960 fn resolve_identifier_in_local_ribs(&mut self,
4962 namespace: Namespace,
4965 // Check the local set of ribs.
4969 let renamed = mtwt::resolve(ident);
4970 let mut value_ribs = self.value_ribs.borrow_mut();
4971 search_result = self.search_ribs(value_ribs.get(),
4976 let name = ident.name;
4977 let mut type_ribs = self.type_ribs.borrow_mut();
4978 search_result = self.search_ribs(type_ribs.get(),
4984 match search_result {
4985 Some(DlDef(def)) => {
4986 debug!("(resolving path in local ribs) resolved `{}` to \
4988 token::get_ident(ident),
4992 Some(DlField) | Some(DlImpl(_)) | None => {
4998 fn resolve_item_by_identifier_in_lexical_scope(&mut self,
5000 namespace: Namespace)
5001 -> Option<(Def, LastPrivate)> {
5003 match self.resolve_item_in_lexical_scope(self.current_module,
5006 DontSearchThroughModules) {
5007 Success((target, _)) => {
5008 match (*target.bindings).def_for_namespace(namespace) {
5010 // This can happen if we were looking for a type and
5011 // found a module instead. Modules don't have defs.
5012 debug!("(resolving item path by identifier in lexical \
5013 scope) failed to resolve {} after success...",
5014 token::get_ident(ident));
5018 debug!("(resolving item path in lexical scope) \
5019 resolved `{}` to item",
5020 token::get_ident(ident));
5021 // This lookup is "all public" because it only searched
5022 // for one identifier in the current module (couldn't
5023 // have passed through reexports or anything like that.
5024 return Some((def, LastMod(AllPublic)));
5029 fail!("unexpected indeterminate result");
5032 debug!("(resolving item path by identifier in lexical scope) \
5033 failed to resolve {}", token::get_ident(ident));
5039 fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
5040 self.emit_errors = false;
5042 self.emit_errors = true;
5046 fn resolve_error(&mut self, span: Span, s: &str) {
5047 if self.emit_errors {
5048 self.session.span_err(span, s);
5052 fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5054 let this = &mut *self;
5056 let mut maybes: ~[token::InternedString] = ~[];
5057 let mut values: ~[uint] = ~[];
5060 let value_ribs = this.value_ribs.borrow();
5061 value_ribs.get().len()
5065 let value_ribs = this.value_ribs.borrow();
5066 let bindings = value_ribs.get()[j].bindings.borrow();
5067 for (&k, _) in bindings.get().iter() {
5068 maybes.push(token::get_name(k));
5069 values.push(uint::MAX);
5073 let mut smallest = 0;
5074 for (i, other) in maybes.iter().enumerate() {
5075 values[i] = name.lev_distance(other.get());
5077 if values[i] <= values[smallest] {
5082 if values.len() > 0 &&
5083 values[smallest] != uint::MAX &&
5084 values[smallest] < name.len() + 2 &&
5085 values[smallest] <= max_distance &&
5086 name != maybes[smallest].get() {
5088 Some(maybes[smallest].get().to_str())
5095 fn resolve_expr(&mut self, expr: &Expr) {
5096 // First, record candidate traits for this expression if it could
5097 // result in the invocation of a method call.
5099 self.record_candidate_traits_for_expr_if_necessary(expr);
5101 // Next, resolve the node.
5103 // The interpretation of paths depends on whether the path has
5104 // multiple elements in it or not.
5106 ExprPath(ref path) => {
5107 // This is a local path in the value namespace. Walk through
5108 // scopes looking for it.
5110 match self.resolve_path(expr.id, path, ValueNS, true) {
5112 // Write the result into the def map.
5113 debug!("(resolving expr) resolved `{}`",
5114 self.path_idents_to_str(path));
5116 // First-class methods are not supported yet; error
5119 (DefMethod(..), _) => {
5120 self.resolve_error(expr.span,
5121 "first-class methods \
5122 are not supported");
5123 self.session.span_note(expr.span,
5131 self.record_def(expr.id, def);
5134 let wrong_name = self.path_idents_to_str(path);
5135 // Be helpful if the name refers to a struct
5136 // (The pattern matching def_tys where the id is in self.structs
5137 // matches on regular structs while excluding tuple- and enum-like
5138 // structs, which wouldn't result in this error.)
5139 match self.with_no_errors(|this|
5140 this.resolve_path(expr.id, path, TypeNS, false)) {
5141 Some((DefTy(struct_id), _))
5142 if self.structs.contains(&struct_id) => {
5143 self.resolve_error(expr.span,
5144 format!("`{}` is a structure name, but \
5146 uses it like a function name",
5149 self.session.span_note(expr.span,
5150 format!("Did you mean to write: \
5151 `{} \\{ /* fields */ \\}`?",
5156 // limit search to 5 to reduce the number
5157 // of stupid suggestions
5158 match self.find_best_match_for_name(wrong_name, 5) {
5160 self.resolve_error(expr.span,
5161 format!("unresolved name `{}`. \
5162 Did you mean `{}`?",
5166 self.resolve_error(expr.span,
5167 format!("unresolved name `{}`.",
5175 visit::walk_expr(self, expr, ());
5178 ExprFnBlock(fn_decl, block) |
5179 ExprProc(fn_decl, block) => {
5180 self.resolve_function(FunctionRibKind(expr.id, block.id),
5181 Some(fn_decl), NoTypeParameters,
5185 ExprStruct(ref path, _, _) => {
5186 // Resolve the path to the structure it goes to.
5187 match self.resolve_path(expr.id, path, TypeNS, false) {
5188 Some((DefTy(class_id), lp)) | Some((DefStruct(class_id), lp))
5189 if self.structs.contains(&class_id) => {
5190 let class_def = DefStruct(class_id);
5191 self.record_def(expr.id, (class_def, lp));
5193 Some(definition @ (DefVariant(_, class_id, _), _))
5194 if self.structs.contains(&class_id) => {
5195 self.record_def(expr.id, definition);
5198 debug!("(resolving expression) didn't find struct \
5199 def: {:?}", result);
5200 let msg = format!("`{}` does not name a structure",
5201 self.path_idents_to_str(path));
5202 self.resolve_error(path.span, msg);
5206 visit::walk_expr(self, expr, ());
5209 ExprLoop(_, Some(label)) => {
5210 self.with_label_rib(|this| {
5211 let def_like = DlDef(DefLabel(expr.id));
5213 let mut label_ribs = this.label_ribs.borrow_mut();
5214 let rib = label_ribs.get()[label_ribs.get().len() -
5216 let mut bindings = rib.bindings.borrow_mut();
5217 let renamed = mtwt::resolve(label);
5218 bindings.get().insert(renamed, def_like);
5221 visit::walk_expr(this, expr, ());
5225 ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
5227 ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5228 let mut label_ribs = self.label_ribs.borrow_mut();
5229 let renamed = mtwt::resolve(label);
5230 match self.search_ribs(label_ribs.get(), renamed, expr.span) {
5232 self.resolve_error(expr.span,
5233 format!("use of undeclared label `{}`",
5234 token::get_ident(label))),
5235 Some(DlDef(def @ DefLabel(_))) => {
5236 // Since this def is a label, it is never read.
5237 self.record_def(expr.id, (def, LastMod(AllPublic)))
5240 self.session.span_bug(expr.span,
5241 "label wasn't mapped to a \
5248 visit::walk_expr(self, expr, ());
5253 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5255 ExprField(_, ident, _) => {
5256 // FIXME(#6890): Even though you can't treat a method like a
5257 // field, we need to add any trait methods we find that match
5258 // the field name so that we can do some nice error reporting
5259 // later on in typeck.
5260 let traits = self.search_for_traits_containing_method(ident);
5261 self.trait_map.insert(expr.id, traits);
5263 ExprMethodCall(ident, _, _) => {
5264 debug!("(recording candidate traits for expr) recording \
5267 let traits = self.search_for_traits_containing_method(ident);
5268 self.trait_map.insert(expr.id, traits);
5276 fn search_for_traits_containing_method(&mut self, name: Ident) -> ~[DefId] {
5277 debug!("(searching for traits containing method) looking for '{}'",
5278 token::get_ident(name));
5280 let mut found_traits = ~[];
5281 let mut search_module = self.current_module;
5282 let method_map = self.method_map.borrow();
5283 match method_map.get().find(&name.name) {
5284 Some(candidate_traits) => loop {
5285 // Look for the current trait.
5286 match self.current_trait_refs {
5287 Some(ref trait_def_ids) => {
5288 for trait_def_id in trait_def_ids.iter() {
5289 if candidate_traits.contains(trait_def_id) {
5290 self.add_trait_info(&mut found_traits,
5301 // Look for trait children.
5302 self.populate_module_if_necessary(search_module);
5304 let children = search_module.children.borrow();
5305 for (_, &child_names) in children.get().iter() {
5306 let def = match child_names.def_for_namespace(TypeNS) {
5310 let trait_def_id = match def {
5311 DefTrait(trait_def_id) => trait_def_id,
5314 if candidate_traits.contains(&trait_def_id) {
5315 self.add_trait_info(&mut found_traits, trait_def_id,
5320 // Look for imports.
5321 let import_resolutions = search_module.import_resolutions
5323 for (_, &import) in import_resolutions.get().iter() {
5324 let target = match import.target_for_namespace(TypeNS) {
5326 Some(target) => target,
5328 let did = match target.bindings.def_for_namespace(TypeNS) {
5329 Some(DefTrait(trait_def_id)) => trait_def_id,
5330 Some(..) | None => continue,
5332 if candidate_traits.contains(&did) {
5333 self.add_trait_info(&mut found_traits, did, name);
5334 self.used_imports.insert((import.type_id.get(), TypeNS));
5338 match search_module.parent_link {
5339 NoParentLink | ModuleParentLink(..) => break,
5340 BlockParentLink(parent_module, _) => {
5341 search_module = parent_module;
5348 return found_traits;
5351 fn add_trait_info(&self,
5352 found_traits: &mut ~[DefId],
5353 trait_def_id: DefId,
5355 debug!("(adding trait info) found trait {}:{} for method '{}'",
5358 token::get_ident(name));
5359 found_traits.push(trait_def_id);
5362 fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
5363 debug!("(recording def) recording {:?} for {:?}, last private {:?}",
5365 assert!(match lp {LastImport{..} => false, _ => true},
5366 "Import should only be used for `use` directives");
5367 self.last_private.insert(node_id, lp);
5368 let mut def_map = self.def_map.borrow_mut();
5369 def_map.get().insert_or_update_with(node_id, def, |_, old_value| {
5370 // Resolve appears to "resolve" the same ID multiple
5371 // times, so here is a sanity check it at least comes to
5372 // the same conclusion! - nmatsakis
5373 if def != *old_value {
5374 self.session.bug(format!("node_id {:?} resolved first to {:?} \
5375 and then {:?}", node_id, *old_value, def));
5380 fn enforce_default_binding_mode(&mut self,
5382 pat_binding_mode: BindingMode,
5384 match pat_binding_mode {
5385 BindByValue(_) => {}
5389 format!("cannot use `ref` binding mode with {}",
5396 // Unused import checking
5398 // Although this is mostly a lint pass, it lives in here because it depends on
5399 // resolve data structures and because it finalises the privacy information for
5400 // `use` directives.
5403 fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
5404 let mut visitor = UnusedImportCheckVisitor{ resolver: self };
5405 visit::walk_crate(&mut visitor, krate, ());
5408 fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
5409 // Ignore is_public import statements because there's no way to be sure
5410 // whether they're used or not. Also ignore imports with a dummy span
5411 // because this means that they were generated in some fashion by the
5412 // compiler and we don't need to consider them.
5413 if vi.vis == Public { return }
5414 if vi.span == DUMMY_SP { return }
5417 ViewItemExternMod(..) => {} // ignore
5418 ViewItemUse(ref path) => {
5419 for p in path.iter() {
5421 ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
5422 ViewPathList(_, ref list, _) => {
5423 for i in list.iter() {
5424 self.finalize_import(i.node.id, i.span);
5427 ViewPathGlob(_, id) => {
5428 if !self.used_imports.contains(&(id, TypeNS)) &&
5429 !self.used_imports.contains(&(id, ValueNS)) {
5430 self.session.add_lint(UnusedImports, id, p.span, ~"unused import");
5439 // We have information about whether `use` (import) directives are actually used now.
5440 // If an import is not used at all, we signal a lint error. If an import is only used
5441 // for a single namespace, we remove the other namespace from the recorded privacy
5442 // information. That means in privacy.rs, we will only check imports and namespaces
5443 // which are used. In particular, this means that if an import could name either a
5444 // public or private item, we will check the correct thing, dependent on how the import
5446 fn finalize_import(&mut self, id: NodeId, span: Span) {
5447 debug!("finalizing import uses for {}", self.session.codemap.span_to_snippet(span));
5449 if !self.used_imports.contains(&(id, TypeNS)) &&
5450 !self.used_imports.contains(&(id, ValueNS)) {
5451 self.session.add_lint(UnusedImports, id, span, ~"unused import");
5454 let (v_priv, t_priv) = match self.last_private.find(&id) {
5455 Some(&LastImport{value_priv: v,
5458 type_used: _}) => (v, t),
5459 Some(_) => fail!("We should only have LastImport for `use` directives"),
5463 let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
5468 let t_used = if self.used_imports.contains(&(id, TypeNS)) {
5474 match (v_priv, t_priv) {
5475 // Since some items may be both in the value _and_ type namespaces (e.g., structs)
5476 // we might have two LastPrivates pointing at the same thing. There is no point
5477 // checking both, so lets not check the value one.
5478 (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
5482 self.last_private.insert(id, LastImport{value_priv: v_priv,
5485 type_used: t_used});
5491 // Diagnostics are not particularly efficient, because they're rarely
5495 /// A somewhat inefficient routine to obtain the name of a module.
5496 fn module_to_str(&mut self, module_: @Module) -> ~str {
5497 let mut idents = ~[];
5498 let mut current_module = module_;
5500 match current_module.parent_link {
5504 ModuleParentLink(module_, name) => {
5506 current_module = module_;
5508 BlockParentLink(module_, _) => {
5509 idents.push(special_idents::opaque);
5510 current_module = module_;
5515 if idents.len() == 0 {
5518 return self.idents_to_str(idents.move_rev_iter().collect::<~[ast::Ident]>());
5521 #[allow(dead_code)] // useful for debugging
5522 fn dump_module(&mut self, module_: @Module) {
5523 debug!("Dump of module `{}`:", self.module_to_str(module_));
5525 debug!("Children:");
5526 self.populate_module_if_necessary(module_);
5527 let children = module_.children.borrow();
5528 for (&name, _) in children.get().iter() {
5529 debug!("* {}", token::get_name(name));
5532 debug!("Import resolutions:");
5533 let import_resolutions = module_.import_resolutions.borrow();
5534 for (&name, import_resolution) in import_resolutions.get().iter() {
5536 match import_resolution.target_for_namespace(ValueNS) {
5537 None => { value_repr = ~""; }
5539 value_repr = ~" value:?";
5545 match import_resolution.target_for_namespace(TypeNS) {
5546 None => { type_repr = ~""; }
5548 type_repr = ~" type:?";
5553 debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
5558 pub struct CrateMap {
5560 exp_map2: ExportMap2,
5561 trait_map: TraitMap,
5562 external_exports: ExternalExports,
5563 last_private_map: LastPrivateMap,
5566 /// Entry point to crate resolution.
5567 pub fn resolve_crate(session: Session,
5568 lang_items: @LanguageItems,
5571 let mut resolver = Resolver(session, lang_items, krate.span);
5572 resolver.resolve(krate);
5573 let Resolver { def_map, export_map2, trait_map, last_private,
5574 external_exports, .. } = resolver;
5577 exp_map2: export_map2,
5578 trait_map: trait_map,
5579 external_exports: external_exports,
5580 last_private_map: last_private,