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;
15 use metadata::csearch;
16 use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
18 use middle::lang_items::LanguageItems;
19 use middle::pat_util::pat_bindings;
20 use middle::subst::{ParamSpace, FnSpace, TypeSpace};
21 use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
22 use util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
24 use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate};
25 use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
26 use syntax::ast::{ExprFnBlock, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
27 use syntax::ast::{ExprPath, ExprProc, ExprStruct, ExprUnboxedFn, FnDecl};
28 use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
29 use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod};
30 use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct};
31 use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local, Method};
32 use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
33 use syntax::ast::{P, Pat, PatEnum, PatIdent, PatLit};
34 use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
35 use syntax::ast::{PrimTy, Public, SelfExplicit, SelfStatic};
36 use syntax::ast::{RegionTyParamBound, StmtDecl, StructField};
37 use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
38 use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
39 use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt};
40 use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyProc, TyRptr};
41 use syntax::ast::{TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
42 use syntax::ast::{UnboxedFnTyParamBound, UnnamedField, UnsafeFn, Variant};
43 use syntax::ast::{ViewItem, ViewItemExternCrate, ViewItemUse, ViewPathGlob};
44 use syntax::ast::{ViewPathList, ViewPathSimple, Visibility};
46 use syntax::ast_util::{PostExpansionMethod, local_def};
47 use syntax::ast_util::{trait_item_to_ty_method, walk_pat};
48 use syntax::attr::AttrMetaMethods;
49 use syntax::ext::mtwt;
50 use syntax::parse::token::special_names;
51 use syntax::parse::token::special_idents;
52 use syntax::parse::token;
53 use syntax::codemap::{Span, DUMMY_SP, Pos};
54 use syntax::owned_slice::OwnedSlice;
56 use syntax::visit::Visitor;
58 use std::collections::{HashMap, HashSet};
59 use std::cell::{Cell, RefCell};
61 use std::mem::replace;
62 use std::rc::{Rc, Weak};
66 pub type DefMap = RefCell<NodeMap<Def>>;
70 binding_mode: BindingMode,
73 // Map from the name in a pattern to its binding mode.
74 type BindingMap = HashMap<Name,binding_info>;
76 // Trait method resolution
77 pub type TraitMap = NodeMap<Vec<DefId> >;
79 // This is the replacement export map. It maps a module to all of the exports
81 pub type ExportMap2 = RefCell<NodeMap<Vec<Export2> >>;
84 pub name: String, // The name of the target.
85 pub def_id: DefId, // The definition of the target.
88 // This set contains all exported definitions from external crates. The set does
89 // not contain any entries from local crates.
90 pub type ExternalExports = DefIdSet;
93 pub type LastPrivateMap = NodeMap<LastPrivate>;
95 pub enum LastPrivate {
97 // `use` directives (imports) can refer to two separate definitions in the
98 // type and value namespaces. We record here the last private node for each
99 // and whether the import is in fact used for each.
100 // If the Option<PrivateDep> fields are None, it means there is no definition
101 // in that namespace.
102 LastImport{pub value_priv: Option<PrivateDep>,
103 pub value_used: ImportUse,
104 pub type_priv: Option<PrivateDep>,
105 pub type_used: ImportUse},
108 pub enum PrivateDep {
113 // How an import is used.
114 #[deriving(PartialEq)]
116 Unused, // The import is not used.
117 Used, // The import is used.
121 fn or(self, other: LastPrivate) -> LastPrivate {
122 match (self, other) {
123 (me, LastMod(AllPublic)) => me,
129 #[deriving(PartialEq)]
130 enum PatternBindingMode {
132 LocalIrrefutableMode,
133 ArgumentIrrefutableMode,
136 #[deriving(PartialEq, Eq, Hash)]
142 #[deriving(PartialEq)]
143 enum NamespaceError {
150 /// A NamespaceResult represents the result of resolving an import in
151 /// a particular namespace. The result is either definitely-resolved,
152 /// definitely- unresolved, or unknown.
154 enum NamespaceResult {
155 /// Means that resolve hasn't gathered enough information yet to determine
156 /// whether the name is bound in this namespace. (That is, it hasn't
157 /// resolved all `use` directives yet.)
159 /// Means that resolve has determined that the name is definitely
160 /// not bound in the namespace.
162 /// Means that resolve has determined that the name is bound in the Module
163 /// argument, and specified by the NameBindings argument.
164 BoundResult(Rc<Module>, Rc<NameBindings>)
167 impl NamespaceResult {
168 fn is_unknown(&self) -> bool {
170 UnknownResult => true,
174 fn is_unbound(&self) -> bool {
176 UnboundResult => true,
182 enum NameDefinition {
183 NoNameDefinition, //< The name was unbound.
184 ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
185 ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
188 impl<'a> Visitor<()> for Resolver<'a> {
189 fn visit_item(&mut self, item: &Item, _: ()) {
190 self.resolve_item(item);
192 fn visit_arm(&mut self, arm: &Arm, _: ()) {
193 self.resolve_arm(arm);
195 fn visit_block(&mut self, block: &Block, _: ()) {
196 self.resolve_block(block);
198 fn visit_expr(&mut self, expr: &Expr, _: ()) {
199 self.resolve_expr(expr);
201 fn visit_local(&mut self, local: &Local, _: ()) {
202 self.resolve_local(local);
204 fn visit_ty(&mut self, ty: &Ty, _: ()) {
205 self.resolve_type(ty);
209 /// Contains data for specific types of import directives.
210 enum ImportDirectiveSubclass {
211 SingleImport(Ident /* target */, Ident /* source */),
215 /// The context that we thread through while building the reduced graph.
217 enum ReducedGraphParent {
218 ModuleReducedGraphParent(Rc<Module>)
221 impl ReducedGraphParent {
222 fn module(&self) -> Rc<Module> {
224 ModuleReducedGraphParent(ref m) => {
231 type ErrorMessage = Option<(Span, String)>;
233 enum ResolveResult<T> {
234 Failed(ErrorMessage), // Failed to resolve the name, optional helpful error message.
235 Indeterminate, // Couldn't determine due to unresolved globs.
236 Success(T) // Successfully resolved the import.
239 impl<T> ResolveResult<T> {
240 fn indeterminate(&self) -> bool {
241 match *self { Indeterminate => true, _ => false }
245 enum FallbackSuggestion {
250 StaticMethod(String),
251 StaticTraitMethod(String),
254 enum TypeParameters<'a> {
260 // Identifies the things that these parameters
261 // were declared on (type, fn, etc)
264 // ID of the enclosing item.
267 // The kind of the rib used for type parameters.
271 // The rib kind controls the translation of argument or local definitions
272 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
275 // No translation needs to be applied.
278 // We passed through a function scope at the given node ID. Translate
279 // upvars as appropriate.
280 FunctionRibKind(NodeId /* func id */, NodeId /* body id */),
282 // We passed through an impl or trait and are now in one of its
283 // methods. Allow references to ty params that impl or trait
284 // binds. Disallow any other upvars (including other ty params that are
286 // parent; method itself
287 MethodRibKind(NodeId, MethodSort),
289 // We passed through an item scope. Disallow upvars.
292 // We're in a constant item. Can't refer to dynamic stuff.
296 // Methods can be required or provided. RequiredMethod methods only occur in traits.
299 ProvidedMethod(NodeId)
302 enum UseLexicalScopeFlag {
307 enum ModulePrefixResult {
309 PrefixFound(Rc<Module>, uint)
312 #[deriving(Clone, Eq, PartialEq)]
313 pub enum TraitItemKind {
314 NonstaticMethodTraitItemKind,
315 StaticMethodTraitItemKind,
319 pub fn from_explicit_self_category(explicit_self_category:
320 ExplicitSelfCategory)
322 if explicit_self_category == StaticExplicitSelfCategory {
323 StaticMethodTraitItemKind
325 NonstaticMethodTraitItemKind
330 #[deriving(PartialEq)]
331 enum NameSearchType {
332 /// We're doing a name search in order to resolve a `use` directive.
335 /// We're doing a name search in order to resolve a path type, a path
336 /// expression, or a path pattern.
340 enum BareIdentifierPatternResolution {
341 FoundStructOrEnumVariant(Def, LastPrivate),
342 FoundConst(Def, LastPrivate),
343 BareIdentifierPatternUnresolved
346 // Specifies how duplicates should be handled when adding a child item if
347 // another item exists with the same name in some namespace.
348 #[deriving(PartialEq)]
349 enum DuplicateCheckingMode {
350 ForbidDuplicateModules,
351 ForbidDuplicateTypesAndModules,
352 ForbidDuplicateValues,
353 ForbidDuplicateTypesAndValues,
359 bindings: RefCell<HashMap<Name, DefLike>>,
364 fn new(kind: RibKind) -> Rib {
366 bindings: RefCell::new(HashMap::new()),
372 /// One import directive.
373 struct ImportDirective {
374 module_path: Vec<Ident>,
375 subclass: ImportDirectiveSubclass,
378 is_public: bool, // see note in ImportResolution about how to use this
382 impl ImportDirective {
383 fn new(module_path: Vec<Ident> ,
384 subclass: ImportDirectiveSubclass,
391 module_path: module_path,
395 is_public: is_public,
396 shadowable: shadowable,
401 /// The item that an import resolves to.
404 target_module: Rc<Module>,
405 bindings: Rc<NameBindings>,
410 fn new(target_module: Rc<Module>,
411 bindings: Rc<NameBindings>,
415 target_module: target_module,
417 shadowable: shadowable,
422 /// An ImportResolution represents a particular `use` directive.
423 struct ImportResolution {
424 /// Whether this resolution came from a `use` or a `pub use`. Note that this
425 /// should *not* be used whenever resolution is being performed, this is
426 /// only looked at for glob imports statements currently. Privacy testing
427 /// occurs during a later phase of compilation.
430 // The number of outstanding references to this name. When this reaches
431 // zero, outside modules can count on the targets being correct. Before
432 // then, all bets are off; future imports could override this name.
433 outstanding_references: uint,
435 /// The value that this `use` directive names, if there is one.
436 value_target: Option<Target>,
437 /// The source node of the `use` directive leading to the value target
441 /// The type that this `use` directive names, if there is one.
442 type_target: Option<Target>,
443 /// The source node of the `use` directive leading to the type target
448 impl ImportResolution {
449 fn new(id: NodeId, is_public: bool) -> ImportResolution {
453 outstanding_references: 0,
456 is_public: is_public,
460 fn target_for_namespace(&self, namespace: Namespace)
463 TypeNS => self.type_target.clone(),
464 ValueNS => self.value_target.clone(),
468 fn id(&self, namespace: Namespace) -> NodeId {
470 TypeNS => self.type_id,
471 ValueNS => self.value_id,
476 /// The link from a module up to its nearest parent node.
480 ModuleParentLink(Weak<Module>, Ident),
481 BlockParentLink(Weak<Module>, NodeId)
484 /// The type of module this is.
485 #[deriving(PartialEq)]
494 /// One node in the tree of modules.
496 parent_link: ParentLink,
497 def_id: Cell<Option<DefId>>,
498 kind: Cell<ModuleKind>,
501 children: RefCell<HashMap<Name, Rc<NameBindings>>>,
502 imports: RefCell<Vec<ImportDirective>>,
504 // The external module children of this node that were declared with
506 external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
508 // The anonymous children of this node. Anonymous children are pseudo-
509 // modules that are implicitly created around items contained within
512 // For example, if we have this:
520 // There will be an anonymous module created around `g` with the ID of the
521 // entry block for `f`.
522 anonymous_children: RefCell<NodeMap<Rc<Module>>>,
524 // The status of resolving each import in this module.
525 import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
527 // The number of unresolved globs that this module exports.
528 glob_count: Cell<uint>,
530 // The index of the import we're resolving.
531 resolved_import_count: Cell<uint>,
533 // Whether this module is populated. If not populated, any attempt to
534 // access the children must be preceded with a
535 // `populate_module_if_necessary` call.
536 populated: Cell<bool>,
540 fn new(parent_link: ParentLink,
541 def_id: Option<DefId>,
547 parent_link: parent_link,
548 def_id: Cell::new(def_id),
549 kind: Cell::new(kind),
550 is_public: is_public,
551 children: RefCell::new(HashMap::new()),
552 imports: RefCell::new(Vec::new()),
553 external_module_children: RefCell::new(HashMap::new()),
554 anonymous_children: RefCell::new(NodeMap::new()),
555 import_resolutions: RefCell::new(HashMap::new()),
556 glob_count: Cell::new(0),
557 resolved_import_count: Cell::new(0),
558 populated: Cell::new(!external),
562 fn all_imports_resolved(&self) -> bool {
563 self.imports.borrow().len() == self.resolved_import_count.get()
567 // Records a possibly-private type definition.
570 is_public: bool, // see note in ImportResolution about how to use this
571 module_def: Option<Rc<Module>>,
572 type_def: Option<Def>,
573 type_span: Option<Span>
576 // Records a possibly-private value definition.
579 is_public: bool, // see note in ImportResolution about how to use this
581 value_span: Option<Span>,
584 // Records the definitions (at most one for each namespace) that a name is
586 struct NameBindings {
587 type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
588 value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
591 /// Ways in which a trait can be referenced
592 enum TraitReferenceType {
593 TraitImplementation, // impl SomeTrait for T { ... }
594 TraitDerivation, // trait T : SomeTrait { ... }
595 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
599 fn new() -> NameBindings {
601 type_def: RefCell::new(None),
602 value_def: RefCell::new(None),
606 /// Creates a new module in this set of name bindings.
607 fn define_module(&self,
608 parent_link: ParentLink,
609 def_id: Option<DefId>,
614 // Merges the module with the existing type def or creates a new one.
615 let module_ = Rc::new(Module::new(parent_link, def_id, kind, external,
617 let type_def = self.type_def.borrow().clone();
620 *self.type_def.borrow_mut() = Some(TypeNsDef {
621 is_public: is_public,
622 module_def: Some(module_),
628 *self.type_def.borrow_mut() = Some(TypeNsDef {
629 is_public: is_public,
630 module_def: Some(module_),
632 type_def: type_def.type_def
638 /// Sets the kind of the module, creating a new one if necessary.
639 fn set_module_kind(&self,
640 parent_link: ParentLink,
641 def_id: Option<DefId>,
646 let type_def = self.type_def.borrow().clone();
649 let module = Module::new(parent_link, def_id, kind,
650 external, is_public);
651 *self.type_def.borrow_mut() = Some(TypeNsDef {
652 is_public: is_public,
653 module_def: Some(Rc::new(module)),
659 match type_def.module_def {
661 let module = Module::new(parent_link,
666 *self.type_def.borrow_mut() = Some(TypeNsDef {
667 is_public: is_public,
668 module_def: Some(Rc::new(module)),
669 type_def: type_def.type_def,
673 Some(module_def) => module_def.kind.set(kind),
679 /// Records a type definition.
680 fn define_type(&self, def: Def, sp: Span, is_public: bool) {
681 // Merges the type with the existing type def or creates a new one.
682 let type_def = self.type_def.borrow().clone();
685 *self.type_def.borrow_mut() = Some(TypeNsDef {
689 is_public: is_public,
693 *self.type_def.borrow_mut() = Some(TypeNsDef {
696 module_def: type_def.module_def,
697 is_public: is_public,
703 /// Records a value definition.
704 fn define_value(&self, def: Def, sp: Span, is_public: bool) {
705 *self.value_def.borrow_mut() = Some(ValueNsDef {
707 value_span: Some(sp),
708 is_public: is_public,
712 /// Returns the module node if applicable.
713 fn get_module_if_available(&self) -> Option<Rc<Module>> {
714 match *self.type_def.borrow() {
715 Some(ref type_def) => type_def.module_def.clone(),
721 * Returns the module node. Fails if this node does not have a module
724 fn get_module(&self) -> Rc<Module> {
725 match self.get_module_if_available() {
727 fail!("get_module called on a node with no module \
730 Some(module_def) => module_def
734 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
736 TypeNS => return self.type_def.borrow().is_some(),
737 ValueNS => return self.value_def.borrow().is_some()
741 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
743 TypeNS => match *self.type_def.borrow() {
744 Some(ref def) => def.is_public, None => false
746 ValueNS => match *self.value_def.borrow() {
747 Some(ref def) => def.is_public, None => false
752 fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
755 match *self.type_def.borrow() {
757 Some(ref type_def) => {
758 match type_def.type_def {
759 Some(type_def) => Some(type_def),
761 match type_def.module_def {
762 Some(ref module) => {
763 match module.def_id.get() {
764 Some(did) => Some(DefMod(did)),
776 match *self.value_def.borrow() {
778 Some(value_def) => Some(value_def.def)
784 fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
785 if self.defined_in_namespace(namespace) {
788 match *self.type_def.borrow() {
790 Some(ref type_def) => type_def.type_span
794 match *self.value_def.borrow() {
796 Some(ref value_def) => value_def.value_span
806 /// Interns the names of the primitive types.
807 struct PrimitiveTypeTable {
808 primitive_types: HashMap<Name, PrimTy>,
811 impl PrimitiveTypeTable {
812 fn new() -> PrimitiveTypeTable {
813 let mut table = PrimitiveTypeTable {
814 primitive_types: HashMap::new()
817 table.intern("bool", TyBool);
818 table.intern("char", TyChar);
819 table.intern("f32", TyFloat(TyF32));
820 table.intern("f64", TyFloat(TyF64));
821 table.intern("int", TyInt(TyI));
822 table.intern("i8", TyInt(TyI8));
823 table.intern("i16", TyInt(TyI16));
824 table.intern("i32", TyInt(TyI32));
825 table.intern("i64", TyInt(TyI64));
826 table.intern("str", TyStr);
827 table.intern("uint", TyUint(TyU));
828 table.intern("u8", TyUint(TyU8));
829 table.intern("u16", TyUint(TyU16));
830 table.intern("u32", TyUint(TyU32));
831 table.intern("u64", TyUint(TyU64));
836 fn intern(&mut self, string: &str, primitive_type: PrimTy) {
837 self.primitive_types.insert(token::intern(string), primitive_type);
842 fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
845 ModuleError | TypeError => "type or module",
846 ValueError => "value",
850 /// The main resolver class.
851 struct Resolver<'a> {
852 session: &'a Session,
854 graph_root: NameBindings,
856 trait_item_map: RefCell<FnvHashMap<(Name, DefId), TraitItemKind>>,
858 structs: FnvHashMap<DefId, Vec<Name>>,
860 // The number of imports that are currently unresolved.
861 unresolved_imports: uint,
863 // The module that represents the current item scope.
864 current_module: Rc<Module>,
866 // The current set of local scopes, for values.
867 // FIXME #4948: Reuse ribs to avoid allocation.
868 value_ribs: RefCell<Vec<Rib>>,
870 // The current set of local scopes, for types.
871 type_ribs: RefCell<Vec<Rib>>,
873 // The current set of local scopes, for labels.
874 label_ribs: RefCell<Vec<Rib>>,
876 // The trait that the current context can refer to.
877 current_trait_ref: Option<(DefId, TraitRef)>,
879 // The current self type if inside an impl (used for better errors).
880 current_self_type: Option<Ty>,
882 // The ident for the keyword "self".
884 // The ident for the non-keyword "Self".
885 type_self_name: Name,
887 // The idents for the primitive types.
888 primitive_type_table: PrimitiveTypeTable,
891 export_map2: ExportMap2,
893 external_exports: ExternalExports,
894 last_private: LastPrivateMap,
896 // Whether or not to print error messages. Can be set to true
897 // when getting additional info for error message suggestions,
898 // so as to avoid printing duplicate errors
901 used_imports: HashSet<(NodeId, Namespace)>,
904 struct BuildReducedGraphVisitor<'a, 'b:'a> {
905 resolver: &'a mut Resolver<'b>,
908 impl<'a, 'b> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a, 'b> {
910 fn visit_item(&mut self, item: &Item, context: ReducedGraphParent) {
911 let p = self.resolver.build_reduced_graph_for_item(item, context);
912 visit::walk_item(self, item, p);
915 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem,
916 context: ReducedGraphParent) {
917 self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
920 let mut v = BuildReducedGraphVisitor{ resolver: r };
921 visit::walk_foreign_item(&mut v, foreign_item, context.clone());
925 fn visit_view_item(&mut self, view_item: &ViewItem, context: ReducedGraphParent) {
926 self.resolver.build_reduced_graph_for_view_item(view_item, context);
929 fn visit_block(&mut self, block: &Block, context: ReducedGraphParent) {
930 let np = self.resolver.build_reduced_graph_for_block(block, context);
931 visit::walk_block(self, block, np);
936 struct UnusedImportCheckVisitor<'a, 'b:'a> {
937 resolver: &'a mut Resolver<'b>
940 impl<'a, 'b> Visitor<()> for UnusedImportCheckVisitor<'a, 'b> {
941 fn visit_view_item(&mut self, vi: &ViewItem, _: ()) {
942 self.resolver.check_for_item_unused_imports(vi);
943 visit::walk_view_item(self, vi, ());
947 impl<'a> Resolver<'a> {
948 fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
949 let graph_root = NameBindings::new();
951 graph_root.define_module(NoParentLink,
952 Some(DefId { krate: 0, node: 0 }),
958 let current_module = graph_root.get_module();
963 // The outermost module has def ID 0; this is not reflected in the
966 graph_root: graph_root,
968 trait_item_map: RefCell::new(FnvHashMap::new()),
969 structs: FnvHashMap::new(),
971 unresolved_imports: 0,
973 current_module: current_module,
974 value_ribs: RefCell::new(Vec::new()),
975 type_ribs: RefCell::new(Vec::new()),
976 label_ribs: RefCell::new(Vec::new()),
978 current_trait_ref: None,
979 current_self_type: None,
981 self_name: special_names::self_,
982 type_self_name: special_names::type_self,
984 primitive_type_table: PrimitiveTypeTable::new(),
986 def_map: RefCell::new(NodeMap::new()),
987 export_map2: RefCell::new(NodeMap::new()),
988 trait_map: NodeMap::new(),
989 used_imports: HashSet::new(),
990 external_exports: DefIdSet::new(),
991 last_private: NodeMap::new(),
996 /// The main name resolution procedure.
997 fn resolve(&mut self, krate: &ast::Crate) {
998 self.build_reduced_graph(krate);
999 self.session.abort_if_errors();
1001 self.resolve_imports();
1002 self.session.abort_if_errors();
1004 self.record_exports();
1005 self.session.abort_if_errors();
1007 self.resolve_crate(krate);
1008 self.session.abort_if_errors();
1010 self.check_for_unused_imports(krate);
1014 // Reduced graph building
1016 // Here we build the "reduced graph": the graph of the module tree without
1017 // any imports resolved.
1020 /// Constructs the reduced graph for the entire crate.
1021 fn build_reduced_graph(&mut self, krate: &ast::Crate) {
1022 let initial_parent =
1023 ModuleReducedGraphParent(self.graph_root.get_module());
1025 let mut visitor = BuildReducedGraphVisitor { resolver: self, };
1026 visit::walk_crate(&mut visitor, krate, initial_parent);
1030 * Adds a new child item to the module definition of the parent node and
1031 * returns its corresponding name bindings as well as the current parent.
1032 * Or, if we're inside a block, creates (or reuses) an anonymous module
1033 * corresponding to the innermost block ID and returns the name bindings
1034 * as well as the newly-created parent.
1036 * If this node does not have a module definition and we are not inside
1041 reduced_graph_parent: ReducedGraphParent,
1042 duplicate_checking_mode: DuplicateCheckingMode,
1043 // For printing errors
1045 -> Rc<NameBindings> {
1046 // If this is the immediate descendant of a module, then we add the
1047 // child name directly. Otherwise, we create or reuse an anonymous
1048 // module and add the child to that.
1050 let module_ = reduced_graph_parent.module();
1052 self.check_for_conflicts_between_external_crates_and_items(&*module_,
1056 // Add or reuse the child.
1057 let child = module_.children.borrow().find_copy(&name.name);
1060 let child = Rc::new(NameBindings::new());
1061 module_.children.borrow_mut().insert(name.name, child.clone());
1065 // Enforce the duplicate checking mode:
1067 // * If we're requesting duplicate module checking, check that
1068 // there isn't a module in the module with the same name.
1070 // * If we're requesting duplicate type checking, check that
1071 // there isn't a type in the module with the same name.
1073 // * If we're requesting duplicate value checking, check that
1074 // there isn't a value in the module with the same name.
1076 // * If we're requesting duplicate type checking and duplicate
1077 // value checking, check that there isn't a duplicate type
1078 // and a duplicate value with the same name.
1080 // * If no duplicate checking was requested at all, do
1083 let mut duplicate_type = NoError;
1084 let ns = match duplicate_checking_mode {
1085 ForbidDuplicateModules => {
1086 if child.get_module_if_available().is_some() {
1087 duplicate_type = ModuleError;
1091 ForbidDuplicateTypesAndModules => {
1092 match child.def_for_namespace(TypeNS) {
1094 Some(_) if child.get_module_if_available()
1095 .map(|m| m.kind.get()) ==
1096 Some(ImplModuleKind) => {}
1097 Some(_) => duplicate_type = TypeError
1101 ForbidDuplicateValues => {
1102 if child.defined_in_namespace(ValueNS) {
1103 duplicate_type = ValueError;
1107 ForbidDuplicateTypesAndValues => {
1109 match child.def_for_namespace(TypeNS) {
1110 Some(DefMod(_)) | None => {}
1113 duplicate_type = TypeError;
1116 if child.defined_in_namespace(ValueNS) {
1117 duplicate_type = ValueError;
1122 OverwriteDuplicates => None
1124 if duplicate_type != NoError {
1125 // Return an error here by looking up the namespace that
1126 // had the duplicate.
1127 let ns = ns.unwrap();
1128 self.resolve_error(sp,
1129 format!("duplicate definition of {} `{}`",
1130 namespace_error_to_string(duplicate_type),
1131 token::get_ident(name)).as_slice());
1133 let r = child.span_for_namespace(ns);
1134 for sp in r.iter() {
1135 self.session.span_note(*sp,
1136 format!("first definition of {} `{}` here",
1137 namespace_error_to_string(duplicate_type),
1138 token::get_ident(name)).as_slice());
1147 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1148 // If the block has view items, we need an anonymous module.
1149 if block.view_items.len() > 0 {
1153 // Check each statement.
1154 for statement in block.stmts.iter() {
1155 match statement.node {
1156 StmtDecl(declaration, _) => {
1157 match declaration.node {
1172 // If we found neither view items nor items, we don't need to create
1173 // an anonymous module.
1178 fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Ident)
1181 ModuleReducedGraphParent(module_) => {
1182 return ModuleParentLink(module_.downgrade(), name);
1187 /// Constructs the reduced graph for one item.
1188 fn build_reduced_graph_for_item(&mut self,
1190 parent: ReducedGraphParent)
1191 -> ReducedGraphParent
1193 let ident = item.ident;
1195 let is_public = item.vis == ast::Public;
1200 self.add_child(ident, parent.clone(), ForbidDuplicateModules, sp);
1202 let parent_link = self.get_parent_link(parent, ident);
1203 let def_id = DefId { krate: 0, node: item.id };
1204 name_bindings.define_module(parent_link,
1208 item.vis == ast::Public,
1211 ModuleReducedGraphParent(name_bindings.get_module())
1214 ItemForeignMod(..) => parent,
1216 // These items live in the value namespace.
1217 ItemStatic(_, m, _) => {
1219 self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
1220 let mutbl = m == ast::MutMutable;
1222 name_bindings.define_value
1223 (DefStatic(local_def(item.id), mutbl), sp, is_public);
1226 ItemFn(_, fn_style, _, _, _) => {
1228 self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
1230 let def = DefFn(local_def(item.id), fn_style);
1231 name_bindings.define_value(def, sp, is_public);
1235 // These items live in the type namespace.
1238 self.add_child(ident,
1240 ForbidDuplicateTypesAndModules,
1243 name_bindings.define_type
1244 (DefTy(local_def(item.id)), sp, is_public);
1248 ItemEnum(ref enum_definition, _) => {
1250 self.add_child(ident,
1252 ForbidDuplicateTypesAndModules,
1255 name_bindings.define_type
1256 (DefTy(local_def(item.id)), sp, is_public);
1258 for variant in (*enum_definition).variants.iter() {
1259 self.build_reduced_graph_for_variant(
1268 // These items live in both the type and value namespaces.
1269 ItemStruct(struct_def, _) => {
1270 // Adding to both Type and Value namespaces or just Type?
1271 let (forbid, ctor_id) = match struct_def.ctor_id {
1272 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1273 None => (ForbidDuplicateTypesAndModules, None)
1276 let name_bindings = self.add_child(ident, parent.clone(), forbid, sp);
1278 // Define a name in the type namespace.
1279 name_bindings.define_type(DefTy(local_def(item.id)), sp, is_public);
1281 // If this is a newtype or unit-like struct, define a name
1282 // in the value namespace as well
1283 ctor_id.while_some(|cid| {
1284 name_bindings.define_value(DefStruct(local_def(cid)), sp,
1289 // Record the def ID and fields of this struct.
1290 let named_fields = struct_def.fields.iter().filter_map(|f| {
1292 NamedField(ident, _) => Some(ident.name),
1293 UnnamedField(_) => None
1296 self.structs.insert(local_def(item.id), named_fields);
1301 ItemImpl(_, None, ty, ref impl_items) => {
1302 // If this implements an anonymous trait, then add all the
1303 // methods within to a new module, if the type was defined
1304 // within this module.
1306 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1307 // should modify anonymous traits to only be implementable in
1308 // the same module that declared the type.
1310 // Create the module and add all methods.
1312 TyPath(ref path, _, _) if path.segments.len() == 1 => {
1313 let name = path.segments.last().unwrap().identifier;
1315 let parent_opt = parent.module().children.borrow()
1316 .find_copy(&name.name);
1317 let new_parent = match parent_opt {
1318 // It already exists
1319 Some(ref child) if child.get_module_if_available()
1321 child.get_module().kind.get() ==
1323 ModuleReducedGraphParent(child.get_module())
1325 // Create the module
1328 self.add_child(name,
1330 ForbidDuplicateModules,
1334 self.get_parent_link(parent.clone(), ident);
1335 let def_id = local_def(item.id);
1338 !name_bindings.defined_in_namespace(ns) ||
1339 name_bindings.defined_in_public_namespace(ns);
1341 name_bindings.define_module(parent_link,
1348 ModuleReducedGraphParent(
1349 name_bindings.get_module())
1353 // For each implementation item...
1354 for impl_item in impl_items.iter() {
1356 MethodImplItem(method) => {
1357 // Add the method to the module.
1358 let ident = method.pe_ident();
1359 let method_name_bindings =
1360 self.add_child(ident,
1362 ForbidDuplicateValues,
1364 let def = match method.pe_explicit_self()
1367 // Static methods become
1368 // `def_static_method`s.
1370 local_def(method.id),
1371 FromImpl(local_def(item.id)),
1372 method.pe_fn_style())
1375 // Non-static methods become
1377 DefMethod(local_def(method.id),
1383 method.pe_vis() == ast::Public;
1384 method_name_bindings.define_value(
1398 ItemImpl(_, Some(_), _, _) => parent,
1400 ItemTrait(_, _, _, ref methods) => {
1402 self.add_child(ident,
1404 ForbidDuplicateTypesAndModules,
1407 // Add all the methods within to a new module.
1408 let parent_link = self.get_parent_link(parent.clone(), ident);
1409 name_bindings.define_module(parent_link,
1410 Some(local_def(item.id)),
1413 item.vis == ast::Public,
1415 let module_parent = ModuleReducedGraphParent(name_bindings.
1418 let def_id = local_def(item.id);
1420 // Add the names of all the methods to the trait info.
1421 for method in methods.iter() {
1422 let ty_m = trait_item_to_ty_method(method);
1424 let ident = ty_m.ident;
1426 // Add it as a name in the trait module.
1427 let (def, static_flag) = match ty_m.explicit_self.node {
1429 // Static methods become `def_static_method`s.
1430 (DefStaticMethod(local_def(ty_m.id),
1431 FromTrait(local_def(item.id)),
1433 StaticMethodTraitItemKind)
1436 // Non-static methods become `def_method`s.
1437 (DefMethod(local_def(ty_m.id),
1438 Some(local_def(item.id))),
1439 NonstaticMethodTraitItemKind)
1443 let method_name_bindings =
1444 self.add_child(ident,
1445 module_parent.clone(),
1446 ForbidDuplicateValues,
1448 method_name_bindings.define_value(def, ty_m.span, true);
1452 .insert((ident.name, def_id), static_flag);
1455 name_bindings.define_type(DefTrait(def_id), sp, is_public);
1458 ItemMac(..) => parent
1462 // Constructs the reduced graph for one variant. Variants exist in the
1463 // type and/or value namespaces.
1464 fn build_reduced_graph_for_variant(&mut self,
1467 parent: ReducedGraphParent,
1469 let ident = variant.node.name;
1471 match variant.node.kind {
1472 TupleVariantKind(_) => {
1473 let child = self.add_child(ident, parent, ForbidDuplicateValues, variant.span);
1474 child.define_value(DefVariant(item_id,
1475 local_def(variant.node.id), false),
1476 variant.span, is_public);
1478 StructVariantKind(_) => {
1479 let child = self.add_child(ident, parent,
1480 ForbidDuplicateTypesAndValues,
1482 child.define_type(DefVariant(item_id,
1483 local_def(variant.node.id), true),
1484 variant.span, is_public);
1486 // Not adding fields for variants as they are not accessed with a self receiver
1487 self.structs.insert(local_def(variant.node.id), Vec::new());
1492 /// Constructs the reduced graph for one 'view item'. View items consist
1493 /// of imports and use directives.
1494 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1495 parent: ReducedGraphParent) {
1496 match view_item.node {
1497 ViewItemUse(ref view_path) => {
1498 // Extract and intern the module part of the path. For
1499 // globs and lists, the path is found directly in the AST;
1500 // for simple paths we have to munge the path a little.
1501 let module_path = match view_path.node {
1502 ViewPathSimple(_, ref full_path, _) => {
1505 .iter().map(|ident| ident.identifier)
1509 ViewPathGlob(ref module_ident_path, _) |
1510 ViewPathList(ref module_ident_path, _, _) => {
1511 module_ident_path.segments
1512 .iter().map(|ident| ident.identifier).collect()
1516 // Build up the import directives.
1517 let module_ = parent.module();
1518 let is_public = view_item.vis == ast::Public;
1523 attr.name() == token::get_ident(
1524 special_idents::prelude_import)
1527 match view_path.node {
1528 ViewPathSimple(binding, ref full_path, id) => {
1530 full_path.segments.last().unwrap().identifier;
1531 if token::get_ident(source_ident).get() == "mod" {
1532 self.resolve_error(view_path.span,
1533 "`mod` imports are only allowed within a { } list");
1536 let subclass = SingleImport(binding,
1538 self.build_import_directive(&*module_,
1546 ViewPathList(_, ref source_items, _) => {
1547 // Make sure there's at most one `mod` import in the list.
1548 let mod_spans = source_items.iter().filter_map(|item| match item.node {
1549 PathListMod { .. } => Some(item.span),
1551 }).collect::<Vec<Span>>();
1552 match mod_spans.as_slice() {
1553 [first, second, ..other] => {
1554 self.resolve_error(first,
1555 "`mod` import can only appear once in the list");
1556 self.session.span_note(second,
1557 "another `mod` import appears here");
1558 for &other_span in other.iter() {
1559 self.session.span_note(other_span,
1560 "another `mod` import appears here");
1566 for source_item in source_items.iter() {
1567 let (module_path, name) = match source_item.node {
1568 PathListIdent { name, .. } =>
1569 (module_path.clone(), name),
1570 PathListMod { .. } => {
1571 let name = match module_path.last() {
1572 Some(ident) => ident.clone(),
1574 self.resolve_error(source_item.span,
1575 "`mod` import can only appear in an import list \
1576 with a non-empty prefix");
1580 let module_path = module_path.as_slice().init();
1581 (Vec::from_slice(module_path), name)
1584 self.build_import_directive(
1587 SingleImport(name, name),
1589 source_item.node.id(),
1594 ViewPathGlob(_, id) => {
1595 self.build_import_directive(&*module_,
1606 ViewItemExternCrate(name, _, node_id) => {
1607 // n.b. we don't need to look at the path option here, because cstore already did
1608 for &crate_id in self.session.cstore
1609 .find_extern_mod_stmt_cnum(node_id).iter() {
1610 let def_id = DefId { krate: crate_id, node: 0 };
1611 self.external_exports.insert(def_id);
1613 ModuleParentLink(parent.module().downgrade(), name);
1614 let external_module = Rc::new(Module::new(parent_link,
1619 debug!("(build reduced graph for item) found extern `{}`",
1620 self.module_to_string(&*external_module));
1621 self.check_for_conflicts_between_external_crates(
1625 parent.module().external_module_children.borrow_mut()
1626 .insert(name.name, external_module.clone());
1627 self.build_reduced_graph_for_external_crate(external_module);
1633 /// Constructs the reduced graph for one foreign item.
1634 fn build_reduced_graph_for_foreign_item(&mut self,
1635 foreign_item: &ForeignItem,
1636 parent: ReducedGraphParent,
1637 f: |&mut Resolver|) {
1638 let name = foreign_item.ident;
1639 let is_public = foreign_item.vis == ast::Public;
1641 self.add_child(name, parent, ForbidDuplicateValues,
1644 match foreign_item.node {
1645 ForeignItemFn(_, ref generics) => {
1646 let def = DefFn(local_def(foreign_item.id), UnsafeFn);
1647 name_bindings.define_value(def, foreign_item.span, is_public);
1649 self.with_type_parameter_rib(
1650 HasTypeParameters(generics,
1656 ForeignItemStatic(_, m) => {
1657 let def = DefStatic(local_def(foreign_item.id), m);
1658 name_bindings.define_value(def, foreign_item.span, is_public);
1665 fn build_reduced_graph_for_block(&mut self,
1667 parent: ReducedGraphParent)
1668 -> ReducedGraphParent
1670 if self.block_needs_anonymous_module(block) {
1671 let block_id = block.id;
1673 debug!("(building reduced graph for block) creating a new \
1674 anonymous module for block {}",
1677 let parent_module = parent.module();
1678 let new_module = Rc::new(Module::new(
1679 BlockParentLink(parent_module.downgrade(), block_id),
1681 AnonymousModuleKind,
1684 parent_module.anonymous_children.borrow_mut()
1685 .insert(block_id, new_module.clone());
1686 ModuleReducedGraphParent(new_module)
1692 fn handle_external_def(&mut self,
1695 child_name_bindings: &NameBindings,
1698 new_parent: ReducedGraphParent) {
1699 debug!("(building reduced graph for \
1700 external crate) building external def, priv {:?}",
1702 let is_public = vis == ast::Public;
1703 let is_exported = is_public && match new_parent {
1704 ModuleReducedGraphParent(ref module) => {
1705 match module.def_id.get() {
1707 Some(did) => self.external_exports.contains(&did)
1712 self.external_exports.insert(def.def_id());
1715 let kind = match def {
1716 DefStruct(..) | DefTy(..) => ImplModuleKind,
1717 _ => NormalModuleKind
1721 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1723 let type_def = child_name_bindings.type_def.borrow().clone();
1725 Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1726 debug!("(building reduced graph for external crate) \
1727 already created module");
1728 module_def.def_id.set(Some(def_id));
1731 debug!("(building reduced graph for \
1732 external crate) building module \
1734 let parent_link = self.get_parent_link(new_parent.clone(), ident);
1736 child_name_bindings.define_module(parent_link,
1749 DefMod(_) | DefForeignMod(_) => {}
1750 DefVariant(enum_did, variant_id, is_struct) => {
1751 debug!("(building reduced graph for external crate) building \
1754 // If this variant is public, then it was publicly reexported,
1755 // otherwise we need to inherit the visibility of the enum
1757 let is_exported = is_public ||
1758 self.external_exports.contains(&enum_did);
1760 child_name_bindings.define_type(def, DUMMY_SP, is_exported);
1761 // Not adding fields for variants as they are not accessed with a self receiver
1762 self.structs.insert(variant_id, Vec::new());
1764 child_name_bindings.define_value(def, DUMMY_SP, is_exported);
1767 DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
1768 debug!("(building reduced graph for external \
1769 crate) building value (fn/static) {}", final_ident);
1770 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1772 DefTrait(def_id) => {
1773 debug!("(building reduced graph for external \
1774 crate) building type {}", final_ident);
1776 // If this is a trait, add all the trait item names to the trait
1779 let trait_item_def_ids =
1780 csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
1781 for trait_item_def_id in trait_item_def_ids.iter() {
1782 let (trait_item_name, trait_item_kind) =
1783 csearch::get_trait_item_name_and_kind(
1784 &self.session.cstore,
1785 trait_item_def_id.def_id());
1787 debug!("(building reduced graph for external crate) ... \
1788 adding trait item '{}'",
1789 token::get_ident(trait_item_name));
1793 .insert((trait_item_name.name, def_id),
1797 self.external_exports
1798 .insert(trait_item_def_id.def_id());
1802 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1804 // Define a module if necessary.
1805 let parent_link = self.get_parent_link(new_parent, ident);
1806 child_name_bindings.set_module_kind(parent_link,
1814 debug!("(building reduced graph for external \
1815 crate) building type {}", final_ident);
1817 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1819 DefStruct(def_id) => {
1820 debug!("(building reduced graph for external \
1821 crate) building type and value for {}",
1823 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1824 let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
1826 }).collect::<Vec<_>>();
1828 if fields.len() == 0 {
1829 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1832 // Record the def ID and fields of this struct.
1833 self.structs.insert(def_id, fields);
1836 debug!("(building reduced graph for external crate) \
1837 ignoring {:?}", def);
1838 // Ignored; handled elsewhere.
1840 DefArg(..) | DefLocal(..) | DefPrimTy(..) |
1841 DefTyParam(..) | DefBinding(..) |
1842 DefUse(..) | DefUpvar(..) | DefRegion(..) |
1843 DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
1844 fail!("didn't expect `{:?}`", def);
1849 /// Builds the reduced graph for a single item in an external crate.
1850 fn build_reduced_graph_for_external_crate_def(&mut self,
1854 visibility: Visibility) {
1857 // Add the new child item, if necessary.
1859 DefForeignMod(def_id) => {
1860 // Foreign modules have no names. Recur and populate
1862 csearch::each_child_of_item(&self.session.cstore,
1867 self.build_reduced_graph_for_external_crate_def(
1875 let child_name_bindings =
1876 self.add_child(ident,
1877 ModuleReducedGraphParent(root.clone()),
1878 OverwriteDuplicates,
1881 self.handle_external_def(def,
1883 &*child_name_bindings,
1884 token::get_ident(ident).get(),
1886 ModuleReducedGraphParent(root));
1891 // We only process static methods of impls here.
1892 match csearch::get_type_name_if_impl(&self.session.cstore, def) {
1894 Some(final_ident) => {
1895 let static_methods_opt =
1896 csearch::get_static_methods_if_impl(&self.session.cstore, def);
1897 match static_methods_opt {
1898 Some(ref static_methods) if
1899 static_methods.len() >= 1 => {
1900 debug!("(building reduced graph for \
1901 external crate) processing \
1902 static methods for type name {}",
1903 token::get_ident(final_ident));
1905 let child_name_bindings =
1908 ModuleReducedGraphParent(root.clone()),
1909 OverwriteDuplicates,
1912 // Process the static methods. First,
1913 // create the module.
1915 let type_def = child_name_bindings.type_def.borrow().clone();
1918 module_def: Some(module_def),
1921 // We already have a module. This
1923 type_module = module_def;
1925 // Mark it as an impl module if
1927 type_module.kind.set(ImplModuleKind);
1931 self.get_parent_link(ModuleReducedGraphParent(root),
1933 child_name_bindings.define_module(
1941 child_name_bindings.
1946 // Add each static method to the module.
1948 ModuleReducedGraphParent(type_module);
1949 for static_method_info in
1950 static_methods.iter() {
1951 let ident = static_method_info.ident;
1952 debug!("(building reduced graph for \
1953 external crate) creating \
1954 static method '{}'",
1955 token::get_ident(ident));
1957 let method_name_bindings =
1958 self.add_child(ident,
1960 OverwriteDuplicates,
1963 static_method_info.def_id,
1964 static_method_info.fn_style);
1966 method_name_bindings.define_value(
1968 visibility == ast::Public);
1972 // Otherwise, do nothing.
1973 Some(_) | None => {}
1979 debug!("(building reduced graph for external crate) \
1985 /// Builds the reduced graph rooted at the given external module.
1986 fn populate_external_module(&mut self, module: Rc<Module>) {
1987 debug!("(populating external module) attempting to populate {}",
1988 self.module_to_string(&*module));
1990 let def_id = match module.def_id.get() {
1992 debug!("(populating external module) ... no def ID!");
1995 Some(def_id) => def_id,
1998 csearch::each_child_of_item(&self.session.cstore,
2000 |def_like, child_ident, visibility| {
2001 debug!("(populating external module) ... found ident: {}",
2002 token::get_ident(child_ident));
2003 self.build_reduced_graph_for_external_crate_def(module.clone(),
2008 module.populated.set(true)
2011 /// Ensures that the reduced graph rooted at the given external module
2012 /// is built, building it if it is not.
2013 fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
2014 if !module.populated.get() {
2015 self.populate_external_module(module.clone())
2017 assert!(module.populated.get())
2020 /// Builds the reduced graph rooted at the 'use' directive for an external
2022 fn build_reduced_graph_for_external_crate(&mut self, root: Rc<Module>) {
2023 csearch::each_top_level_item_of_crate(&self.session.cstore,
2028 |def_like, ident, visibility| {
2029 self.build_reduced_graph_for_external_crate_def(root.clone(),
2036 /// Creates and adds an import directive to the given module.
2037 fn build_import_directive(&mut self,
2039 module_path: Vec<Ident> ,
2040 subclass: ImportDirectiveSubclass,
2045 module_.imports.borrow_mut().push(ImportDirective::new(module_path,
2051 self.unresolved_imports += 1;
2052 // Bump the reference count on the name. Or, if this is a glob, set
2053 // the appropriate flag.
2056 SingleImport(target, _) => {
2057 debug!("(building import directive) building import \
2059 self.idents_to_string(module_.imports.borrow().last().unwrap()
2060 .module_path.as_slice()),
2061 token::get_ident(target));
2063 let mut import_resolutions = module_.import_resolutions
2065 match import_resolutions.find_mut(&target.name) {
2066 Some(resolution) => {
2067 debug!("(building import directive) bumping \
2069 resolution.outstanding_references += 1;
2071 // the source of this name is different now
2072 resolution.type_id = id;
2073 resolution.value_id = id;
2074 resolution.is_public = is_public;
2079 debug!("(building import directive) creating new");
2080 let mut resolution = ImportResolution::new(id, is_public);
2081 resolution.outstanding_references = 1;
2082 import_resolutions.insert(target.name, resolution);
2085 // Set the glob flag. This tells us that we don't know the
2086 // module's exports ahead of time.
2088 module_.glob_count.set(module_.glob_count.get() + 1);
2093 // Import resolution
2095 // This is a fixed-point algorithm. We resolve imports until our efforts
2096 // are stymied by an unresolved import; then we bail out of the current
2097 // module and continue. We terminate successfully once no more imports
2098 // remain or unsuccessfully when no forward progress in resolving imports
2101 /// Resolves all imports for the crate. This method performs the fixed-
2102 /// point iteration.
2103 fn resolve_imports(&mut self) {
2105 let mut prev_unresolved_imports = 0;
2107 debug!("(resolving imports) iteration {}, {} imports left",
2108 i, self.unresolved_imports);
2110 let module_root = self.graph_root.get_module();
2111 self.resolve_imports_for_module_subtree(module_root.clone());
2113 if self.unresolved_imports == 0 {
2114 debug!("(resolving imports) success");
2118 if self.unresolved_imports == prev_unresolved_imports {
2119 self.report_unresolved_imports(module_root);
2124 prev_unresolved_imports = self.unresolved_imports;
2128 /// Attempts to resolve imports for the given module and all of its
2130 fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
2131 debug!("(resolving imports for module subtree) resolving {}",
2132 self.module_to_string(&*module_));
2133 let orig_module = replace(&mut self.current_module, module_.clone());
2134 self.resolve_imports_for_module(module_.clone());
2135 self.current_module = orig_module;
2137 self.populate_module_if_necessary(&module_);
2138 for (_, child_node) in module_.children.borrow().iter() {
2139 match child_node.get_module_if_available() {
2143 Some(child_module) => {
2144 self.resolve_imports_for_module_subtree(child_module);
2149 for (_, child_module) in module_.anonymous_children.borrow().iter() {
2150 self.resolve_imports_for_module_subtree(child_module.clone());
2154 /// Attempts to resolve imports for the given module only.
2155 fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
2156 if module.all_imports_resolved() {
2157 debug!("(resolving imports for module) all imports resolved for \
2159 self.module_to_string(&*module));
2163 let imports = module.imports.borrow();
2164 let import_count = imports.len();
2165 while module.resolved_import_count.get() < import_count {
2166 let import_index = module.resolved_import_count.get();
2167 let import_directive = imports.get(import_index);
2168 match self.resolve_import_for_module(module.clone(),
2171 let (span, help) = match err {
2172 Some((span, msg)) => (span, format!(". {}", msg)),
2173 None => (import_directive.span, String::new())
2175 let msg = format!("unresolved import `{}`{}",
2176 self.import_path_to_string(
2177 import_directive.module_path
2179 import_directive.subclass),
2181 self.resolve_error(span, msg.as_slice());
2183 Indeterminate => break, // Bail out. We'll come around next time.
2184 Success(()) => () // Good. Continue.
2187 module.resolved_import_count
2188 .set(module.resolved_import_count.get() + 1);
2192 fn idents_to_string(&self, idents: &[Ident]) -> String {
2193 let mut first = true;
2194 let mut result = String::new();
2195 for ident in idents.iter() {
2199 result.push_str("::")
2201 result.push_str(token::get_ident(*ident).get());
2206 fn path_idents_to_string(&self, path: &Path) -> String {
2207 let identifiers: Vec<ast::Ident> = path.segments
2209 .map(|seg| seg.identifier)
2211 self.idents_to_string(identifiers.as_slice())
2214 fn import_directive_subclass_to_string(&mut self,
2215 subclass: ImportDirectiveSubclass)
2218 SingleImport(_, source) => {
2219 token::get_ident(source).get().to_string()
2221 GlobImport => "*".to_string()
2225 fn import_path_to_string(&mut self,
2227 subclass: ImportDirectiveSubclass)
2229 if idents.is_empty() {
2230 self.import_directive_subclass_to_string(subclass)
2233 self.idents_to_string(idents),
2234 self.import_directive_subclass_to_string(
2235 subclass))).to_string()
2239 /// Attempts to resolve the given import. The return value indicates
2240 /// failure if we're certain the name does not exist, indeterminate if we
2241 /// don't know whether the name exists at the moment due to other
2242 /// currently-unresolved imports, or success if we know the name exists.
2243 /// If successful, the resolved bindings are written into the module.
2244 fn resolve_import_for_module(&mut self,
2245 module_: Rc<Module>,
2246 import_directive: &ImportDirective)
2247 -> ResolveResult<()> {
2248 let mut resolution_result = Failed(None);
2249 let module_path = &import_directive.module_path;
2251 debug!("(resolving import for module) resolving import `{}::...` in \
2253 self.idents_to_string(module_path.as_slice()),
2254 self.module_to_string(&*module_));
2256 // First, resolve the module path for the directive, if necessary.
2257 let container = if module_path.len() == 0 {
2258 // Use the crate root.
2259 Some((self.graph_root.get_module(), LastMod(AllPublic)))
2261 match self.resolve_module_path(module_.clone(),
2262 module_path.as_slice(),
2263 DontUseLexicalScope,
2264 import_directive.span,
2267 resolution_result = Failed(err);
2271 resolution_result = Indeterminate;
2274 Success(container) => Some(container),
2280 Some((containing_module, lp)) => {
2281 // We found the module that the target is contained
2282 // within. Attempt to resolve the import within it.
2284 match import_directive.subclass {
2285 SingleImport(target, source) => {
2287 self.resolve_single_import(&*module_,
2296 self.resolve_glob_import(&*module_,
2305 // Decrement the count of unresolved imports.
2306 match resolution_result {
2308 assert!(self.unresolved_imports >= 1);
2309 self.unresolved_imports -= 1;
2312 // Nothing to do here; just return the error.
2316 // Decrement the count of unresolved globs if necessary. But only if
2317 // the resolution result is indeterminate -- otherwise we'll stop
2318 // processing imports here. (See the loop in
2319 // resolve_imports_for_module.)
2321 if !resolution_result.indeterminate() {
2322 match import_directive.subclass {
2324 assert!(module_.glob_count.get() >= 1);
2325 module_.glob_count.set(module_.glob_count.get() - 1);
2327 SingleImport(..) => {
2333 return resolution_result;
2336 fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
2338 type_def: RefCell::new(Some(TypeNsDef {
2340 module_def: Some(module),
2344 value_def: RefCell::new(None),
2348 fn resolve_single_import(&mut self,
2350 containing_module: Rc<Module>,
2353 directive: &ImportDirective,
2355 -> ResolveResult<()> {
2356 debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2357 `{}` id {}, last private {:?}",
2358 token::get_ident(target),
2359 self.module_to_string(&*containing_module),
2360 token::get_ident(source),
2361 self.module_to_string(module_),
2367 LastImport {..} => {
2369 .span_bug(directive.span,
2370 "not expecting Import here, must be LastMod")
2374 // We need to resolve both namespaces for this to succeed.
2377 let mut value_result = UnknownResult;
2378 let mut type_result = UnknownResult;
2380 // Search for direct children of the containing module.
2381 self.populate_module_if_necessary(&containing_module);
2383 match containing_module.children.borrow().find(&source.name) {
2387 Some(ref child_name_bindings) => {
2388 if child_name_bindings.defined_in_namespace(ValueNS) {
2389 debug!("(resolving single import) found value binding");
2390 value_result = BoundResult(containing_module.clone(),
2391 (*child_name_bindings).clone());
2393 if child_name_bindings.defined_in_namespace(TypeNS) {
2394 debug!("(resolving single import) found type binding");
2395 type_result = BoundResult(containing_module.clone(),
2396 (*child_name_bindings).clone());
2401 // Unless we managed to find a result in both namespaces (unlikely),
2402 // search imports as well.
2403 let mut value_used_reexport = false;
2404 let mut type_used_reexport = false;
2405 match (value_result.clone(), type_result.clone()) {
2406 (BoundResult(..), BoundResult(..)) => {} // Continue.
2408 // If there is an unresolved glob at this point in the
2409 // containing module, bail out. We don't know enough to be
2410 // able to resolve this import.
2412 if containing_module.glob_count.get() > 0 {
2413 debug!("(resolving single import) unresolved glob; \
2415 return Indeterminate;
2418 // Now search the exported imports within the containing module.
2419 match containing_module.import_resolutions.borrow().find(&source.name) {
2421 debug!("(resolving single import) no import");
2422 // The containing module definitely doesn't have an
2423 // exported import with the name in question. We can
2424 // therefore accurately report that the names are
2427 if value_result.is_unknown() {
2428 value_result = UnboundResult;
2430 if type_result.is_unknown() {
2431 type_result = UnboundResult;
2434 Some(import_resolution)
2435 if import_resolution.outstanding_references == 0 => {
2437 fn get_binding(this: &mut Resolver,
2438 import_resolution: &ImportResolution,
2439 namespace: Namespace)
2440 -> NamespaceResult {
2442 // Import resolutions must be declared with "pub"
2443 // in order to be exported.
2444 if !import_resolution.is_public {
2445 return UnboundResult;
2448 match import_resolution.
2449 target_for_namespace(namespace) {
2451 return UnboundResult;
2458 debug!("(resolving single import) found \
2459 import in ns {:?}", namespace);
2460 let id = import_resolution.id(namespace);
2461 this.used_imports.insert((id, namespace));
2462 return BoundResult(target_module, bindings);
2467 // The name is an import which has been fully
2468 // resolved. We can, therefore, just follow it.
2469 if value_result.is_unknown() {
2470 value_result = get_binding(self, import_resolution,
2472 value_used_reexport = import_resolution.is_public;
2474 if type_result.is_unknown() {
2475 type_result = get_binding(self, import_resolution,
2477 type_used_reexport = import_resolution.is_public;
2482 // The import is unresolved. Bail out.
2483 debug!("(resolving single import) unresolved import; \
2485 return Indeterminate;
2491 // If we didn't find a result in the type namespace, search the
2492 // external modules.
2493 let mut value_used_public = false;
2494 let mut type_used_public = false;
2496 BoundResult(..) => {}
2498 match containing_module.external_module_children.borrow_mut()
2499 .find_copy(&source.name) {
2500 None => {} // Continue.
2502 debug!("(resolving single import) found external \
2505 Rc::new(Resolver::create_name_bindings_from_module(
2507 type_result = BoundResult(containing_module.clone(),
2509 type_used_public = true;
2515 // We've successfully resolved the import. Write the results in.
2516 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2517 let import_resolution = import_resolutions.get_mut(&target.name);
2519 match value_result {
2520 BoundResult(ref target_module, ref name_bindings) => {
2521 debug!("(resolving single import) found value target");
2522 self.check_for_conflicting_import(
2523 &import_resolution.value_target,
2528 import_resolution.value_target =
2529 Some(Target::new(target_module.clone(),
2530 name_bindings.clone(),
2531 directive.shadowable));
2532 import_resolution.value_id = directive.id;
2533 import_resolution.is_public = directive.is_public;
2534 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2536 UnboundResult => { /* Continue. */ }
2538 fail!("value result should be known at this point");
2542 BoundResult(ref target_module, ref name_bindings) => {
2543 debug!("(resolving single import) found type target: {:?}",
2544 { name_bindings.type_def.borrow().clone().unwrap().type_def });
2545 self.check_for_conflicting_import(
2546 &import_resolution.type_target,
2551 import_resolution.type_target =
2552 Some(Target::new(target_module.clone(),
2553 name_bindings.clone(),
2554 directive.shadowable));
2555 import_resolution.type_id = directive.id;
2556 import_resolution.is_public = directive.is_public;
2557 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2559 UnboundResult => { /* Continue. */ }
2561 fail!("type result should be known at this point");
2565 self.check_for_conflicts_between_imports_and_items(
2571 if value_result.is_unbound() && type_result.is_unbound() {
2572 let msg = format!("There is no `{}` in `{}`",
2573 token::get_ident(source),
2574 self.module_to_string(&*containing_module));
2575 return Failed(Some((directive.span, msg)));
2577 let value_used_public = value_used_reexport || value_used_public;
2578 let type_used_public = type_used_reexport || type_used_public;
2580 assert!(import_resolution.outstanding_references >= 1);
2581 import_resolution.outstanding_references -= 1;
2583 // record what this import resolves to for later uses in documentation,
2584 // this may resolve to either a value or a type, but for documentation
2585 // purposes it's good enough to just favor one over the other.
2586 let value_private = match import_resolution.value_target {
2587 Some(ref target) => {
2588 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2589 self.def_map.borrow_mut().insert(directive.id, def);
2590 let did = def.def_id();
2591 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2593 // AllPublic here and below is a dummy value, it should never be used because
2594 // _exists is false.
2597 let type_private = match import_resolution.type_target {
2598 Some(ref target) => {
2599 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2600 self.def_map.borrow_mut().insert(directive.id, def);
2601 let did = def.def_id();
2602 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2607 self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2609 type_priv: type_private,
2612 debug!("(resolving single import) successfully resolved import");
2616 // Resolves a glob import. Note that this function cannot fail; it either
2617 // succeeds or bails out (as importing * from an empty module or a module
2618 // that exports nothing is valid).
2619 fn resolve_glob_import(&mut self,
2621 containing_module: Rc<Module>,
2622 import_directive: &ImportDirective,
2624 -> ResolveResult<()> {
2625 let id = import_directive.id;
2626 let is_public = import_directive.is_public;
2628 // This function works in a highly imperative manner; it eagerly adds
2629 // everything it can to the list of import resolutions of the module
2631 debug!("(resolving glob import) resolving glob import {}", id);
2633 // We must bail out if the node has unresolved imports of any kind
2634 // (including globs).
2635 if !(*containing_module).all_imports_resolved() {
2636 debug!("(resolving glob import) target module has unresolved \
2637 imports; bailing out");
2638 return Indeterminate;
2641 assert_eq!(containing_module.glob_count.get(), 0);
2643 // Add all resolved imports from the containing module.
2644 let import_resolutions = containing_module.import_resolutions
2646 for (ident, target_import_resolution) in import_resolutions.iter() {
2647 debug!("(resolving glob import) writing module resolution \
2649 target_import_resolution.type_target.is_none(),
2650 self.module_to_string(module_));
2652 if !target_import_resolution.is_public {
2653 debug!("(resolving glob import) nevermind, just kidding");
2657 // Here we merge two import resolutions.
2658 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2659 match import_resolutions.find_mut(ident) {
2660 Some(dest_import_resolution) => {
2661 // Merge the two import resolutions at a finer-grained
2664 match target_import_resolution.value_target {
2668 Some(ref value_target) => {
2669 dest_import_resolution.value_target =
2670 Some(value_target.clone());
2673 match target_import_resolution.type_target {
2677 Some(ref type_target) => {
2678 dest_import_resolution.type_target =
2679 Some(type_target.clone());
2682 dest_import_resolution.is_public = is_public;
2688 // Simple: just copy the old import resolution.
2689 let mut new_import_resolution = ImportResolution::new(id, is_public);
2690 new_import_resolution.value_target =
2691 target_import_resolution.value_target.clone();
2692 new_import_resolution.type_target =
2693 target_import_resolution.type_target.clone();
2695 import_resolutions.insert(*ident, new_import_resolution);
2698 // Add all children from the containing module.
2699 self.populate_module_if_necessary(&containing_module);
2701 for (&name, name_bindings) in containing_module.children
2703 self.merge_import_resolution(module_,
2704 containing_module.clone(),
2707 name_bindings.clone());
2711 // Add external module children from the containing module.
2712 for (&name, module) in containing_module.external_module_children
2715 Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
2716 self.merge_import_resolution(module_,
2717 containing_module.clone(),
2723 // Record the destination of this import
2724 match containing_module.def_id.get() {
2726 self.def_map.borrow_mut().insert(id, DefMod(did));
2727 self.last_private.insert(id, lp);
2732 debug!("(resolving glob import) successfully resolved import");
2736 fn merge_import_resolution(&mut self,
2738 containing_module: Rc<Module>,
2739 import_directive: &ImportDirective,
2741 name_bindings: Rc<NameBindings>) {
2742 let id = import_directive.id;
2743 let is_public = import_directive.is_public;
2745 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2746 let dest_import_resolution = import_resolutions.find_or_insert_with(name, |_| {
2747 // Create a new import resolution from this child.
2748 ImportResolution::new(id, is_public)
2751 debug!("(resolving glob import) writing resolution `{}` in `{}` \
2753 token::get_name(name).get().to_string(),
2754 self.module_to_string(&*containing_module),
2755 self.module_to_string(module_));
2757 // Merge the child item into the import resolution.
2758 if name_bindings.defined_in_public_namespace(ValueNS) {
2759 debug!("(resolving glob import) ... for value target");
2760 dest_import_resolution.value_target =
2761 Some(Target::new(containing_module.clone(),
2762 name_bindings.clone(),
2763 import_directive.shadowable));
2764 dest_import_resolution.value_id = id;
2766 if name_bindings.defined_in_public_namespace(TypeNS) {
2767 debug!("(resolving glob import) ... for type target");
2768 dest_import_resolution.type_target =
2769 Some(Target::new(containing_module,
2770 name_bindings.clone(),
2771 import_directive.shadowable));
2772 dest_import_resolution.type_id = id;
2774 dest_import_resolution.is_public = is_public;
2776 self.check_for_conflicts_between_imports_and_items(
2778 dest_import_resolution,
2779 import_directive.span,
2783 /// Checks that imported names and items don't have the same name.
2784 fn check_for_conflicting_import(&mut self,
2785 target: &Option<Target>,
2788 namespace: Namespace) {
2789 if self.session.features.import_shadowing.get() {
2794 Some(ref target) if !target.shadowable => {
2795 let msg = format!("a {} named `{}` has already been imported \
2801 token::get_name(name).get());
2802 self.session.span_err(import_span, msg.as_slice());
2804 Some(_) | None => {}
2808 /// Checks that imported names and items don't have the same name.
2809 fn check_for_conflicts_between_imports_and_items(&mut self,
2812 &mut ImportResolution,
2815 if self.session.features.import_shadowing.get() {
2819 // First, check for conflicts between imports and `extern crate`s.
2820 if module.external_module_children
2822 .contains_key(&name) {
2823 match import_resolution.type_target {
2824 Some(ref target) if !target.shadowable => {
2825 let msg = format!("import `{}` conflicts with imported \
2826 crate in this module",
2827 token::get_name(name).get());
2828 self.session.span_err(import_span, msg.as_slice());
2830 Some(_) | None => {}
2834 // Check for item conflicts.
2835 let children = module.children.borrow();
2836 let name_bindings = match children.find(&name) {
2838 // There can't be any conflicts.
2841 Some(ref name_bindings) => (*name_bindings).clone(),
2844 match import_resolution.value_target {
2845 Some(ref target) if !target.shadowable => {
2846 match *name_bindings.value_def.borrow() {
2848 Some(ref value) => {
2849 let msg = format!("import `{}` conflicts with value \
2851 token::get_name(name).get());
2852 self.session.span_err(import_span, msg.as_slice());
2853 match value.value_span {
2858 "note conflicting value here");
2864 Some(_) | None => {}
2867 match import_resolution.type_target {
2868 Some(ref target) if !target.shadowable => {
2869 match *name_bindings.type_def.borrow() {
2872 let msg = format!("import `{}` conflicts with type in \
2874 token::get_name(name).get());
2875 self.session.span_err(import_span, msg.as_slice());
2876 match ty.type_span {
2881 "note conflicting type here")
2887 Some(_) | None => {}
2891 /// Checks that the names of external crates don't collide with other
2892 /// external crates.
2893 fn check_for_conflicts_between_external_crates(&self,
2897 if self.session.features.import_shadowing.get() {
2901 if module.external_module_children.borrow().contains_key(&name) {
2904 format!("an external crate named `{}` has already \
2905 been imported into this module",
2906 token::get_name(name).get()).as_slice());
2910 /// Checks that the names of items don't collide with external crates.
2911 fn check_for_conflicts_between_external_crates_and_items(&self,
2915 if self.session.features.import_shadowing.get() {
2919 if module.external_module_children.borrow().contains_key(&name) {
2922 format!("the name `{}` conflicts with an external \
2923 crate that has been imported into this \
2925 token::get_name(name).get()).as_slice());
2929 /// Resolves the given module path from the given root `module_`.
2930 fn resolve_module_path_from_root(&mut self,
2931 module_: Rc<Module>,
2932 module_path: &[Ident],
2935 name_search_type: NameSearchType,
2937 -> ResolveResult<(Rc<Module>, LastPrivate)> {
2938 fn search_parent_externals(needle: Name, module: &Rc<Module>)
2939 -> Option<Rc<Module>> {
2940 module.external_module_children.borrow()
2942 .map(|_| module.clone())
2944 match module.parent_link.clone() {
2945 ModuleParentLink(parent, _) => {
2946 search_parent_externals(needle,
2947 &parent.upgrade().unwrap())
2954 let mut search_module = module_;
2955 let mut index = index;
2956 let module_path_len = module_path.len();
2957 let mut closest_private = lp;
2959 // Resolve the module part of the path. This does not involve looking
2960 // upward though scope chains; we simply resolve names directly in
2961 // modules as we go.
2962 while index < module_path_len {
2963 let name = module_path[index];
2964 match self.resolve_name_in_module(search_module.clone(),
2970 let segment_name = token::get_ident(name);
2971 let module_name = self.module_to_string(&*search_module);
2972 let mut span = span;
2973 let msg = if "???" == module_name.as_slice() {
2974 span.hi = span.lo + Pos::from_uint(segment_name.get().len());
2976 match search_parent_externals(name.name,
2977 &self.current_module) {
2979 let path_str = self.idents_to_string(module_path);
2980 let target_mod_str = self.module_to_string(&*module);
2981 let current_mod_str =
2982 self.module_to_string(&*self.current_module);
2984 let prefix = if target_mod_str == current_mod_str {
2985 "self::".to_string()
2987 format!("{}::", target_mod_str)
2990 format!("Did you mean `{}{}`?", prefix, path_str)
2992 None => format!("Maybe a missing `extern crate {}`?",
2996 format!("Could not find `{}` in `{}`.",
3001 return Failed(Some((span, msg)));
3003 Failed(err) => return Failed(err),
3005 debug!("(resolving module path for import) module \
3006 resolution is indeterminate: {}",
3007 token::get_ident(name));
3008 return Indeterminate;
3010 Success((target, used_proxy)) => {
3011 // Check to see whether there are type bindings, and, if
3012 // so, whether there is a module within.
3013 match *target.bindings.type_def.borrow() {
3014 Some(ref type_def) => {
3015 match type_def.module_def {
3017 let msg = format!("Not a module `{}`",
3018 token::get_ident(name));
3020 return Failed(Some((span, msg)));
3022 Some(ref module_def) => {
3023 // If we're doing the search for an
3024 // import, do not allow traits and impls
3026 match (name_search_type,
3027 module_def.kind.get()) {
3028 (ImportSearch, TraitModuleKind) |
3029 (ImportSearch, ImplModuleKind) => {
3031 "Cannot import from a trait or \
3032 type implementation".to_string();
3033 return Failed(Some((span, msg)));
3036 search_module = module_def.clone();
3038 // Keep track of the closest
3039 // private module used when
3040 // resolving this import chain.
3042 !search_module.is_public {
3043 match search_module.def_id
3047 LastMod(DependsOn(did));
3058 // There are no type bindings at all.
3059 let msg = format!("Not a module `{}`",
3060 token::get_ident(name));
3061 return Failed(Some((span, msg)));
3070 return Success((search_module, closest_private));
3073 /// Attempts to resolve the module part of an import directive or path
3074 /// rooted at the given module.
3076 /// On success, returns the resolved module, and the closest *private*
3077 /// module found to the destination when resolving this path.
3078 fn resolve_module_path(&mut self,
3079 module_: Rc<Module>,
3080 module_path: &[Ident],
3081 use_lexical_scope: UseLexicalScopeFlag,
3083 name_search_type: NameSearchType)
3084 -> ResolveResult<(Rc<Module>, LastPrivate)> {
3085 let module_path_len = module_path.len();
3086 assert!(module_path_len > 0);
3088 debug!("(resolving module path for import) processing `{}` rooted at \
3090 self.idents_to_string(module_path),
3091 self.module_to_string(&*module_));
3093 // Resolve the module prefix, if any.
3094 let module_prefix_result = self.resolve_module_prefix(module_.clone(),
3100 match module_prefix_result {
3102 let mpath = self.idents_to_string(module_path);
3103 let mpath = mpath.as_slice();
3104 match mpath.rfind(':') {
3106 let msg = format!("Could not find `{}` in `{}`",
3107 // idx +- 1 to account for the
3108 // colons on either side
3109 mpath.slice_from(idx + 1),
3110 mpath.slice_to(idx - 1));
3111 return Failed(Some((span, msg)));
3113 None => return Failed(None),
3116 Failed(err) => return Failed(err),
3118 debug!("(resolving module path for import) indeterminate; \
3120 return Indeterminate;
3122 Success(NoPrefixFound) => {
3123 // There was no prefix, so we're considering the first element
3124 // of the path. How we handle this depends on whether we were
3125 // instructed to use lexical scope or not.
3126 match use_lexical_scope {
3127 DontUseLexicalScope => {
3128 // This is a crate-relative path. We will start the
3129 // resolution process at index zero.
3130 search_module = self.graph_root.get_module();
3132 last_private = LastMod(AllPublic);
3134 UseLexicalScope => {
3135 // This is not a crate-relative path. We resolve the
3136 // first component of the path in the current lexical
3137 // scope and then proceed to resolve below that.
3138 match self.resolve_module_in_lexical_scope(
3141 Failed(err) => return Failed(err),
3143 debug!("(resolving module path for import) \
3144 indeterminate; bailing");
3145 return Indeterminate;
3147 Success(containing_module) => {
3148 search_module = containing_module;
3150 last_private = LastMod(AllPublic);
3156 Success(PrefixFound(ref containing_module, index)) => {
3157 search_module = containing_module.clone();
3158 start_index = index;
3159 last_private = LastMod(DependsOn(containing_module.def_id
3165 self.resolve_module_path_from_root(search_module,
3173 /// Invariant: This must only be called during main resolution, not during
3174 /// import resolution.
3175 fn resolve_item_in_lexical_scope(&mut self,
3176 module_: Rc<Module>,
3178 namespace: Namespace)
3179 -> ResolveResult<(Target, bool)> {
3180 debug!("(resolving item in lexical scope) resolving `{}` in \
3181 namespace {:?} in `{}`",
3182 token::get_ident(name),
3184 self.module_to_string(&*module_));
3186 // The current module node is handled specially. First, check for
3187 // its immediate children.
3188 self.populate_module_if_necessary(&module_);
3190 match module_.children.borrow().find(&name.name) {
3192 if name_bindings.defined_in_namespace(namespace) => {
3193 debug!("top name bindings succeeded");
3194 return Success((Target::new(module_.clone(),
3195 name_bindings.clone(),
3199 Some(_) | None => { /* Not found; continue. */ }
3202 // Now check for its import directives. We don't have to have resolved
3203 // all its imports in the usual way; this is because chains of
3204 // adjacent import statements are processed as though they mutated the
3206 match module_.import_resolutions.borrow().find(&name.name) {
3208 // Not found; continue.
3210 Some(import_resolution) => {
3211 match (*import_resolution).target_for_namespace(namespace) {
3213 // Not found; continue.
3214 debug!("(resolving item in lexical scope) found \
3215 import resolution, but not in namespace {:?}",
3219 debug!("(resolving item in lexical scope) using \
3220 import resolution");
3221 self.used_imports.insert((import_resolution.id(namespace), namespace));
3222 return Success((target, false));
3228 // Search for external modules.
3229 if namespace == TypeNS {
3230 match module_.external_module_children.borrow().find_copy(&name.name) {
3234 Rc::new(Resolver::create_name_bindings_from_module(module));
3235 debug!("lower name bindings succeeded");
3236 return Success((Target::new(module_,
3244 // Finally, proceed up the scope chain looking for parent modules.
3245 let mut search_module = module_;
3247 // Go to the next parent.
3248 match search_module.parent_link.clone() {
3250 // No more parents. This module was unresolved.
3251 debug!("(resolving item in lexical scope) unresolved \
3253 return Failed(None);
3255 ModuleParentLink(parent_module_node, _) => {
3256 match search_module.kind.get() {
3257 NormalModuleKind => {
3258 // We stop the search here.
3259 debug!("(resolving item in lexical \
3260 scope) unresolved module: not \
3261 searching through module \
3263 return Failed(None);
3268 AnonymousModuleKind => {
3269 search_module = parent_module_node.upgrade().unwrap();
3273 BlockParentLink(ref parent_module_node, _) => {
3274 search_module = parent_module_node.upgrade().unwrap();
3278 // Resolve the name in the parent module.
3279 match self.resolve_name_in_module(search_module.clone(),
3284 Failed(Some((span, msg))) =>
3285 self.resolve_error(span, format!("failed to resolve. {}",
3287 Failed(None) => (), // Continue up the search chain.
3289 // We couldn't see through the higher scope because of an
3290 // unresolved import higher up. Bail.
3292 debug!("(resolving item in lexical scope) indeterminate \
3293 higher scope; bailing");
3294 return Indeterminate;
3296 Success((target, used_reexport)) => {
3297 // We found the module.
3298 debug!("(resolving item in lexical scope) found name \
3300 return Success((target, used_reexport));
3306 /// Resolves a module name in the current lexical scope.
3307 fn resolve_module_in_lexical_scope(&mut self,
3308 module_: Rc<Module>,
3310 -> ResolveResult<Rc<Module>> {
3311 // If this module is an anonymous module, resolve the item in the
3312 // lexical scope. Otherwise, resolve the item from the crate root.
3313 let resolve_result = self.resolve_item_in_lexical_scope(
3314 module_, name, TypeNS);
3315 match resolve_result {
3316 Success((target, _)) => {
3317 let bindings = &*target.bindings;
3318 match *bindings.type_def.borrow() {
3319 Some(ref type_def) => {
3320 match type_def.module_def {
3322 debug!("!!! (resolving module in lexical \
3323 scope) module wasn't actually a \
3325 return Failed(None);
3327 Some(ref module_def) => {
3328 return Success(module_def.clone());
3333 debug!("!!! (resolving module in lexical scope) module
3334 wasn't actually a module!");
3335 return Failed(None);
3340 debug!("(resolving module in lexical scope) indeterminate; \
3342 return Indeterminate;
3345 debug!("(resolving module in lexical scope) failed to resolve");
3351 /// Returns the nearest normal module parent of the given module.
3352 fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
3353 -> Option<Rc<Module>> {
3354 let mut module_ = module_;
3356 match module_.parent_link.clone() {
3357 NoParentLink => return None,
3358 ModuleParentLink(new_module, _) |
3359 BlockParentLink(new_module, _) => {
3360 let new_module = new_module.upgrade().unwrap();
3361 match new_module.kind.get() {
3362 NormalModuleKind => return Some(new_module),
3366 AnonymousModuleKind => module_ = new_module,
3373 /// Returns the nearest normal module parent of the given module, or the
3374 /// module itself if it is a normal module.
3375 fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
3377 match module_.kind.get() {
3378 NormalModuleKind => return module_,
3382 AnonymousModuleKind => {
3383 match self.get_nearest_normal_module_parent(module_.clone()) {
3385 Some(new_module) => new_module
3391 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3392 /// (b) some chain of `super::`.
3393 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3394 fn resolve_module_prefix(&mut self,
3395 module_: Rc<Module>,
3396 module_path: &[Ident])
3397 -> ResolveResult<ModulePrefixResult> {
3398 // Start at the current module if we see `self` or `super`, or at the
3399 // top of the crate otherwise.
3400 let mut containing_module;
3402 let first_module_path_string = token::get_ident(module_path[0]);
3403 if "self" == first_module_path_string.get() {
3405 self.get_nearest_normal_module_parent_or_self(module_);
3407 } else if "super" == first_module_path_string.get() {
3409 self.get_nearest_normal_module_parent_or_self(module_);
3410 i = 0; // We'll handle `super` below.
3412 return Success(NoPrefixFound);
3415 // Now loop through all the `super`s we find.
3416 while i < module_path.len() {
3417 let string = token::get_ident(module_path[i]);
3418 if "super" != string.get() {
3421 debug!("(resolving module prefix) resolving `super` at {}",
3422 self.module_to_string(&*containing_module));
3423 match self.get_nearest_normal_module_parent(containing_module) {
3424 None => return Failed(None),
3425 Some(new_module) => {
3426 containing_module = new_module;
3432 debug!("(resolving module prefix) finished resolving prefix at {}",
3433 self.module_to_string(&*containing_module));
3435 return Success(PrefixFound(containing_module, i));
3438 /// Attempts to resolve the supplied name in the given module for the
3439 /// given namespace. If successful, returns the target corresponding to
3442 /// The boolean returned on success is an indicator of whether this lookup
3443 /// passed through a public re-export proxy.
3444 fn resolve_name_in_module(&mut self,
3445 module_: Rc<Module>,
3447 namespace: Namespace,
3448 name_search_type: NameSearchType,
3449 allow_private_imports: bool)
3450 -> ResolveResult<(Target, bool)> {
3451 debug!("(resolving name in module) resolving `{}` in `{}`",
3452 token::get_name(name).get(),
3453 self.module_to_string(&*module_));
3455 // First, check the direct children of the module.
3456 self.populate_module_if_necessary(&module_);
3458 match module_.children.borrow().find(&name) {
3460 if name_bindings.defined_in_namespace(namespace) => {
3461 debug!("(resolving name in module) found node as child");
3462 return Success((Target::new(module_.clone(),
3463 name_bindings.clone(),
3472 // Next, check the module's imports if necessary.
3474 // If this is a search of all imports, we should be done with glob
3475 // resolution at this point.
3476 if name_search_type == PathSearch {
3477 assert_eq!(module_.glob_count.get(), 0);
3480 // Check the list of resolved imports.
3481 match module_.import_resolutions.borrow().find(&name) {
3482 Some(import_resolution) if allow_private_imports ||
3483 import_resolution.is_public => {
3485 if import_resolution.is_public &&
3486 import_resolution.outstanding_references != 0 {
3487 debug!("(resolving name in module) import \
3488 unresolved; bailing out");
3489 return Indeterminate;
3491 match import_resolution.target_for_namespace(namespace) {
3493 debug!("(resolving name in module) name found, \
3494 but not in namespace {:?}",
3498 debug!("(resolving name in module) resolved to \
3500 self.used_imports.insert((import_resolution.id(namespace), namespace));
3501 return Success((target, true));
3505 Some(..) | None => {} // Continue.
3508 // Finally, search through external children.
3509 if namespace == TypeNS {
3510 match module_.external_module_children.borrow().find_copy(&name) {
3514 Rc::new(Resolver::create_name_bindings_from_module(module));
3515 return Success((Target::new(module_,
3523 // We're out of luck.
3524 debug!("(resolving name in module) failed to resolve `{}`",
3525 token::get_name(name).get());
3526 return Failed(None);
3529 fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
3530 let index = module_.resolved_import_count.get();
3531 let imports = module_.imports.borrow();
3532 let import_count = imports.len();
3533 if index != import_count {
3534 let sn = self.session
3536 .span_to_snippet(imports.get(index).span)
3538 if sn.as_slice().contains("::") {
3539 self.resolve_error(imports.get(index).span,
3540 "unresolved import");
3542 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3543 sn.as_slice().slice(0, sn.len()));
3544 self.resolve_error(imports.get(index).span, err.as_slice());
3548 // Descend into children and anonymous children.
3549 self.populate_module_if_necessary(&module_);
3551 for (_, child_node) in module_.children.borrow().iter() {
3552 match child_node.get_module_if_available() {
3556 Some(child_module) => {
3557 self.report_unresolved_imports(child_module);
3562 for (_, module_) in module_.anonymous_children.borrow().iter() {
3563 self.report_unresolved_imports(module_.clone());
3569 // This pass simply determines what all "export" keywords refer to and
3570 // writes the results into the export map.
3572 // FIXME #4953 This pass will be removed once exports change to per-item.
3573 // Then this operation can simply be performed as part of item (or import)
3576 fn record_exports(&mut self) {
3577 let root_module = self.graph_root.get_module();
3578 self.record_exports_for_module_subtree(root_module);
3581 fn record_exports_for_module_subtree(&mut self,
3582 module_: Rc<Module>) {
3583 // If this isn't a local krate, then bail out. We don't need to record
3584 // exports for nonlocal crates.
3586 match module_.def_id.get() {
3587 Some(def_id) if def_id.krate == LOCAL_CRATE => {
3589 debug!("(recording exports for module subtree) recording \
3590 exports for local module `{}`",
3591 self.module_to_string(&*module_));
3594 // Record exports for the root module.
3595 debug!("(recording exports for module subtree) recording \
3596 exports for root module `{}`",
3597 self.module_to_string(&*module_));
3601 debug!("(recording exports for module subtree) not recording \
3603 self.module_to_string(&*module_));
3608 self.record_exports_for_module(&*module_);
3609 self.populate_module_if_necessary(&module_);
3611 for (_, child_name_bindings) in module_.children.borrow().iter() {
3612 match child_name_bindings.get_module_if_available() {
3616 Some(child_module) => {
3617 self.record_exports_for_module_subtree(child_module);
3622 for (_, child_module) in module_.anonymous_children.borrow().iter() {
3623 self.record_exports_for_module_subtree(child_module.clone());
3627 fn record_exports_for_module(&mut self, module_: &Module) {
3628 let mut exports2 = Vec::new();
3630 self.add_exports_for_module(&mut exports2, module_);
3631 match module_.def_id.get() {
3633 self.export_map2.borrow_mut().insert(def_id.node, exports2);
3634 debug!("(computing exports) writing exports for {} (some)",
3641 fn add_exports_of_namebindings(&mut self,
3642 exports2: &mut Vec<Export2> ,
3644 namebindings: &NameBindings,
3646 match namebindings.def_for_namespace(ns) {
3648 let name = token::get_name(name);
3649 debug!("(computing exports) YES: export '{}' => {:?}",
3651 exports2.push(Export2 {
3652 name: name.get().to_string(),
3657 debug!("(computing exports) NO: {:?}", d_opt);
3662 fn add_exports_for_module(&mut self,
3663 exports2: &mut Vec<Export2> ,
3665 for (name, importresolution) in module_.import_resolutions.borrow().iter() {
3666 if !importresolution.is_public {
3669 let xs = [TypeNS, ValueNS];
3670 for &ns in xs.iter() {
3671 match importresolution.target_for_namespace(ns) {
3673 debug!("(computing exports) maybe export '{}'",
3674 token::get_name(*name));
3675 self.add_exports_of_namebindings(exports2,
3688 // We maintain a list of value ribs and type ribs.
3690 // Simultaneously, we keep track of the current position in the module
3691 // graph in the `current_module` pointer. When we go to resolve a name in
3692 // the value or type namespaces, we first look through all the ribs and
3693 // then query the module graph. When we resolve a name in the module
3694 // namespace, we can skip all the ribs (since nested modules are not
3695 // allowed within blocks in Rust) and jump straight to the current module
3698 // Named implementations are handled separately. When we find a method
3699 // call, we consult the module node to find all of the implementations in
3700 // scope. This information is lazily cached in the module node. We then
3701 // generate a fake "implementation scope" containing all the
3702 // implementations thus found, for compatibility with old resolve pass.
3704 fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
3705 let orig_module = self.current_module.clone();
3707 // Move down in the graph.
3713 self.populate_module_if_necessary(&orig_module);
3715 match orig_module.children.borrow().find(&name.name) {
3717 debug!("!!! (with scope) didn't find `{}` in `{}`",
3718 token::get_ident(name),
3719 self.module_to_string(&*orig_module));
3721 Some(name_bindings) => {
3722 match (*name_bindings).get_module_if_available() {
3724 debug!("!!! (with scope) didn't find module \
3726 token::get_ident(name),
3727 self.module_to_string(&*orig_module));
3730 self.current_module = module_;
3740 self.current_module = orig_module;
3743 /// Wraps the given definition in the appropriate number of `def_upvar`
3750 -> Option<DefLike> {
3755 DlDef(d @ DefLocal(..)) | DlDef(d @ DefUpvar(..)) |
3756 DlDef(d @ DefArg(..)) | DlDef(d @ DefBinding(..)) => {
3758 is_ty_param = false;
3760 DlDef(d @ DefTyParam(..)) |
3761 DlDef(d @ DefSelfTy(..)) => {
3766 return Some(def_like);
3770 let mut rib_index = rib_index + 1;
3771 while rib_index < ribs.len() {
3772 match ribs[rib_index].kind {
3774 // Nothing to do. Continue.
3776 FunctionRibKind(function_id, body_id) => {
3778 def = DefUpvar(def.def_id().node,
3784 MethodRibKind(item_id, _) => {
3785 // If the def is a ty param, and came from the parent
3788 DefTyParam(_, did, _) if {
3789 self.def_map.borrow().find(&did.node).map(|x| *x)
3790 == Some(DefTyParamBinder(item_id))
3803 // This was an attempt to access an upvar inside a
3804 // named function item. This is not allowed, so we
3809 "can't capture dynamic environment in a fn item; \
3810 use the || { ... } closure form instead");
3812 // This was an attempt to use a type parameter outside
3815 self.resolve_error(span,
3816 "can't use type parameters from \
3817 outer function; try using a local \
3818 type parameter instead");
3827 // This was an attempt to access an upvar inside a
3828 // named function item. This is not allowed, so we
3833 "can't capture dynamic environment in a fn item; \
3834 use the || { ... } closure form instead");
3836 // This was an attempt to use a type parameter outside
3839 self.resolve_error(span,
3840 "can't use type parameters from \
3841 outer function; try using a local \
3842 type parameter instead");
3847 ConstantItemRibKind => {
3850 self.resolve_error(span,
3851 "cannot use an outer type \
3852 parameter in this context");
3854 // Still doesn't deal with upvars
3855 self.resolve_error(span,
3856 "attempt to use a non-constant \
3857 value in a constant");
3866 return Some(DlDef(def));
3869 fn search_ribs(&self,
3873 -> Option<DefLike> {
3874 // FIXME #4950: This should not use a while loop.
3875 // FIXME #4950: Try caching?
3877 let mut i = ribs.len();
3880 let binding_opt = ribs[i].bindings.borrow().find_copy(&name);
3883 return self.upvarify(ribs, i, def_like, span);
3894 fn resolve_crate(&mut self, krate: &ast::Crate) {
3895 debug!("(resolving crate) starting");
3897 visit::walk_crate(self, krate, ());
3900 fn resolve_item(&mut self, item: &Item) {
3901 debug!("(resolving item) resolving {}",
3902 token::get_ident(item.ident));
3906 // enum item: resolve all the variants' discrs,
3907 // then resolve the ty params
3908 ItemEnum(ref enum_def, ref generics) => {
3909 for variant in (*enum_def).variants.iter() {
3910 for dis_expr in variant.node.disr_expr.iter() {
3911 // resolve the discriminator expr
3913 self.with_constant_rib(|this| {
3914 this.resolve_expr(&**dis_expr);
3919 // n.b. the discr expr gets visited twice.
3920 // but maybe it's okay since the first time will signal an
3921 // error if there is one? -- tjc
3922 self.with_type_parameter_rib(HasTypeParameters(generics,
3927 this.resolve_type_parameters(&generics.ty_params);
3928 this.resolve_where_clause(&generics.where_clause);
3929 visit::walk_item(this, item, ());
3933 ItemTy(_, ref generics) => {
3934 self.with_type_parameter_rib(HasTypeParameters(generics,
3939 visit::walk_item(this, item, ());
3943 ItemImpl(ref generics,
3944 ref implemented_traits,
3946 ref impl_items) => {
3947 self.resolve_implementation(item.id,
3951 impl_items.as_slice());
3954 ItemTrait(ref generics, ref unbound, ref bounds, ref methods) => {
3955 // Create a new rib for the self type.
3956 let self_type_rib = Rib::new(ItemRibKind);
3958 // plain insert (no renaming, types are not currently hygienic....)
3959 let name = self.type_self_name;
3960 self_type_rib.bindings.borrow_mut()
3961 .insert(name, DlDef(DefSelfTy(item.id)));
3962 self.type_ribs.borrow_mut().push(self_type_rib);
3964 // Create a new rib for the trait-wide type parameters.
3965 self.with_type_parameter_rib(HasTypeParameters(generics,
3970 this.resolve_type_parameters(&generics.ty_params);
3971 this.resolve_where_clause(&generics.where_clause);
3973 this.resolve_type_parameter_bounds(item.id, bounds,
3977 &Some(ast::TraitTyParamBound(ref tpb)) => {
3978 this.resolve_trait_reference(item.id, tpb, TraitDerivation);
3983 for method in (*methods).iter() {
3984 // Create a new rib for the method-specific type
3987 // FIXME #4951: Do we need a node ID here?
3990 ast::RequiredMethod(ref ty_m) => {
3991 this.with_type_parameter_rib
3992 (HasTypeParameters(&ty_m.generics,
3995 MethodRibKind(item.id, RequiredMethod)),
3998 // Resolve the method-specific type
4000 this.resolve_type_parameters(
4001 &ty_m.generics.ty_params);
4002 this.resolve_where_clause(&ty_m.generics
4005 for argument in ty_m.decl.inputs.iter() {
4006 this.resolve_type(&*argument.ty);
4009 match ty_m.explicit_self.node {
4010 SelfExplicit(ref typ, _) => {
4011 this.resolve_type(&**typ)
4016 this.resolve_type(&*ty_m.decl.output);
4019 ast::ProvidedMethod(ref m) => {
4020 this.resolve_method(MethodRibKind(item.id,
4021 ProvidedMethod(m.id)),
4028 self.type_ribs.borrow_mut().pop();
4031 ItemStruct(ref struct_def, ref generics) => {
4032 self.resolve_struct(item.id,
4034 struct_def.super_struct,
4035 struct_def.fields.as_slice());
4038 ItemMod(ref module_) => {
4039 self.with_scope(Some(item.ident), |this| {
4040 this.resolve_module(module_, item.span, item.ident,
4045 ItemForeignMod(ref foreign_module) => {
4046 self.with_scope(Some(item.ident), |this| {
4047 for foreign_item in foreign_module.items.iter() {
4048 match foreign_item.node {
4049 ForeignItemFn(_, ref generics) => {
4050 this.with_type_parameter_rib(
4052 generics, FnSpace, foreign_item.id,
4054 |this| visit::walk_foreign_item(this,
4058 ForeignItemStatic(..) => {
4059 visit::walk_foreign_item(this,
4068 ItemFn(fn_decl, _, _, ref generics, block) => {
4069 self.resolve_function(ItemRibKind,
4080 self.with_constant_rib(|this| {
4081 visit::walk_item(this, item, ());
4086 // do nothing, these are just around to be encoded
4091 fn with_type_parameter_rib(&mut self,
4092 type_parameters: TypeParameters,
4093 f: |&mut Resolver|) {
4094 match type_parameters {
4095 HasTypeParameters(generics, space, node_id,
4098 let function_type_rib = Rib::new(rib_kind);
4100 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
4101 let ident = type_parameter.ident;
4102 debug!("with_type_parameter_rib: {} {}", node_id,
4104 let def_like = DlDef(DefTyParam(space,
4105 local_def(type_parameter.id),
4107 // Associate this type parameter with
4108 // the item that bound it
4109 self.record_def(type_parameter.id,
4110 (DefTyParamBinder(node_id), LastMod(AllPublic)));
4111 // plain insert (no renaming)
4112 function_type_rib.bindings.borrow_mut()
4113 .insert(ident.name, def_like);
4115 self.type_ribs.borrow_mut().push(function_type_rib);
4118 NoTypeParameters => {
4125 match type_parameters {
4126 HasTypeParameters(..) => { self.type_ribs.borrow_mut().pop(); }
4127 NoTypeParameters => { }
4131 fn with_label_rib(&mut self, f: |&mut Resolver|) {
4132 self.label_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4134 self.label_ribs.borrow_mut().pop();
4137 fn with_constant_rib(&mut self, f: |&mut Resolver|) {
4138 self.value_ribs.borrow_mut().push(Rib::new(ConstantItemRibKind));
4139 self.type_ribs.borrow_mut().push(Rib::new(ConstantItemRibKind));
4141 self.type_ribs.borrow_mut().pop();
4142 self.value_ribs.borrow_mut().pop();
4145 fn resolve_function(&mut self,
4147 optional_declaration: Option<P<FnDecl>>,
4148 type_parameters: TypeParameters,
4150 // Create a value rib for the function.
4151 let function_value_rib = Rib::new(rib_kind);
4152 self.value_ribs.borrow_mut().push(function_value_rib);
4154 // Create a label rib for the function.
4155 let function_label_rib = Rib::new(rib_kind);
4156 self.label_ribs.borrow_mut().push(function_label_rib);
4158 // If this function has type parameters, add them now.
4159 self.with_type_parameter_rib(type_parameters, |this| {
4160 // Resolve the type parameters.
4161 match type_parameters {
4162 NoTypeParameters => {
4165 HasTypeParameters(ref generics, _, _, _) => {
4166 this.resolve_type_parameters(&generics.ty_params);
4167 this.resolve_where_clause(&generics.where_clause);
4171 // Add each argument to the rib.
4172 match optional_declaration {
4176 Some(declaration) => {
4177 for argument in declaration.inputs.iter() {
4178 let mut bindings_list = HashMap::new();
4179 this.resolve_pattern(&*argument.pat,
4180 ArgumentIrrefutableMode,
4181 &mut bindings_list);
4183 this.resolve_type(&*argument.ty);
4185 debug!("(resolving function) recorded argument");
4188 this.resolve_type(&*declaration.output);
4192 // Resolve the function body.
4193 this.resolve_block(&*block);
4195 debug!("(resolving function) leaving function");
4198 self.label_ribs.borrow_mut().pop();
4199 self.value_ribs.borrow_mut().pop();
4202 fn resolve_type_parameters(&mut self,
4203 type_parameters: &OwnedSlice<TyParam>) {
4204 for type_parameter in type_parameters.iter() {
4205 for bound in type_parameter.bounds.iter() {
4206 self.resolve_type_parameter_bound(type_parameter.id, bound,
4207 TraitBoundingTypeParameter);
4209 match &type_parameter.unbound {
4210 &Some(ref unbound) =>
4211 self.resolve_type_parameter_bound(
4212 type_parameter.id, unbound, TraitBoundingTypeParameter),
4215 match type_parameter.default {
4216 Some(ref ty) => self.resolve_type(&**ty),
4222 fn resolve_type_parameter_bounds(&mut self,
4224 type_parameter_bounds: &OwnedSlice<TyParamBound>,
4225 reference_type: TraitReferenceType) {
4226 for type_parameter_bound in type_parameter_bounds.iter() {
4227 self.resolve_type_parameter_bound(id, type_parameter_bound,
4232 fn resolve_type_parameter_bound(&mut self,
4234 type_parameter_bound: &TyParamBound,
4235 reference_type: TraitReferenceType) {
4236 match *type_parameter_bound {
4237 TraitTyParamBound(ref tref) => {
4238 self.resolve_trait_reference(id, tref, reference_type)
4240 UnboxedFnTyParamBound(ref unboxed_function) => {
4241 for argument in unboxed_function.decl.inputs.iter() {
4242 self.resolve_type(&*argument.ty);
4245 self.resolve_type(&*unboxed_function.decl.output);
4247 RegionTyParamBound(..) => {}
4251 fn resolve_trait_reference(&mut self,
4253 trait_reference: &TraitRef,
4254 reference_type: TraitReferenceType) {
4255 match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
4257 let path_str = self.path_idents_to_string(&trait_reference.path);
4258 let usage_str = match reference_type {
4259 TraitBoundingTypeParameter => "bound type parameter with",
4260 TraitImplementation => "implement",
4261 TraitDerivation => "derive",
4264 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
4265 self.resolve_error(trait_reference.path.span, msg.as_slice());
4269 (DefTrait(_), _) => {
4270 debug!("(resolving trait) found trait def: {:?}", def);
4271 self.record_def(trait_reference.ref_id, def);
4274 self.resolve_error(trait_reference.path.span,
4275 format!("`{}` is not a trait",
4276 self.path_idents_to_string(
4277 &trait_reference.path)));
4279 // If it's a typedef, give a note
4282 self.session.span_note(
4283 trait_reference.path.span,
4284 format!("`type` aliases cannot \
4285 be used for traits")
4297 fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
4298 for predicate in where_clause.predicates.iter() {
4299 match self.resolve_identifier(predicate.ident,
4303 Some((def @ DefTyParam(_, _, _), last_private)) => {
4304 self.record_def(predicate.id, (def, last_private));
4309 format!("undeclared type parameter `{}`",
4311 predicate.ident)).as_slice());
4315 for bound in predicate.bounds.iter() {
4316 self.resolve_type_parameter_bound(predicate.id, bound,
4317 TraitBoundingTypeParameter);
4322 fn resolve_struct(&mut self,
4324 generics: &Generics,
4325 super_struct: Option<P<Ty>>,
4326 fields: &[StructField]) {
4327 // If applicable, create a rib for the type parameters.
4328 self.with_type_parameter_rib(HasTypeParameters(generics,
4333 // Resolve the type parameters.
4334 this.resolve_type_parameters(&generics.ty_params);
4335 this.resolve_where_clause(&generics.where_clause);
4337 // Resolve the super struct.
4338 match super_struct {
4339 Some(t) => match t.node {
4340 TyPath(ref path, None, path_id) => {
4341 match this.resolve_path(id, path, TypeNS, true) {
4342 Some((DefTy(def_id), lp)) if this.structs.contains_key(&def_id) => {
4343 let def = DefStruct(def_id);
4344 debug!("(resolving struct) resolved `{}` to type {:?}",
4345 token::get_ident(path.segments
4349 debug!("(resolving struct) writing resolution for `{}` (id {})",
4350 this.path_idents_to_string(path),
4352 this.record_def(path_id, (def, lp));
4354 Some((DefStruct(_), _)) => {
4355 span_err!(this.session, t.span, E0154,
4356 "super-struct is defined in a different crate");
4359 span_err!(this.session, t.span, E0155,
4360 "super-struct is not a struct type");
4363 span_err!(this.session, t.span, E0156,
4364 "super-struct could not be resolved");
4368 _ => this.session.span_bug(t.span, "path not mapped to a TyPath")
4374 for field in fields.iter() {
4375 this.resolve_type(&*field.node.ty);
4380 // Does this really need to take a RibKind or is it always going
4381 // to be NormalRibKind?
4382 fn resolve_method(&mut self,
4385 let method_generics = method.pe_generics();
4386 let type_parameters = HasTypeParameters(method_generics,
4391 match method.pe_explicit_self().node {
4392 SelfExplicit(ref typ, _) => self.resolve_type(&**typ),
4396 self.resolve_function(rib_kind,
4397 Some(method.pe_fn_decl()),
4402 fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
4403 // Handle nested impls (inside fn bodies)
4404 let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
4405 let result = f(self);
4406 self.current_self_type = previous_value;
4410 fn with_optional_trait_ref<T>(&mut self, id: NodeId,
4411 opt_trait_ref: &Option<TraitRef>,
4412 f: |&mut Resolver| -> T) -> T {
4413 let new_val = match *opt_trait_ref {
4414 Some(ref trait_ref) => {
4415 self.resolve_trait_reference(id, trait_ref, TraitImplementation);
4417 match self.def_map.borrow().find(&trait_ref.ref_id) {
4419 let did = def.def_id();
4420 Some((did, trait_ref.clone()))
4427 let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
4428 let result = f(self);
4429 self.current_trait_ref = original_trait_ref;
4433 fn resolve_implementation(&mut self,
4435 generics: &Generics,
4436 opt_trait_reference: &Option<TraitRef>,
4438 impl_items: &[ImplItem]) {
4439 // If applicable, create a rib for the type parameters.
4440 self.with_type_parameter_rib(HasTypeParameters(generics,
4445 // Resolve the type parameters.
4446 this.resolve_type_parameters(&generics.ty_params);
4447 this.resolve_where_clause(&generics.where_clause);
4449 // Resolve the trait reference, if necessary.
4450 this.with_optional_trait_ref(id, opt_trait_reference, |this| {
4451 // Resolve the self type.
4452 this.resolve_type(self_type);
4454 this.with_current_self_type(self_type, |this| {
4455 for impl_item in impl_items.iter() {
4457 MethodImplItem(method) => {
4458 // If this is a trait impl, ensure the method
4460 this.check_trait_item(method.pe_ident(),
4463 // We also need a new scope for the method-
4464 // specific type parameters.
4465 this.resolve_method(
4467 ProvidedMethod(method.id)),
4477 fn check_trait_item(&self, ident: Ident, span: Span) {
4478 // If there is a TraitRef in scope for an impl, then the method must be in the trait.
4479 for &(did, ref trait_ref) in self.current_trait_ref.iter() {
4480 let method_name = ident.name;
4482 if self.trait_item_map.borrow().find(&(method_name, did)).is_none() {
4483 let path_str = self.path_idents_to_string(&trait_ref.path);
4484 self.resolve_error(span,
4485 format!("method `{}` is not a member of trait `{}`",
4486 token::get_name(method_name),
4487 path_str).as_slice());
4492 fn resolve_module(&mut self, module: &Mod, _span: Span,
4493 _name: Ident, id: NodeId) {
4494 // Write the implementations in scope into the module metadata.
4495 debug!("(resolving module) resolving module ID {}", id);
4496 visit::walk_mod(self, module, ());
4499 fn resolve_local(&mut self, local: &Local) {
4500 // Resolve the type.
4501 self.resolve_type(&*local.ty);
4503 // Resolve the initializer, if necessary.
4508 Some(ref initializer) => {
4509 self.resolve_expr(&**initializer);
4513 // Resolve the pattern.
4514 let mut bindings_list = HashMap::new();
4515 self.resolve_pattern(&*local.pat,
4516 LocalIrrefutableMode,
4517 &mut bindings_list);
4520 // build a map from pattern identifiers to binding-info's.
4521 // this is done hygienically. This could arise for a macro
4522 // that expands into an or-pattern where one 'x' was from the
4523 // user and one 'x' came from the macro.
4524 fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
4525 let mut result = HashMap::new();
4526 pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
4527 let name = mtwt::resolve(path1.node);
4529 binding_info {span: sp,
4530 binding_mode: binding_mode});
4535 // check that all of the arms in an or-pattern have exactly the
4536 // same set of bindings, with the same binding modes for each.
4537 fn check_consistent_bindings(&mut self, arm: &Arm) {
4538 if arm.pats.len() == 0 {
4541 let map_0 = self.binding_mode_map(&**arm.pats.get(0));
4542 for (i, p) in arm.pats.iter().enumerate() {
4543 let map_i = self.binding_mode_map(&**p);
4545 for (&key, &binding_0) in map_0.iter() {
4546 match map_i.find(&key) {
4550 format!("variable `{}` from pattern #1 is \
4551 not bound in pattern #{}",
4552 token::get_name(key),
4555 Some(binding_i) => {
4556 if binding_0.binding_mode != binding_i.binding_mode {
4559 format!("variable `{}` is bound with different \
4560 mode in pattern #{} than in pattern #1",
4561 token::get_name(key),
4568 for (&key, &binding) in map_i.iter() {
4569 if !map_0.contains_key(&key) {
4572 format!("variable `{}` from pattern {}{} is \
4573 not bound in pattern {}1",
4574 token::get_name(key),
4575 "#", i + 1, "#").as_slice());
4581 fn resolve_arm(&mut self, arm: &Arm) {
4582 self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4584 let mut bindings_list = HashMap::new();
4585 for pattern in arm.pats.iter() {
4586 self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
4589 // This has to happen *after* we determine which
4590 // pat_idents are variants
4591 self.check_consistent_bindings(arm);
4593 visit::walk_expr_opt(self, arm.guard, ());
4594 self.resolve_expr(&*arm.body);
4596 self.value_ribs.borrow_mut().pop();
4599 fn resolve_block(&mut self, block: &Block) {
4600 debug!("(resolving block) entering block");
4601 self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4603 // Move down in the graph, if there's an anonymous module rooted here.
4604 let orig_module = self.current_module.clone();
4605 match orig_module.anonymous_children.borrow().find(&block.id) {
4606 None => { /* Nothing to do. */ }
4607 Some(anonymous_module) => {
4608 debug!("(resolving block) found anonymous module, moving \
4610 self.current_module = anonymous_module.clone();
4614 // Descend into the block.
4615 visit::walk_block(self, block, ());
4618 self.current_module = orig_module;
4620 self.value_ribs.borrow_mut().pop();
4621 debug!("(resolving block) leaving block");
4624 fn resolve_type(&mut self, ty: &Ty) {
4626 // Like path expressions, the interpretation of path types depends
4627 // on whether the path has multiple elements in it or not.
4629 TyPath(ref path, ref bounds, path_id) => {
4630 // This is a path in the type namespace. Walk through scopes
4632 let mut result_def = None;
4634 // First, check to see whether the name is a primitive type.
4635 if path.segments.len() == 1 {
4636 let id = path.segments.last().unwrap().identifier;
4638 match self.primitive_type_table
4642 Some(&primitive_type) => {
4644 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4648 .any(|s| !s.lifetimes.is_empty()) {
4649 span_err!(self.session, path.span, E0157,
4650 "lifetime parameters are not allowed on this type");
4651 } else if path.segments
4653 .any(|s| s.types.len() > 0) {
4654 span_err!(self.session, path.span, E0153,
4655 "type parameters are not allowed on this type");
4666 match self.resolve_path(ty.id, path, TypeNS, true) {
4668 debug!("(resolving type) resolved `{}` to \
4670 token::get_ident(path.segments
4674 result_def = Some(def);
4681 Some(_) => {} // Continue.
4686 // Write the result into the def map.
4687 debug!("(resolving type) writing resolution for `{}` \
4689 self.path_idents_to_string(path),
4691 self.record_def(path_id, def);
4694 let msg = format!("use of undeclared type name `{}`",
4695 self.path_idents_to_string(path));
4696 self.resolve_error(ty.span, msg.as_slice());
4700 bounds.as_ref().map(|bound_vec| {
4701 self.resolve_type_parameter_bounds(ty.id, bound_vec,
4702 TraitBoundingTypeParameter);
4706 TyClosure(c) | TyProc(c) => {
4707 self.resolve_type_parameter_bounds(ty.id, &c.bounds,
4708 TraitBoundingTypeParameter);
4709 visit::walk_ty(self, ty, ());
4713 // Just resolve embedded types.
4714 visit::walk_ty(self, ty, ());
4719 fn resolve_pattern(&mut self,
4721 mode: PatternBindingMode,
4722 // Maps idents to the node ID for the (outermost)
4723 // pattern that binds them
4724 bindings_list: &mut HashMap<Name,NodeId>) {
4725 let pat_id = pattern.id;
4726 walk_pat(pattern, |pattern| {
4727 match pattern.node {
4728 PatIdent(binding_mode, ref path1, _) => {
4730 // The meaning of pat_ident with no type parameters
4731 // depends on whether an enum variant or unit-like struct
4732 // with that name is in scope. The probing lookup has to
4733 // be careful not to emit spurious errors. Only matching
4734 // patterns (match) can match nullary variants or
4735 // unit-like structs. For binding patterns (let), matching
4736 // such a value is simply disallowed (since it's rarely
4739 let ident = path1.node;
4740 let renamed = mtwt::resolve(ident);
4742 match self.resolve_bare_identifier_pattern(ident, pattern.span) {
4743 FoundStructOrEnumVariant(def, lp)
4744 if mode == RefutableMode => {
4745 debug!("(resolving pattern) resolving `{}` to \
4746 struct or enum variant",
4747 token::get_name(renamed));
4749 self.enforce_default_binding_mode(
4753 self.record_def(pattern.id, (def, lp));
4755 FoundStructOrEnumVariant(..) => {
4758 format!("declaration of `{}` shadows an enum \
4759 variant or unit-like struct in \
4761 token::get_name(renamed)).as_slice());
4763 FoundConst(def, lp) if mode == RefutableMode => {
4764 debug!("(resolving pattern) resolving `{}` to \
4766 token::get_name(renamed));
4768 self.enforce_default_binding_mode(
4772 self.record_def(pattern.id, (def, lp));
4775 self.resolve_error(pattern.span,
4776 "only irrefutable patterns \
4779 BareIdentifierPatternUnresolved => {
4780 debug!("(resolving pattern) binding `{}`",
4781 token::get_name(renamed));
4783 let def = match mode {
4785 // For pattern arms, we must use
4786 // `def_binding` definitions.
4788 DefBinding(pattern.id, binding_mode)
4790 LocalIrrefutableMode => {
4791 // But for locals, we use `def_local`.
4792 DefLocal(pattern.id, binding_mode)
4794 ArgumentIrrefutableMode => {
4795 // And for function arguments, `def_arg`.
4796 DefArg(pattern.id, binding_mode)
4800 // Record the definition so that later passes
4801 // will be able to distinguish variants from
4802 // locals in patterns.
4804 self.record_def(pattern.id, (def, LastMod(AllPublic)));
4806 // Add the binding to the local ribs, if it
4807 // doesn't already exist in the bindings list. (We
4808 // must not add it if it's in the bindings list
4809 // because that breaks the assumptions later
4810 // passes make about or-patterns.)
4812 if !bindings_list.contains_key(&renamed) {
4813 let this = &mut *self;
4814 let value_ribs = this.value_ribs.borrow();
4815 let length = value_ribs.len();
4816 let last_rib = value_ribs.get(
4818 last_rib.bindings.borrow_mut()
4819 .insert(renamed, DlDef(def));
4820 bindings_list.insert(renamed, pat_id);
4821 } else if bindings_list.find(&renamed) ==
4823 // Then this is a duplicate variable in the
4824 // same disjunction, which is an error.
4825 self.resolve_error(pattern.span,
4826 format!("identifier `{}` is bound \
4827 more than once in the same \
4829 token::get_ident(ident)).as_slice());
4831 // Else, not bound in the same pattern: do
4837 PatEnum(ref path, _) => {
4838 // This must be an enum variant, struct or const.
4839 match self.resolve_path(pat_id, path, ValueNS, false) {
4840 Some(def @ (DefFn(..), _)) |
4841 Some(def @ (DefVariant(..), _)) |
4842 Some(def @ (DefStruct(..), _)) |
4843 Some(def @ (DefStatic(..), _)) => {
4844 self.record_def(pattern.id, def);
4847 self.resolve_error(path.span,
4848 format!("`{}` is not an enum variant, struct or const",
4853 .identifier)).as_slice());
4856 self.resolve_error(path.span,
4857 format!("unresolved enum variant, struct or const `{}`",
4862 .identifier)).as_slice());
4866 // Check the types in the path pattern.
4867 for ty in path.segments
4869 .flat_map(|s| s.types.iter()) {
4870 self.resolve_type(&**ty);
4874 PatLit(ref expr) => {
4875 self.resolve_expr(&**expr);
4878 PatRange(ref first_expr, ref last_expr) => {
4879 self.resolve_expr(&**first_expr);
4880 self.resolve_expr(&**last_expr);
4883 PatStruct(ref path, _, _) => {
4884 match self.resolve_path(pat_id, path, TypeNS, false) {
4885 Some(definition) => {
4886 self.record_def(pattern.id, definition);
4889 debug!("(resolving pattern) didn't find struct \
4890 def: {:?}", result);
4891 let msg = format!("`{}` does not name a structure",
4892 self.path_idents_to_string(path));
4893 self.resolve_error(path.span, msg.as_slice());
4906 fn resolve_bare_identifier_pattern(&mut self, name: Ident, span: Span)
4907 -> BareIdentifierPatternResolution {
4908 let module = self.current_module.clone();
4909 match self.resolve_item_in_lexical_scope(module,
4912 Success((target, _)) => {
4913 debug!("(resolve bare identifier pattern) succeeded in \
4914 finding {} at {:?}",
4915 token::get_ident(name),
4916 target.bindings.value_def.borrow());
4917 match *target.bindings.value_def.borrow() {
4919 fail!("resolved name in the value namespace to a \
4920 set of name bindings with no def?!");
4923 // For the two success cases, this lookup can be
4924 // considered as not having a private component because
4925 // the lookup happened only within the current module.
4927 def @ DefVariant(..) | def @ DefStruct(..) => {
4928 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
4930 def @ DefStatic(_, false) => {
4931 return FoundConst(def, LastMod(AllPublic));
4933 DefStatic(_, true) => {
4934 self.resolve_error(span,
4935 "mutable static variables cannot be referenced in a pattern");
4936 return BareIdentifierPatternUnresolved;
4939 return BareIdentifierPatternUnresolved;
4947 fail!("unexpected indeterminate result");
4951 Some((span, msg)) => {
4952 self.resolve_error(span, format!("failed to resolve: {}",
4958 debug!("(resolve bare identifier pattern) failed to find {}",
4959 token::get_ident(name));
4960 return BareIdentifierPatternUnresolved;
4965 /// If `check_ribs` is true, checks the local definitions first; i.e.
4966 /// doesn't skip straight to the containing module.
4967 fn resolve_path(&mut self,
4970 namespace: Namespace,
4971 check_ribs: bool) -> Option<(Def, LastPrivate)> {
4972 // First, resolve the types.
4973 for ty in path.segments.iter().flat_map(|s| s.types.iter()) {
4974 self.resolve_type(&**ty);
4978 return self.resolve_crate_relative_path(path, namespace);
4981 let unqualified_def =
4982 self.resolve_identifier(path.segments
4989 if path.segments.len() > 1 {
4990 let def = self.resolve_module_relative_path(path, namespace);
4991 match (def, unqualified_def) {
4992 (Some((d, _)), Some((ud, _))) if d == ud => {
4994 .add_lint(lint::builtin::UNNECESSARY_QUALIFICATION,
4997 "unnecessary qualification".to_string());
5005 return unqualified_def;
5008 // resolve a single identifier (used as a varref)
5009 fn resolve_identifier(&mut self,
5011 namespace: Namespace,
5014 -> Option<(Def, LastPrivate)> {
5016 match self.resolve_identifier_in_local_ribs(identifier,
5020 return Some((def, LastMod(AllPublic)));
5028 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
5032 // FIXME #4952: Merge me with resolve_name_in_module?
5033 fn resolve_definition_of_name_in_module(&mut self,
5034 containing_module: Rc<Module>,
5036 namespace: Namespace)
5038 // First, search children.
5039 self.populate_module_if_necessary(&containing_module);
5041 match containing_module.children.borrow().find(&name) {
5042 Some(child_name_bindings) => {
5043 match child_name_bindings.def_for_namespace(namespace) {
5045 // Found it. Stop the search here.
5046 let p = child_name_bindings.defined_in_public_namespace(
5048 let lp = if p {LastMod(AllPublic)} else {
5049 LastMod(DependsOn(def.def_id()))
5051 return ChildNameDefinition(def, lp);
5059 // Next, search import resolutions.
5060 match containing_module.import_resolutions.borrow().find(&name) {
5061 Some(import_resolution) if import_resolution.is_public => {
5062 match (*import_resolution).target_for_namespace(namespace) {
5064 match target.bindings.def_for_namespace(namespace) {
5067 let id = import_resolution.id(namespace);
5068 self.used_imports.insert((id, namespace));
5069 return ImportNameDefinition(def, LastMod(AllPublic));
5072 // This can happen with external impls, due to
5073 // the imperfect way we read the metadata.
5080 Some(..) | None => {} // Continue.
5083 // Finally, search through external children.
5084 if namespace == TypeNS {
5085 match containing_module.external_module_children.borrow()
5089 match module.def_id.get() {
5090 None => {} // Continue.
5092 let lp = if module.is_public {LastMod(AllPublic)} else {
5093 LastMod(DependsOn(def_id))
5095 return ChildNameDefinition(DefMod(def_id), lp);
5102 return NoNameDefinition;
5105 // resolve a "module-relative" path, e.g. a::b::c
5106 fn resolve_module_relative_path(&mut self,
5108 namespace: Namespace)
5109 -> Option<(Def, LastPrivate)> {
5110 let module_path_idents = path.segments.init().iter()
5111 .map(|ps| ps.identifier)
5112 .collect::<Vec<_>>();
5114 let containing_module;
5116 let module = self.current_module.clone();
5117 match self.resolve_module_path(module,
5118 module_path_idents.as_slice(),
5123 let (span, msg) = match err {
5124 Some((span, msg)) => (span, msg),
5126 let msg = format!("Use of undeclared module `{}`",
5127 self.idents_to_string(
5128 module_path_idents.as_slice()));
5133 self.resolve_error(span, format!("failed to resolve. {}",
5137 Indeterminate => fail!("indeterminate unexpected"),
5138 Success((resulting_module, resulting_last_private)) => {
5139 containing_module = resulting_module;
5140 last_private = resulting_last_private;
5144 let ident = path.segments.last().unwrap().identifier;
5145 let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
5148 NoNameDefinition => {
5149 // We failed to resolve the name. Report an error.
5152 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
5153 (def, last_private.or(lp))
5156 match containing_module.kind.get() {
5157 TraitModuleKind | ImplModuleKind => {
5158 match containing_module.def_id.get() {
5160 match self.trait_item_map.borrow().find(&(ident.name, def_id)) {
5161 Some(&StaticMethodTraitItemKind) => (),
5164 debug!("containing module was a trait or impl \
5165 and name was a method -> not resolved");
5178 /// Invariant: This must be called only during main resolution, not during
5179 /// import resolution.
5180 fn resolve_crate_relative_path(&mut self,
5182 namespace: Namespace)
5183 -> Option<(Def, LastPrivate)> {
5184 let module_path_idents = path.segments.init().iter()
5185 .map(|ps| ps.identifier)
5186 .collect::<Vec<_>>();
5188 let root_module = self.graph_root.get_module();
5190 let containing_module;
5192 match self.resolve_module_path_from_root(root_module,
5193 module_path_idents.as_slice(),
5197 LastMod(AllPublic)) {
5199 let (span, msg) = match err {
5200 Some((span, msg)) => (span, msg),
5202 let msg = format!("Use of undeclared module `::{}`",
5203 self.idents_to_string(
5204 module_path_idents.as_slice()));
5209 self.resolve_error(span, format!("failed to resolve. {}",
5215 fail!("indeterminate unexpected");
5218 Success((resulting_module, resulting_last_private)) => {
5219 containing_module = resulting_module;
5220 last_private = resulting_last_private;
5224 let name = path.segments.last().unwrap().identifier.name;
5225 match self.resolve_definition_of_name_in_module(containing_module,
5228 NoNameDefinition => {
5229 // We failed to resolve the name. Report an error.
5232 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
5233 return Some((def, last_private.or(lp)));
5238 fn resolve_identifier_in_local_ribs(&mut self,
5240 namespace: Namespace,
5243 // Check the local set of ribs.
5244 let search_result = match namespace {
5246 let renamed = mtwt::resolve(ident);
5247 self.search_ribs(self.value_ribs.borrow().as_slice(),
5251 let name = ident.name;
5252 self.search_ribs(self.type_ribs.borrow().as_slice(), name, span)
5256 match search_result {
5257 Some(DlDef(def)) => {
5258 debug!("(resolving path in local ribs) resolved `{}` to \
5260 token::get_ident(ident),
5264 Some(DlField) | Some(DlImpl(_)) | None => {
5270 fn resolve_item_by_identifier_in_lexical_scope(&mut self,
5272 namespace: Namespace)
5273 -> Option<(Def, LastPrivate)> {
5275 let module = self.current_module.clone();
5276 match self.resolve_item_in_lexical_scope(module,
5279 Success((target, _)) => {
5280 match (*target.bindings).def_for_namespace(namespace) {
5282 // This can happen if we were looking for a type and
5283 // found a module instead. Modules don't have defs.
5284 debug!("(resolving item path by identifier in lexical \
5285 scope) failed to resolve {} after success...",
5286 token::get_ident(ident));
5290 debug!("(resolving item path in lexical scope) \
5291 resolved `{}` to item",
5292 token::get_ident(ident));
5293 // This lookup is "all public" because it only searched
5294 // for one identifier in the current module (couldn't
5295 // have passed through reexports or anything like that.
5296 return Some((def, LastMod(AllPublic)));
5301 fail!("unexpected indeterminate result");
5305 Some((span, msg)) =>
5306 self.resolve_error(span, format!("failed to resolve. {}", msg)),
5310 debug!("(resolving item path by identifier in lexical scope) \
5311 failed to resolve {}", token::get_ident(ident));
5317 fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
5318 self.emit_errors = false;
5320 self.emit_errors = true;
5324 fn resolve_error<T: Str>(&self, span: Span, s: T) {
5325 if self.emit_errors {
5326 self.session.span_err(span, s.as_slice());
5330 fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
5331 #[deriving(PartialEq)]
5332 enum FallbackChecks {
5337 fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
5338 -> Option<(Path, NodeId, FallbackChecks)> {
5340 TyPath(ref path, _, node_id) => Some((path.clone(), node_id, allow)),
5341 TyPtr(mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
5342 TyRptr(_, mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
5343 // This doesn't handle the remaining `Ty` variants as they are not
5344 // that commonly the self_type, it might be interesting to provide
5345 // support for those in future.
5350 fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
5351 -> Option<Rc<Module>> {
5352 let root = this.current_module.clone();
5353 let last_name = ident_path.last().unwrap().name;
5355 if ident_path.len() == 1 {
5356 match this.primitive_type_table.primitive_types.find(&last_name) {
5359 match this.current_module.children.borrow().find(&last_name) {
5360 Some(child) => child.get_module_if_available(),
5366 match this.resolve_module_path(root,
5367 ident_path.as_slice(),
5371 Success((module, _)) => Some(module),
5377 let (path, node_id, allowed) = match self.current_self_type {
5378 Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
5380 None => return NoSuggestion,
5382 None => return NoSuggestion,
5385 if allowed == Everything {
5386 // Look for a field with the same name in the current self_type.
5387 match self.def_map.borrow().find(&node_id) {
5389 | Some(&DefStruct(did))
5390 | Some(&DefVariant(_, did, _)) => match self.structs.find(&did) {
5393 if fields.iter().any(|&field_name| name == field_name) {
5398 _ => {} // Self type didn't resolve properly
5402 let ident_path = path.segments.iter().map(|seg| seg.identifier).collect::<Vec<_>>();
5404 // Look for a method in the current self type's impl module.
5405 match get_module(self, path.span, ident_path.as_slice()) {
5406 Some(module) => match module.children.borrow().find(&name) {
5408 let p_str = self.path_idents_to_string(&path);
5409 match binding.def_for_namespace(ValueNS) {
5410 Some(DefStaticMethod(_, provenance, _)) => {
5412 FromImpl(_) => return StaticMethod(p_str),
5413 FromTrait(_) => unreachable!()
5416 Some(DefMethod(_, None)) if allowed == Everything => return Method,
5417 Some(DefMethod(_, Some(_))) => return TraitItem,
5426 // Look for a method in the current trait.
5427 let trait_item_map = self.trait_item_map.borrow();
5428 match self.current_trait_ref {
5429 Some((did, ref trait_ref)) => {
5430 let path_str = self.path_idents_to_string(&trait_ref.path);
5432 match trait_item_map.find(&(name, did)) {
5433 Some(&StaticMethodTraitItemKind) => return StaticTraitMethod(path_str),
5434 Some(_) => return TraitItem,
5444 fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5446 let this = &mut *self;
5448 let mut maybes: Vec<token::InternedString> = Vec::new();
5449 let mut values: Vec<uint> = Vec::new();
5451 let mut j = this.value_ribs.borrow().len();
5454 let value_ribs = this.value_ribs.borrow();
5455 let bindings = value_ribs.get(j).bindings.borrow();
5456 for (&k, _) in bindings.iter() {
5457 maybes.push(token::get_name(k));
5458 values.push(uint::MAX);
5462 let mut smallest = 0;
5463 for (i, other) in maybes.iter().enumerate() {
5464 *values.get_mut(i) = name.lev_distance(other.get());
5466 if *values.get(i) <= *values.get(smallest) {
5471 if values.len() > 0 &&
5472 *values.get(smallest) != uint::MAX &&
5473 *values.get(smallest) < name.len() + 2 &&
5474 *values.get(smallest) <= max_distance &&
5475 name != maybes.get(smallest).get() {
5477 Some(maybes.get(smallest).get().to_string())
5484 fn resolve_expr(&mut self, expr: &Expr) {
5485 // First, record candidate traits for this expression if it could
5486 // result in the invocation of a method call.
5488 self.record_candidate_traits_for_expr_if_necessary(expr);
5490 // Next, resolve the node.
5492 // The interpretation of paths depends on whether the path has
5493 // multiple elements in it or not.
5495 ExprPath(ref path) => {
5496 // This is a local path in the value namespace. Walk through
5497 // scopes looking for it.
5499 match self.resolve_path(expr.id, path, ValueNS, true) {
5501 // Write the result into the def map.
5502 debug!("(resolving expr) resolved `{}`",
5503 self.path_idents_to_string(path));
5505 // First-class methods are not supported yet; error
5508 (DefMethod(..), _) => {
5509 self.resolve_error(expr.span,
5510 "first-class methods \
5511 are not supported");
5512 self.session.span_note(expr.span,
5520 self.record_def(expr.id, def);
5523 let wrong_name = self.path_idents_to_string(path);
5524 // Be helpful if the name refers to a struct
5525 // (The pattern matching def_tys where the id is in self.structs
5526 // matches on regular structs while excluding tuple- and enum-like
5527 // structs, which wouldn't result in this error.)
5528 match self.with_no_errors(|this|
5529 this.resolve_path(expr.id, path, TypeNS, false)) {
5530 Some((DefTy(struct_id), _))
5531 if self.structs.contains_key(&struct_id) => {
5532 self.resolve_error(expr.span,
5533 format!("`{}` is a structure name, but \
5535 uses it like a function name",
5536 wrong_name).as_slice());
5538 self.session.span_note(expr.span,
5539 format!("Did you mean to write: \
5540 `{} {{ /* fields */ }}`?",
5541 wrong_name).as_slice());
5545 let mut method_scope = false;
5546 self.value_ribs.borrow().iter().rev().all(|rib| {
5547 let res = match *rib {
5548 Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
5549 Rib { bindings: _, kind: ItemRibKind } => false,
5550 _ => return true, // Keep advancing
5554 false // Stop advancing
5557 if method_scope && token::get_name(self.self_name).get()
5558 == wrong_name.as_slice() {
5561 "`self` is not available \
5562 in a static method. Maybe a \
5563 `self` argument is missing?");
5565 let last_name = path.segments.last().unwrap().identifier.name;
5566 let mut msg = match self.find_fallback_in_self_type(last_name) {
5568 // limit search to 5 to reduce the number
5569 // of stupid suggestions
5570 self.find_best_match_for_name(wrong_name.as_slice(), 5)
5571 .map_or("".to_string(),
5572 |x| format!("`{}`", x))
5575 format!("`self.{}`", wrong_name),
5578 format!("to call `self.{}`", wrong_name),
5579 StaticTraitMethod(path_str)
5580 | StaticMethod(path_str) =>
5581 format!("to call `{}::{}`", path_str, wrong_name)
5585 msg = format!(" Did you mean {}?", msg)
5590 format!("unresolved name `{}`.{}",
5599 visit::walk_expr(self, expr, ());
5602 ExprFnBlock(_, fn_decl, block) |
5603 ExprProc(fn_decl, block) |
5604 ExprUnboxedFn(_, _, fn_decl, block) => {
5605 self.resolve_function(FunctionRibKind(expr.id, block.id),
5606 Some(fn_decl), NoTypeParameters,
5610 ExprStruct(ref path, _, _) => {
5611 // Resolve the path to the structure it goes to. We don't
5612 // check to ensure that the path is actually a structure; that
5613 // is checked later during typeck.
5614 match self.resolve_path(expr.id, path, TypeNS, false) {
5615 Some(definition) => self.record_def(expr.id, definition),
5617 debug!("(resolving expression) didn't find struct \
5618 def: {:?}", result);
5619 let msg = format!("`{}` does not name a structure",
5620 self.path_idents_to_string(path));
5621 self.resolve_error(path.span, msg.as_slice());
5625 visit::walk_expr(self, expr, ());
5628 ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
5629 self.with_label_rib(|this| {
5630 let def_like = DlDef(DefLabel(expr.id));
5633 let label_ribs = this.label_ribs.borrow();
5634 let length = label_ribs.len();
5635 let rib = label_ribs.get(length - 1);
5636 let renamed = mtwt::resolve(label);
5637 rib.bindings.borrow_mut().insert(renamed, def_like);
5640 visit::walk_expr(this, expr, ());
5644 ExprForLoop(ref pattern, ref head, ref body, optional_label) => {
5645 self.resolve_expr(&**head);
5647 self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
5649 self.resolve_pattern(&**pattern,
5650 LocalIrrefutableMode,
5651 &mut HashMap::new());
5653 match optional_label {
5658 .push(Rib::new(NormalRibKind));
5659 let def_like = DlDef(DefLabel(expr.id));
5662 let label_ribs = self.label_ribs.borrow();
5663 let length = label_ribs.len();
5664 let rib = label_ribs.get(length - 1);
5665 let renamed = mtwt::resolve(label);
5666 rib.bindings.borrow_mut().insert(renamed,
5672 self.resolve_block(&**body);
5674 if optional_label.is_some() {
5675 drop(self.label_ribs.borrow_mut().pop())
5678 self.value_ribs.borrow_mut().pop();
5681 ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5682 let renamed = mtwt::resolve(label);
5683 match self.search_ribs(self.label_ribs.borrow().as_slice(),
5684 renamed, expr.span) {
5688 format!("use of undeclared label `{}`",
5689 token::get_ident(label)).as_slice())
5691 Some(DlDef(def @ DefLabel(_))) => {
5692 // Since this def is a label, it is never read.
5693 self.record_def(expr.id, (def, LastMod(AllPublic)))
5696 self.session.span_bug(expr.span,
5697 "label wasn't mapped to a \
5704 visit::walk_expr(self, expr, ());
5709 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5711 ExprField(_, ident, _) => {
5712 // FIXME(#6890): Even though you can't treat a method like a
5713 // field, we need to add any trait methods we find that match
5714 // the field name so that we can do some nice error reporting
5715 // later on in typeck.
5716 let traits = self.search_for_traits_containing_method(ident.node.name);
5717 self.trait_map.insert(expr.id, traits);
5719 ExprMethodCall(ident, _, _) => {
5720 debug!("(recording candidate traits for expr) recording \
5723 let traits = self.search_for_traits_containing_method(ident.node.name);
5724 self.trait_map.insert(expr.id, traits);
5732 fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
5733 debug!("(searching for traits containing method) looking for '{}'",
5734 token::get_name(name));
5736 fn add_trait_info(found_traits: &mut Vec<DefId>,
5737 trait_def_id: DefId,
5739 debug!("(adding trait info) found trait {}:{} for method '{}'",
5742 token::get_name(name));
5743 found_traits.push(trait_def_id);
5746 let mut found_traits = Vec::new();
5747 let mut search_module = self.current_module.clone();
5749 // Look for the current trait.
5750 match self.current_trait_ref {
5751 Some((trait_def_id, _)) => {
5752 let trait_item_map = self.trait_item_map.borrow();
5754 if trait_item_map.contains_key(&(name, trait_def_id)) {
5755 add_trait_info(&mut found_traits, trait_def_id, name);
5758 None => {} // Nothing to do.
5761 // Look for trait children.
5762 self.populate_module_if_necessary(&search_module);
5765 let trait_item_map = self.trait_item_map.borrow();
5766 for (_, child_names) in search_module.children.borrow().iter() {
5767 let def = match child_names.def_for_namespace(TypeNS) {
5771 let trait_def_id = match def {
5772 DefTrait(trait_def_id) => trait_def_id,
5775 if trait_item_map.contains_key(&(name, trait_def_id)) {
5776 add_trait_info(&mut found_traits, trait_def_id, name);
5781 // Look for imports.
5782 for (_, import) in search_module.import_resolutions.borrow().iter() {
5783 let target = match import.target_for_namespace(TypeNS) {
5785 Some(target) => target,
5787 let did = match target.bindings.def_for_namespace(TypeNS) {
5788 Some(DefTrait(trait_def_id)) => trait_def_id,
5789 Some(..) | None => continue,
5791 if self.trait_item_map.borrow().contains_key(&(name, did)) {
5792 add_trait_info(&mut found_traits, did, name);
5793 self.used_imports.insert((import.type_id, TypeNS));
5797 match search_module.parent_link.clone() {
5798 NoParentLink | ModuleParentLink(..) => break,
5799 BlockParentLink(parent_module, _) => {
5800 search_module = parent_module.upgrade().unwrap();
5808 fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
5809 debug!("(recording def) recording {:?} for {:?}, last private {:?}",
5811 assert!(match lp {LastImport{..} => false, _ => true},
5812 "Import should only be used for `use` directives");
5813 self.last_private.insert(node_id, lp);
5814 self.def_map.borrow_mut().insert_or_update_with(node_id, def, |_, old_value| {
5815 // Resolve appears to "resolve" the same ID multiple
5816 // times, so here is a sanity check it at least comes to
5817 // the same conclusion! - nmatsakis
5818 if def != *old_value {
5820 .bug(format!("node_id {:?} resolved first to {:?} and \
5829 fn enforce_default_binding_mode(&mut self,
5831 pat_binding_mode: BindingMode,
5833 match pat_binding_mode {
5834 BindByValue(_) => {}
5836 self.resolve_error(pat.span,
5837 format!("cannot use `ref` binding mode \
5845 // Unused import checking
5847 // Although this is mostly a lint pass, it lives in here because it depends on
5848 // resolve data structures and because it finalises the privacy information for
5849 // `use` directives.
5852 fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
5853 let mut visitor = UnusedImportCheckVisitor{ resolver: self };
5854 visit::walk_crate(&mut visitor, krate, ());
5857 fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
5858 // Ignore is_public import statements because there's no way to be sure
5859 // whether they're used or not. Also ignore imports with a dummy span
5860 // because this means that they were generated in some fashion by the
5861 // compiler and we don't need to consider them.
5862 if vi.vis == Public { return }
5863 if vi.span == DUMMY_SP { return }
5866 ViewItemExternCrate(..) => {} // ignore
5867 ViewItemUse(ref p) => {
5869 ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
5870 ViewPathList(_, ref list, _) => {
5871 for i in list.iter() {
5872 self.finalize_import(i.node.id(), i.span);
5875 ViewPathGlob(_, id) => {
5876 if !self.used_imports.contains(&(id, TypeNS)) &&
5877 !self.used_imports.contains(&(id, ValueNS)) {
5879 .add_lint(lint::builtin::UNUSED_IMPORTS,
5882 "unused import".to_string());
5890 // We have information about whether `use` (import) directives are actually used now.
5891 // If an import is not used at all, we signal a lint error. If an import is only used
5892 // for a single namespace, we remove the other namespace from the recorded privacy
5893 // information. That means in privacy.rs, we will only check imports and namespaces
5894 // which are used. In particular, this means that if an import could name either a
5895 // public or private item, we will check the correct thing, dependent on how the import
5897 fn finalize_import(&mut self, id: NodeId, span: Span) {
5898 debug!("finalizing import uses for {}",
5899 self.session.codemap().span_to_snippet(span));
5901 if !self.used_imports.contains(&(id, TypeNS)) &&
5902 !self.used_imports.contains(&(id, ValueNS)) {
5903 self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
5906 "unused import".to_string());
5909 let (v_priv, t_priv) = match self.last_private.find(&id) {
5917 fail!("we should only have LastImport for `use` directives")
5922 let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
5927 let t_used = if self.used_imports.contains(&(id, TypeNS)) {
5933 match (v_priv, t_priv) {
5934 // Since some items may be both in the value _and_ type namespaces (e.g., structs)
5935 // we might have two LastPrivates pointing at the same thing. There is no point
5936 // checking both, so lets not check the value one.
5937 (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
5941 self.last_private.insert(id, LastImport{value_priv: v_priv,
5944 type_used: t_used});
5950 // Diagnostics are not particularly efficient, because they're rarely
5954 /// A somewhat inefficient routine to obtain the name of a module.
5955 fn module_to_string(&self, module: &Module) -> String {
5956 let mut idents = Vec::new();
5958 fn collect_mod(idents: &mut Vec<ast::Ident>, module: &Module) {
5959 match module.parent_link {
5961 ModuleParentLink(ref module, name) => {
5963 collect_mod(idents, &*module.upgrade().unwrap());
5965 BlockParentLink(ref module, _) => {
5966 // danger, shouldn't be ident?
5967 idents.push(special_idents::opaque);
5968 collect_mod(idents, &*module.upgrade().unwrap());
5972 collect_mod(&mut idents, module);
5974 if idents.len() == 0 {
5975 return "???".to_string();
5977 self.idents_to_string(idents.move_iter().rev()
5978 .collect::<Vec<ast::Ident>>()
5982 #[allow(dead_code)] // useful for debugging
5983 fn dump_module(&mut self, module_: Rc<Module>) {
5984 debug!("Dump of module `{}`:", self.module_to_string(&*module_));
5986 debug!("Children:");
5987 self.populate_module_if_necessary(&module_);
5988 for (&name, _) in module_.children.borrow().iter() {
5989 debug!("* {}", token::get_name(name));
5992 debug!("Import resolutions:");
5993 let import_resolutions = module_.import_resolutions.borrow();
5994 for (&name, import_resolution) in import_resolutions.iter() {
5996 match import_resolution.target_for_namespace(ValueNS) {
5997 None => { value_repr = "".to_string(); }
5999 value_repr = " value:?".to_string();
6005 match import_resolution.target_for_namespace(TypeNS) {
6006 None => { type_repr = "".to_string(); }
6008 type_repr = " type:?".to_string();
6013 debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
6018 pub struct CrateMap {
6019 pub def_map: DefMap,
6020 pub exp_map2: ExportMap2,
6021 pub trait_map: TraitMap,
6022 pub external_exports: ExternalExports,
6023 pub last_private_map: LastPrivateMap,
6026 /// Entry point to crate resolution.
6027 pub fn resolve_crate(session: &Session,
6031 let mut resolver = Resolver::new(session, krate.span);
6032 resolver.resolve(krate);
6033 let Resolver { def_map, export_map2, trait_map, last_private,
6034 external_exports, .. } = resolver;
6037 exp_map2: export_map2,
6038 trait_map: trait_map,
6039 external_exports: external_exports,
6040 last_private_map: last_private,