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 pub use self::PrivateDep::*;
14 pub use self::ImportUse::*;
15 pub use self::TraitItemKind::*;
16 pub use self::LastPrivate::*;
17 use self::PatternBindingMode::*;
18 use self::Namespace::*;
19 use self::NamespaceError::*;
20 use self::NamespaceResult::*;
21 use self::NameDefinition::*;
22 use self::ImportDirectiveSubclass::*;
23 use self::ReducedGraphParent::*;
24 use self::ResolveResult::*;
25 use self::FallbackSuggestion::*;
26 use self::TypeParameters::*;
28 use self::MethodSort::*;
29 use self::UseLexicalScopeFlag::*;
30 use self::ModulePrefixResult::*;
31 use self::NameSearchType::*;
32 use self::BareIdentifierPatternResolution::*;
33 use self::DuplicateCheckingMode::*;
34 use self::ParentLink::*;
35 use self::ModuleKind::*;
36 use self::TraitReferenceType::*;
37 use self::FallbackChecks::*;
41 use metadata::csearch;
42 use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
44 use middle::lang_items::LanguageItems;
45 use middle::pat_util::pat_bindings;
46 use middle::subst::{ParamSpace, FnSpace, TypeSpace};
47 use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
48 use middle::ty::{CaptureModeMap, Freevar, FreevarMap};
49 use util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
51 use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
52 use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
53 use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
54 use syntax::ast::{ExprPath, ExprProc, ExprStruct, FnDecl};
55 use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
56 use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod};
57 use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct};
58 use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local, ItemConst};
59 use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
60 use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
61 use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
62 use syntax::ast::{PolyTraitRef, PrimTy, Public, SelfExplicit, SelfStatic};
63 use syntax::ast::{RegionTyParamBound, StmtDecl, StructField};
64 use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
65 use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
66 use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum};
67 use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyProc, TyQPath};
68 use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
69 use syntax::ast::{TypeImplItem, UnnamedField};
70 use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
71 use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
72 use syntax::ast::{Visibility};
74 use syntax::ast_util::{mod, PostExpansionMethod, local_def, walk_pat};
75 use syntax::attr::AttrMetaMethods;
76 use syntax::ext::mtwt;
77 use syntax::parse::token::{mod, special_names, special_idents};
78 use syntax::codemap::{Span, DUMMY_SP, Pos};
79 use syntax::owned_slice::OwnedSlice;
80 use syntax::visit::{mod, Visitor};
82 use std::collections::{HashMap, HashSet};
83 use std::collections::hash_map::{Occupied, Vacant};
84 use std::cell::{Cell, RefCell};
85 use std::mem::replace;
86 use std::rc::{Rc, Weak};
90 pub type DefMap = RefCell<NodeMap<Def>>;
94 binding_mode: BindingMode,
97 impl Copy for binding_info {}
99 // Map from the name in a pattern to its binding mode.
100 type BindingMap = HashMap<Name,binding_info>;
102 // Trait method resolution
103 pub type TraitMap = NodeMap<Vec<DefId> >;
105 // This is the replacement export map. It maps a module to all of the exports
107 pub type ExportMap2 = NodeMap<Vec<Export2>>;
110 pub name: String, // The name of the target.
111 pub def_id: DefId, // The definition of the target.
114 // This set contains all exported definitions from external crates. The set does
115 // not contain any entries from local crates.
116 pub type ExternalExports = DefIdSet;
119 pub type LastPrivateMap = NodeMap<LastPrivate>;
122 pub enum LastPrivate {
124 // `use` directives (imports) can refer to two separate definitions in the
125 // type and value namespaces. We record here the last private node for each
126 // and whether the import is in fact used for each.
127 // If the Option<PrivateDep> fields are None, it means there is no definition
128 // in that namespace.
129 LastImport{value_priv: Option<PrivateDep>,
130 value_used: ImportUse,
131 type_priv: Option<PrivateDep>,
132 type_used: ImportUse},
135 impl Copy for LastPrivate {}
138 pub enum PrivateDep {
143 impl Copy for PrivateDep {}
145 // How an import is used.
146 #[deriving(PartialEq, Show)]
148 Unused, // The import is not used.
149 Used, // The import is used.
152 impl Copy for ImportUse {}
155 fn or(self, other: LastPrivate) -> LastPrivate {
156 match (self, other) {
157 (me, LastMod(AllPublic)) => me,
163 #[deriving(PartialEq)]
164 enum PatternBindingMode {
166 LocalIrrefutableMode,
167 ArgumentIrrefutableMode,
170 impl Copy for PatternBindingMode {}
172 #[deriving(PartialEq, Eq, Hash, Show)]
178 impl Copy for Namespace {}
180 #[deriving(PartialEq)]
181 enum NamespaceError {
188 impl Copy for NamespaceError {}
190 /// A NamespaceResult represents the result of resolving an import in
191 /// a particular namespace. The result is either definitely-resolved,
192 /// definitely- unresolved, or unknown.
194 enum NamespaceResult {
195 /// Means that resolve hasn't gathered enough information yet to determine
196 /// whether the name is bound in this namespace. (That is, it hasn't
197 /// resolved all `use` directives yet.)
199 /// Means that resolve has determined that the name is definitely
200 /// not bound in the namespace.
202 /// Means that resolve has determined that the name is bound in the Module
203 /// argument, and specified by the NameBindings argument.
204 BoundResult(Rc<Module>, Rc<NameBindings>)
207 impl NamespaceResult {
208 fn is_unknown(&self) -> bool {
210 UnknownResult => true,
214 fn is_unbound(&self) -> bool {
216 UnboundResult => true,
222 enum NameDefinition {
223 NoNameDefinition, //< The name was unbound.
224 ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
225 ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
228 impl<'a, 'v> Visitor<'v> for Resolver<'a> {
229 fn visit_item(&mut self, item: &Item) {
230 self.resolve_item(item);
232 fn visit_arm(&mut self, arm: &Arm) {
233 self.resolve_arm(arm);
235 fn visit_block(&mut self, block: &Block) {
236 self.resolve_block(block);
238 fn visit_expr(&mut self, expr: &Expr) {
239 self.resolve_expr(expr);
241 fn visit_local(&mut self, local: &Local) {
242 self.resolve_local(local);
244 fn visit_ty(&mut self, ty: &Ty) {
245 self.resolve_type(ty);
249 /// Contains data for specific types of import directives.
250 enum ImportDirectiveSubclass {
251 SingleImport(Name /* target */, Name /* source */),
255 impl Copy for ImportDirectiveSubclass {}
257 /// The context that we thread through while building the reduced graph.
259 enum ReducedGraphParent {
260 ModuleReducedGraphParent(Rc<Module>)
263 impl ReducedGraphParent {
264 fn module(&self) -> Rc<Module> {
266 ModuleReducedGraphParent(ref m) => {
273 type ErrorMessage = Option<(Span, String)>;
275 enum ResolveResult<T> {
276 Failed(ErrorMessage), // Failed to resolve the name, optional helpful error message.
277 Indeterminate, // Couldn't determine due to unresolved globs.
278 Success(T) // Successfully resolved the import.
281 impl<T> ResolveResult<T> {
282 fn indeterminate(&self) -> bool {
283 match *self { Indeterminate => true, _ => false }
287 enum FallbackSuggestion {
292 StaticMethod(String),
296 enum TypeParameters<'a> {
302 // Identifies the things that these parameters
303 // were declared on (type, fn, etc)
306 // ID of the enclosing item.
309 // The kind of the rib used for type parameters.
313 impl<'a> Copy for TypeParameters<'a> {}
315 // The rib kind controls the translation of local
316 // definitions (`DefLocal`) to upvars (`DefUpvar`).
319 // No translation needs to be applied.
322 // We passed through a closure scope at the given node ID.
323 // Translate upvars as appropriate.
324 ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
326 // We passed through an impl or trait and are now in one of its
327 // methods. Allow references to ty params that impl or trait
328 // binds. Disallow any other upvars (including other ty params that are
330 // parent; method itself
331 MethodRibKind(NodeId, MethodSort),
333 // We passed through an item scope. Disallow upvars.
336 // We're in a constant item. Can't refer to dynamic stuff.
340 impl Copy for RibKind {}
342 // Methods can be required or provided. RequiredMethod methods only occur in traits.
345 ProvidedMethod(NodeId)
348 impl Copy for MethodSort {}
350 enum UseLexicalScopeFlag {
355 impl Copy for UseLexicalScopeFlag {}
357 enum ModulePrefixResult {
359 PrefixFound(Rc<Module>, uint)
362 #[deriving(Clone, Eq, PartialEq)]
363 pub enum TraitItemKind {
364 NonstaticMethodTraitItemKind,
365 StaticMethodTraitItemKind,
369 impl Copy for TraitItemKind {}
372 pub fn from_explicit_self_category(explicit_self_category:
373 ExplicitSelfCategory)
375 if explicit_self_category == StaticExplicitSelfCategory {
376 StaticMethodTraitItemKind
378 NonstaticMethodTraitItemKind
383 #[deriving(PartialEq)]
384 enum NameSearchType {
385 /// We're doing a name search in order to resolve a `use` directive.
388 /// We're doing a name search in order to resolve a path type, a path
389 /// expression, or a path pattern.
393 impl Copy for NameSearchType {}
395 enum BareIdentifierPatternResolution {
396 FoundStructOrEnumVariant(Def, LastPrivate),
397 FoundConst(Def, LastPrivate),
398 BareIdentifierPatternUnresolved
401 impl Copy for BareIdentifierPatternResolution {}
403 // Specifies how duplicates should be handled when adding a child item if
404 // another item exists with the same name in some namespace.
405 #[deriving(PartialEq)]
406 enum DuplicateCheckingMode {
407 ForbidDuplicateModules,
408 ForbidDuplicateTypesAndModules,
409 ForbidDuplicateValues,
410 ForbidDuplicateTypesAndValues,
414 impl Copy for DuplicateCheckingMode {}
418 bindings: HashMap<Name, DefLike>,
423 fn new(kind: RibKind) -> Rib {
425 bindings: HashMap::new(),
431 /// One import directive.
432 struct ImportDirective {
433 module_path: Vec<Name>,
434 subclass: ImportDirectiveSubclass,
437 is_public: bool, // see note in ImportResolution about how to use this
441 impl ImportDirective {
442 fn new(module_path: Vec<Name> ,
443 subclass: ImportDirectiveSubclass,
450 module_path: module_path,
454 is_public: is_public,
455 shadowable: shadowable,
460 /// The item that an import resolves to.
463 target_module: Rc<Module>,
464 bindings: Rc<NameBindings>,
469 fn new(target_module: Rc<Module>,
470 bindings: Rc<NameBindings>,
474 target_module: target_module,
476 shadowable: shadowable,
481 /// An ImportResolution represents a particular `use` directive.
482 struct ImportResolution {
483 /// Whether this resolution came from a `use` or a `pub use`. Note that this
484 /// should *not* be used whenever resolution is being performed, this is
485 /// only looked at for glob imports statements currently. Privacy testing
486 /// occurs during a later phase of compilation.
489 // The number of outstanding references to this name. When this reaches
490 // zero, outside modules can count on the targets being correct. Before
491 // then, all bets are off; future imports could override this name.
492 outstanding_references: uint,
494 /// The value that this `use` directive names, if there is one.
495 value_target: Option<Target>,
496 /// The source node of the `use` directive leading to the value target
500 /// The type that this `use` directive names, if there is one.
501 type_target: Option<Target>,
502 /// The source node of the `use` directive leading to the type target
507 impl ImportResolution {
508 fn new(id: NodeId, is_public: bool) -> ImportResolution {
512 outstanding_references: 0,
515 is_public: is_public,
519 fn target_for_namespace(&self, namespace: Namespace)
522 TypeNS => self.type_target.clone(),
523 ValueNS => self.value_target.clone(),
527 fn id(&self, namespace: Namespace) -> NodeId {
529 TypeNS => self.type_id,
530 ValueNS => self.value_id,
535 /// The link from a module up to its nearest parent node.
539 ModuleParentLink(Weak<Module>, Name),
540 BlockParentLink(Weak<Module>, NodeId)
543 /// The type of module this is.
544 #[deriving(PartialEq)]
553 impl Copy for ModuleKind {}
555 /// One node in the tree of modules.
557 parent_link: ParentLink,
558 def_id: Cell<Option<DefId>>,
559 kind: Cell<ModuleKind>,
562 children: RefCell<HashMap<Name, Rc<NameBindings>>>,
563 imports: RefCell<Vec<ImportDirective>>,
565 // The external module children of this node that were declared with
567 external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
569 // The anonymous children of this node. Anonymous children are pseudo-
570 // modules that are implicitly created around items contained within
573 // For example, if we have this:
581 // There will be an anonymous module created around `g` with the ID of the
582 // entry block for `f`.
583 anonymous_children: RefCell<NodeMap<Rc<Module>>>,
585 // The status of resolving each import in this module.
586 import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
588 // The number of unresolved globs that this module exports.
589 glob_count: Cell<uint>,
591 // The index of the import we're resolving.
592 resolved_import_count: Cell<uint>,
594 // Whether this module is populated. If not populated, any attempt to
595 // access the children must be preceded with a
596 // `populate_module_if_necessary` call.
597 populated: Cell<bool>,
601 fn new(parent_link: ParentLink,
602 def_id: Option<DefId>,
608 parent_link: parent_link,
609 def_id: Cell::new(def_id),
610 kind: Cell::new(kind),
611 is_public: is_public,
612 children: RefCell::new(HashMap::new()),
613 imports: RefCell::new(Vec::new()),
614 external_module_children: RefCell::new(HashMap::new()),
615 anonymous_children: RefCell::new(NodeMap::new()),
616 import_resolutions: RefCell::new(HashMap::new()),
617 glob_count: Cell::new(0),
618 resolved_import_count: Cell::new(0),
619 populated: Cell::new(!external),
623 fn all_imports_resolved(&self) -> bool {
624 self.imports.borrow().len() == self.resolved_import_count.get()
630 flags DefModifiers: u8 {
631 const PUBLIC = 0b0000_0001,
632 const IMPORTABLE = 0b0000_0010,
636 impl Copy for DefModifiers {}
638 // Records a possibly-private type definition.
641 modifiers: DefModifiers, // see note in ImportResolution about how to use this
642 module_def: Option<Rc<Module>>,
643 type_def: Option<Def>,
644 type_span: Option<Span>
647 // Records a possibly-private value definition.
648 #[deriving(Clone, Show)]
650 modifiers: DefModifiers, // see note in ImportResolution about how to use this
652 value_span: Option<Span>,
655 impl Copy for ValueNsDef {}
657 // Records the definitions (at most one for each namespace) that a name is
659 struct NameBindings {
660 type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
661 value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
664 /// Ways in which a trait can be referenced
665 enum TraitReferenceType {
666 TraitImplementation, // impl SomeTrait for T { ... }
667 TraitDerivation, // trait T : SomeTrait { ... }
668 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
669 TraitObject, // Box<for<'a> SomeTrait>
670 TraitQPath, // <T as SomeTrait>::
673 impl Copy for TraitReferenceType {}
676 fn new() -> NameBindings {
678 type_def: RefCell::new(None),
679 value_def: RefCell::new(None),
683 /// Creates a new module in this set of name bindings.
684 fn define_module(&self,
685 parent_link: ParentLink,
686 def_id: Option<DefId>,
691 // Merges the module with the existing type def or creates a new one.
692 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
693 let module_ = Rc::new(Module::new(parent_link,
698 let type_def = self.type_def.borrow().clone();
701 *self.type_def.borrow_mut() = Some(TypeNsDef {
702 modifiers: modifiers,
703 module_def: Some(module_),
709 *self.type_def.borrow_mut() = Some(TypeNsDef {
710 modifiers: modifiers,
711 module_def: Some(module_),
713 type_def: type_def.type_def
719 /// Sets the kind of the module, creating a new one if necessary.
720 fn set_module_kind(&self,
721 parent_link: ParentLink,
722 def_id: Option<DefId>,
727 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
728 let type_def = self.type_def.borrow().clone();
731 let module = Module::new(parent_link, def_id, kind,
732 external, is_public);
733 *self.type_def.borrow_mut() = Some(TypeNsDef {
734 modifiers: modifiers,
735 module_def: Some(Rc::new(module)),
741 match type_def.module_def {
743 let module = Module::new(parent_link,
748 *self.type_def.borrow_mut() = Some(TypeNsDef {
749 modifiers: modifiers,
750 module_def: Some(Rc::new(module)),
751 type_def: type_def.type_def,
755 Some(module_def) => module_def.kind.set(kind),
761 /// Records a type definition.
762 fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
763 debug!("defining type for def {} with modifiers {}", def, modifiers);
764 // Merges the type with the existing type def or creates a new one.
765 let type_def = self.type_def.borrow().clone();
768 *self.type_def.borrow_mut() = Some(TypeNsDef {
772 modifiers: modifiers,
776 *self.type_def.borrow_mut() = Some(TypeNsDef {
779 module_def: type_def.module_def,
780 modifiers: modifiers,
786 /// Records a value definition.
787 fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
788 debug!("defining value for def {} with modifiers {}", def, modifiers);
789 *self.value_def.borrow_mut() = Some(ValueNsDef {
791 value_span: Some(sp),
792 modifiers: modifiers,
796 /// Returns the module node if applicable.
797 fn get_module_if_available(&self) -> Option<Rc<Module>> {
798 match *self.type_def.borrow() {
799 Some(ref type_def) => type_def.module_def.clone(),
804 /// Returns the module node. Panics if this node does not have a module
806 fn get_module(&self) -> Rc<Module> {
807 match self.get_module_if_available() {
809 panic!("get_module called on a node with no module \
812 Some(module_def) => module_def
816 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
818 TypeNS => return self.type_def.borrow().is_some(),
819 ValueNS => return self.value_def.borrow().is_some()
823 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
824 self.defined_in_namespace_with(namespace, PUBLIC)
827 fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
829 TypeNS => match *self.type_def.borrow() {
830 Some(ref def) => def.modifiers.contains(modifiers), None => false
832 ValueNS => match *self.value_def.borrow() {
833 Some(ref def) => def.modifiers.contains(modifiers), None => false
838 fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
841 match *self.type_def.borrow() {
843 Some(ref type_def) => {
844 match type_def.type_def {
845 Some(type_def) => Some(type_def),
847 match type_def.module_def {
848 Some(ref module) => {
849 match module.def_id.get() {
850 Some(did) => Some(DefMod(did)),
862 match *self.value_def.borrow() {
864 Some(value_def) => Some(value_def.def)
870 fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
871 if self.defined_in_namespace(namespace) {
874 match *self.type_def.borrow() {
876 Some(ref type_def) => type_def.type_span
880 match *self.value_def.borrow() {
882 Some(ref value_def) => value_def.value_span
892 /// Interns the names of the primitive types.
893 struct PrimitiveTypeTable {
894 primitive_types: HashMap<Name, PrimTy>,
897 impl PrimitiveTypeTable {
898 fn new() -> PrimitiveTypeTable {
899 let mut table = PrimitiveTypeTable {
900 primitive_types: HashMap::new()
903 table.intern("bool", TyBool);
904 table.intern("char", TyChar);
905 table.intern("f32", TyFloat(TyF32));
906 table.intern("f64", TyFloat(TyF64));
907 table.intern("int", TyInt(TyI));
908 table.intern("i8", TyInt(TyI8));
909 table.intern("i16", TyInt(TyI16));
910 table.intern("i32", TyInt(TyI32));
911 table.intern("i64", TyInt(TyI64));
912 table.intern("str", TyStr);
913 table.intern("uint", TyUint(TyU));
914 table.intern("u8", TyUint(TyU8));
915 table.intern("u16", TyUint(TyU16));
916 table.intern("u32", TyUint(TyU32));
917 table.intern("u64", TyUint(TyU64));
922 fn intern(&mut self, string: &str, primitive_type: PrimTy) {
923 self.primitive_types.insert(token::intern(string), primitive_type);
928 fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
931 ModuleError | TypeError => "type or module",
932 ValueError => "value",
936 /// The main resolver class.
937 struct Resolver<'a> {
938 session: &'a Session,
940 graph_root: NameBindings,
942 trait_item_map: FnvHashMap<(Name, DefId), TraitItemKind>,
944 structs: FnvHashMap<DefId, Vec<Name>>,
946 // The number of imports that are currently unresolved.
947 unresolved_imports: uint,
949 // The module that represents the current item scope.
950 current_module: Rc<Module>,
952 // The current set of local scopes, for values.
953 // FIXME #4948: Reuse ribs to avoid allocation.
954 value_ribs: Vec<Rib>,
956 // The current set of local scopes, for types.
959 // The current set of local scopes, for labels.
960 label_ribs: Vec<Rib>,
962 // The trait that the current context can refer to.
963 current_trait_ref: Option<(DefId, TraitRef)>,
965 // The current self type if inside an impl (used for better errors).
966 current_self_type: Option<Ty>,
968 // The ident for the keyword "self".
970 // The ident for the non-keyword "Self".
971 type_self_name: Name,
973 // The idents for the primitive types.
974 primitive_type_table: PrimitiveTypeTable,
977 freevars: RefCell<FreevarMap>,
978 freevars_seen: RefCell<NodeMap<NodeSet>>,
979 capture_mode_map: CaptureModeMap,
980 export_map2: ExportMap2,
982 external_exports: ExternalExports,
983 last_private: LastPrivateMap,
985 // Whether or not to print error messages. Can be set to true
986 // when getting additional info for error message suggestions,
987 // so as to avoid printing duplicate errors
990 used_imports: HashSet<(NodeId, Namespace)>,
991 used_crates: HashSet<CrateNum>,
994 struct BuildReducedGraphVisitor<'a, 'b:'a> {
995 resolver: &'a mut Resolver<'b>,
996 parent: ReducedGraphParent
999 impl<'a, 'b, 'v> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b> {
1001 fn visit_item(&mut self, item: &Item) {
1002 let p = self.resolver.build_reduced_graph_for_item(item, self.parent.clone());
1003 let old_parent = replace(&mut self.parent, p);
1004 visit::walk_item(self, item);
1005 self.parent = old_parent;
1008 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
1009 let parent = self.parent.clone();
1010 self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
1013 let mut v = BuildReducedGraphVisitor {
1015 parent: parent.clone()
1017 visit::walk_foreign_item(&mut v, foreign_item);
1021 fn visit_view_item(&mut self, view_item: &ViewItem) {
1022 self.resolver.build_reduced_graph_for_view_item(view_item, self.parent.clone());
1025 fn visit_block(&mut self, block: &Block) {
1026 let np = self.resolver.build_reduced_graph_for_block(block, self.parent.clone());
1027 let old_parent = replace(&mut self.parent, np);
1028 visit::walk_block(self, block);
1029 self.parent = old_parent;
1034 struct UnusedImportCheckVisitor<'a, 'b:'a> {
1035 resolver: &'a mut Resolver<'b>
1038 impl<'a, 'b, 'v> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b> {
1039 fn visit_view_item(&mut self, vi: &ViewItem) {
1040 self.resolver.check_for_item_unused_imports(vi);
1041 visit::walk_view_item(self, vi);
1045 #[deriving(PartialEq)]
1046 enum FallbackChecks {
1052 impl<'a> Resolver<'a> {
1053 fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
1054 let graph_root = NameBindings::new();
1056 graph_root.define_module(NoParentLink,
1057 Some(DefId { krate: 0, node: 0 }),
1063 let current_module = graph_root.get_module();
1068 // The outermost module has def ID 0; this is not reflected in the
1071 graph_root: graph_root,
1073 trait_item_map: FnvHashMap::new(),
1074 structs: FnvHashMap::new(),
1076 unresolved_imports: 0,
1078 current_module: current_module,
1079 value_ribs: Vec::new(),
1080 type_ribs: Vec::new(),
1081 label_ribs: Vec::new(),
1083 current_trait_ref: None,
1084 current_self_type: None,
1086 self_name: special_names::self_,
1087 type_self_name: special_names::type_self,
1089 primitive_type_table: PrimitiveTypeTable::new(),
1091 def_map: RefCell::new(NodeMap::new()),
1092 freevars: RefCell::new(NodeMap::new()),
1093 freevars_seen: RefCell::new(NodeMap::new()),
1094 capture_mode_map: NodeMap::new(),
1095 export_map2: NodeMap::new(),
1096 trait_map: NodeMap::new(),
1097 used_imports: HashSet::new(),
1098 used_crates: HashSet::new(),
1099 external_exports: DefIdSet::new(),
1100 last_private: NodeMap::new(),
1105 /// The main name resolution procedure.
1106 fn resolve(&mut self, krate: &ast::Crate) {
1107 self.build_reduced_graph(krate);
1108 self.session.abort_if_errors();
1110 self.resolve_imports();
1111 self.session.abort_if_errors();
1113 self.record_exports();
1114 self.session.abort_if_errors();
1116 self.resolve_crate(krate);
1117 self.session.abort_if_errors();
1119 self.check_for_unused_imports(krate);
1123 // Reduced graph building
1125 // Here we build the "reduced graph": the graph of the module tree without
1126 // any imports resolved.
1129 /// Constructs the reduced graph for the entire crate.
1130 fn build_reduced_graph(&mut self, krate: &ast::Crate) {
1131 let parent = ModuleReducedGraphParent(self.graph_root.get_module());
1132 let mut visitor = BuildReducedGraphVisitor {
1136 visit::walk_crate(&mut visitor, krate);
1139 /// Adds a new child item to the module definition of the parent node and
1140 /// returns its corresponding name bindings as well as the current parent.
1141 /// Or, if we're inside a block, creates (or reuses) an anonymous module
1142 /// corresponding to the innermost block ID and returns the name bindings
1143 /// as well as the newly-created parent.
1147 /// Panics if this node does not have a module definition and we are not inside
1151 reduced_graph_parent: ReducedGraphParent,
1152 duplicate_checking_mode: DuplicateCheckingMode,
1153 // For printing errors
1155 -> Rc<NameBindings> {
1156 // If this is the immediate descendant of a module, then we add the
1157 // child name directly. Otherwise, we create or reuse an anonymous
1158 // module and add the child to that.
1160 let module_ = reduced_graph_parent.module();
1162 self.check_for_conflicts_between_external_crates_and_items(&*module_,
1166 // Add or reuse the child.
1167 let child = module_.children.borrow().get(&name).cloned();
1170 let child = Rc::new(NameBindings::new());
1171 module_.children.borrow_mut().insert(name, child.clone());
1175 // Enforce the duplicate checking mode:
1177 // * If we're requesting duplicate module checking, check that
1178 // there isn't a module in the module with the same name.
1180 // * If we're requesting duplicate type checking, check that
1181 // there isn't a type in the module with the same name.
1183 // * If we're requesting duplicate value checking, check that
1184 // there isn't a value in the module with the same name.
1186 // * If we're requesting duplicate type checking and duplicate
1187 // value checking, check that there isn't a duplicate type
1188 // and a duplicate value with the same name.
1190 // * If no duplicate checking was requested at all, do
1193 let mut duplicate_type = NoError;
1194 let ns = match duplicate_checking_mode {
1195 ForbidDuplicateModules => {
1196 if child.get_module_if_available().is_some() {
1197 duplicate_type = ModuleError;
1201 ForbidDuplicateTypesAndModules => {
1202 match child.def_for_namespace(TypeNS) {
1204 Some(_) if child.get_module_if_available()
1205 .map(|m| m.kind.get()) ==
1206 Some(ImplModuleKind) => {}
1207 Some(_) => duplicate_type = TypeError
1211 ForbidDuplicateValues => {
1212 if child.defined_in_namespace(ValueNS) {
1213 duplicate_type = ValueError;
1217 ForbidDuplicateTypesAndValues => {
1219 match child.def_for_namespace(TypeNS) {
1220 Some(DefMod(_)) | None => {}
1223 duplicate_type = TypeError;
1226 if child.defined_in_namespace(ValueNS) {
1227 duplicate_type = ValueError;
1232 OverwriteDuplicates => None
1234 if duplicate_type != NoError {
1235 // Return an error here by looking up the namespace that
1236 // had the duplicate.
1237 let ns = ns.unwrap();
1238 self.resolve_error(sp,
1239 format!("duplicate definition of {} `{}`",
1240 namespace_error_to_string(duplicate_type),
1241 token::get_name(name)).as_slice());
1243 let r = child.span_for_namespace(ns);
1244 for sp in r.iter() {
1245 self.session.span_note(*sp,
1246 format!("first definition of {} `{}` here",
1247 namespace_error_to_string(duplicate_type),
1248 token::get_name(name)).as_slice());
1257 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1258 // If the block has view items, we need an anonymous module.
1259 if block.view_items.len() > 0 {
1263 // Check each statement.
1264 for statement in block.stmts.iter() {
1265 match statement.node {
1266 StmtDecl(ref declaration, _) => {
1267 match declaration.node {
1282 // If we found neither view items nor items, we don't need to create
1283 // an anonymous module.
1288 fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Name)
1291 ModuleReducedGraphParent(module_) => {
1292 return ModuleParentLink(module_.downgrade(), name);
1297 /// Constructs the reduced graph for one item.
1298 fn build_reduced_graph_for_item(&mut self,
1300 parent: ReducedGraphParent)
1301 -> ReducedGraphParent
1303 let name = item.ident.name;
1305 let is_public = item.vis == ast::Public;
1306 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
1311 self.add_child(name, parent.clone(), ForbidDuplicateModules, sp);
1313 let parent_link = self.get_parent_link(parent, name);
1314 let def_id = DefId { krate: 0, node: item.id };
1315 name_bindings.define_module(parent_link,
1319 item.vis == ast::Public,
1322 ModuleReducedGraphParent(name_bindings.get_module())
1325 ItemForeignMod(..) => parent,
1327 // These items live in the value namespace.
1328 ItemStatic(_, m, _) => {
1330 self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
1331 let mutbl = m == ast::MutMutable;
1333 name_bindings.define_value
1334 (DefStatic(local_def(item.id), mutbl), sp, modifiers);
1337 ItemConst(_, _) => {
1338 self.add_child(name, parent.clone(), ForbidDuplicateValues, sp)
1339 .define_value(DefConst(local_def(item.id)),
1343 ItemFn(_, _, _, _, _) => {
1345 self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
1347 let def = DefFn(local_def(item.id), false);
1348 name_bindings.define_value(def, sp, modifiers);
1352 // These items live in the type namespace.
1355 self.add_child(name,
1357 ForbidDuplicateTypesAndModules,
1360 name_bindings.define_type
1361 (DefTy(local_def(item.id), false), sp, modifiers);
1365 ItemEnum(ref enum_definition, _) => {
1367 self.add_child(name,
1369 ForbidDuplicateTypesAndModules,
1372 name_bindings.define_type
1373 (DefTy(local_def(item.id), true), sp, modifiers);
1375 let parent_link = self.get_parent_link(parent.clone(), name);
1376 // We want to make sure the module type is EnumModuleKind
1377 // even if there's already an ImplModuleKind module defined,
1378 // since that's how we prevent duplicate enum definitions
1379 name_bindings.set_module_kind(parent_link,
1380 Some(local_def(item.id)),
1386 for variant in (*enum_definition).variants.iter() {
1387 self.build_reduced_graph_for_variant(
1390 ModuleReducedGraphParent(name_bindings.get_module()));
1395 // These items live in both the type and value namespaces.
1396 ItemStruct(ref struct_def, _) => {
1397 // Adding to both Type and Value namespaces or just Type?
1398 let (forbid, ctor_id) = match struct_def.ctor_id {
1399 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1400 None => (ForbidDuplicateTypesAndModules, None)
1403 let name_bindings = self.add_child(name, parent.clone(), forbid, sp);
1405 // Define a name in the type namespace.
1406 name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
1408 // If this is a newtype or unit-like struct, define a name
1409 // in the value namespace as well
1412 name_bindings.define_value(DefStruct(local_def(cid)),
1418 // Record the def ID and fields of this struct.
1419 let named_fields = struct_def.fields.iter().filter_map(|f| {
1421 NamedField(ident, _) => Some(ident.name),
1422 UnnamedField(_) => None
1425 self.structs.insert(local_def(item.id), named_fields);
1430 ItemImpl(_, None, ref ty, ref impl_items) => {
1431 // If this implements an anonymous trait, then add all the
1432 // methods within to a new module, if the type was defined
1433 // within this module.
1435 let mod_name = match ty.node {
1436 TyPath(ref path, _) if path.segments.len() == 1 => {
1437 // FIXME(18446) we should distinguish between the name of
1438 // a trait and the name of an impl of that trait.
1439 Some(path.segments.last().unwrap().identifier.name)
1441 TyObjectSum(ref lhs_ty, _) => {
1443 TyPath(ref path, _) if path.segments.len() == 1 => {
1444 Some(path.segments.last().unwrap().identifier.name)
1458 self.resolve_error(ty.span,
1459 "inherent implementations may \
1460 only be implemented in the same \
1461 module as the type they are \
1465 // Create the module and add all methods.
1466 let parent_opt = parent.module().children.borrow()
1467 .get(&mod_name).cloned();
1468 let new_parent = match parent_opt {
1469 // It already exists
1470 Some(ref child) if child.get_module_if_available()
1472 (child.get_module().kind.get() == ImplModuleKind ||
1473 child.get_module().kind.get() == TraitModuleKind) => {
1474 ModuleReducedGraphParent(child.get_module())
1476 Some(ref child) if child.get_module_if_available()
1478 child.get_module().kind.get() ==
1480 ModuleReducedGraphParent(child.get_module())
1482 // Create the module
1485 self.add_child(mod_name,
1487 ForbidDuplicateModules,
1491 self.get_parent_link(parent.clone(), name);
1492 let def_id = local_def(item.id);
1495 !name_bindings.defined_in_namespace(ns) ||
1496 name_bindings.defined_in_public_namespace(ns);
1498 name_bindings.define_module(parent_link,
1505 ModuleReducedGraphParent(
1506 name_bindings.get_module())
1510 // For each implementation item...
1511 for impl_item in impl_items.iter() {
1513 MethodImplItem(ref method) => {
1514 // Add the method to the module.
1515 let name = method.pe_ident().name;
1516 let method_name_bindings =
1517 self.add_child(name,
1519 ForbidDuplicateValues,
1521 let def = match method.pe_explicit_self()
1524 // Static methods become
1525 // `DefStaticMethod`s.
1526 DefStaticMethod(local_def(method.id),
1527 FromImpl(local_def(item.id)))
1530 // Non-static methods become
1532 DefMethod(local_def(method.id),
1534 FromImpl(local_def(item.id)))
1538 // NB: not IMPORTABLE
1539 let modifiers = if method.pe_vis() == ast::Public {
1542 DefModifiers::empty()
1544 method_name_bindings.define_value(
1549 TypeImplItem(ref typedef) => {
1550 // Add the typedef to the module.
1551 let name = typedef.ident.name;
1552 let typedef_name_bindings =
1556 ForbidDuplicateTypesAndModules,
1558 let def = DefAssociatedTy(local_def(
1560 // NB: not IMPORTABLE
1561 let modifiers = if typedef.vis == ast::Public {
1564 DefModifiers::empty()
1566 typedef_name_bindings.define_type(
1579 ItemImpl(_, Some(_), _, _) => parent,
1581 ItemTrait(_, _, _, ref methods) => {
1583 self.add_child(name,
1585 ForbidDuplicateTypesAndModules,
1588 // Add all the methods within to a new module.
1589 let parent_link = self.get_parent_link(parent.clone(), name);
1590 name_bindings.define_module(parent_link,
1591 Some(local_def(item.id)),
1594 item.vis == ast::Public,
1596 let module_parent = ModuleReducedGraphParent(name_bindings.
1599 let def_id = local_def(item.id);
1601 // Add the names of all the methods to the trait info.
1602 for method in methods.iter() {
1603 let (name, kind) = match *method {
1604 ast::RequiredMethod(_) |
1605 ast::ProvidedMethod(_) => {
1607 ast_util::trait_item_to_ty_method(method);
1609 let name = ty_m.ident.name;
1611 // Add it as a name in the trait module.
1612 let (def, static_flag) = match ty_m.explicit_self
1615 // Static methods become `DefStaticMethod`s.
1618 FromTrait(local_def(item.id))),
1619 StaticMethodTraitItemKind)
1622 // Non-static methods become `DefMethod`s.
1623 (DefMethod(local_def(ty_m.id),
1624 Some(local_def(item.id)),
1625 FromTrait(local_def(item.id))),
1626 NonstaticMethodTraitItemKind)
1630 let method_name_bindings =
1631 self.add_child(name,
1632 module_parent.clone(),
1633 ForbidDuplicateTypesAndValues,
1635 // NB: not IMPORTABLE
1636 method_name_bindings.define_value(def,
1642 ast::TypeTraitItem(ref associated_type) => {
1643 let def = DefAssociatedTy(local_def(
1644 associated_type.ty_param.id));
1647 self.add_child(associated_type.ty_param.ident.name,
1648 module_parent.clone(),
1649 ForbidDuplicateTypesAndValues,
1650 associated_type.ty_param.span);
1651 // NB: not IMPORTABLE
1652 name_bindings.define_type(def,
1653 associated_type.ty_param.span,
1656 (associated_type.ty_param.ident.name, TypeTraitItemKind)
1660 self.trait_item_map.insert((name, def_id), kind);
1663 name_bindings.define_type(DefTrait(def_id), sp, modifiers);
1666 ItemMac(..) => parent
1670 // Constructs the reduced graph for one variant. Variants exist in the
1671 // type and value namespaces.
1672 fn build_reduced_graph_for_variant(&mut self,
1675 parent: ReducedGraphParent) {
1676 let name = variant.node.name.name;
1677 let is_exported = match variant.node.kind {
1678 TupleVariantKind(_) => false,
1679 StructVariantKind(_) => {
1680 // Not adding fields for variants as they are not accessed with a self receiver
1681 self.structs.insert(local_def(variant.node.id), Vec::new());
1686 let child = self.add_child(name, parent,
1687 ForbidDuplicateTypesAndValues,
1689 // variants are always treated as importable to allow them to be glob
1691 child.define_value(DefVariant(item_id,
1692 local_def(variant.node.id), is_exported),
1693 variant.span, PUBLIC | IMPORTABLE);
1694 child.define_type(DefVariant(item_id,
1695 local_def(variant.node.id), is_exported),
1696 variant.span, PUBLIC | IMPORTABLE);
1699 /// Constructs the reduced graph for one 'view item'. View items consist
1700 /// of imports and use directives.
1701 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1702 parent: ReducedGraphParent) {
1703 match view_item.node {
1704 ViewItemUse(ref view_path) => {
1705 // Extract and intern the module part of the path. For
1706 // globs and lists, the path is found directly in the AST;
1707 // for simple paths we have to munge the path a little.
1708 let module_path = match view_path.node {
1709 ViewPathSimple(_, ref full_path, _) => {
1712 .iter().map(|ident| ident.identifier.name)
1716 ViewPathGlob(ref module_ident_path, _) |
1717 ViewPathList(ref module_ident_path, _, _) => {
1718 module_ident_path.segments
1719 .iter().map(|ident| ident.identifier.name).collect()
1723 // Build up the import directives.
1724 let module_ = parent.module();
1725 let is_public = view_item.vis == ast::Public;
1730 attr.name() == token::get_name(
1731 special_idents::prelude_import.name)
1734 match view_path.node {
1735 ViewPathSimple(binding, ref full_path, id) => {
1737 full_path.segments.last().unwrap().identifier.name;
1738 if token::get_name(source_name).get() == "mod" {
1739 self.resolve_error(view_path.span,
1740 "`mod` imports are only allowed within a { } list");
1743 let subclass = SingleImport(binding.name,
1745 self.build_import_directive(&*module_,
1753 ViewPathList(_, ref source_items, _) => {
1754 // Make sure there's at most one `mod` import in the list.
1755 let mod_spans = source_items.iter().filter_map(|item| match item.node {
1756 PathListMod { .. } => Some(item.span),
1758 }).collect::<Vec<Span>>();
1759 if mod_spans.len() > 1 {
1760 self.resolve_error(mod_spans[0],
1761 "`mod` import can only appear once in the list");
1762 for other_span in mod_spans.iter().skip(1) {
1763 self.session.span_note(*other_span,
1764 "another `mod` import appears here");
1768 for source_item in source_items.iter() {
1769 let (module_path, name) = match source_item.node {
1770 PathListIdent { name, .. } =>
1771 (module_path.clone(), name.name),
1772 PathListMod { .. } => {
1773 let name = match module_path.last() {
1774 Some(name) => *name,
1776 self.resolve_error(source_item.span,
1777 "`mod` import can only appear in an import list \
1778 with a non-empty prefix");
1782 let module_path = module_path.init();
1783 (module_path.to_vec(), name)
1786 self.build_import_directive(
1789 SingleImport(name, name),
1791 source_item.node.id(),
1796 ViewPathGlob(_, id) => {
1797 self.build_import_directive(&*module_,
1808 ViewItemExternCrate(name, _, node_id) => {
1809 // n.b. we don't need to look at the path option here, because cstore already did
1810 for &crate_id in self.session.cstore
1811 .find_extern_mod_stmt_cnum(node_id).iter() {
1812 let def_id = DefId { krate: crate_id, node: 0 };
1813 self.external_exports.insert(def_id);
1815 ModuleParentLink(parent.module().downgrade(), name.name);
1816 let external_module = Rc::new(Module::new(parent_link,
1821 debug!("(build reduced graph for item) found extern `{}`",
1822 self.module_to_string(&*external_module));
1823 self.check_for_conflicts_between_external_crates(
1827 parent.module().external_module_children.borrow_mut()
1828 .insert(name.name, external_module.clone());
1829 self.build_reduced_graph_for_external_crate(external_module);
1835 /// Constructs the reduced graph for one foreign item.
1836 fn build_reduced_graph_for_foreign_item(&mut self,
1837 foreign_item: &ForeignItem,
1838 parent: ReducedGraphParent,
1839 f: |&mut Resolver|) {
1840 let name = foreign_item.ident.name;
1841 let is_public = foreign_item.vis == ast::Public;
1842 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
1844 self.add_child(name, parent, ForbidDuplicateValues,
1847 match foreign_item.node {
1848 ForeignItemFn(_, ref generics) => {
1849 let def = DefFn(local_def(foreign_item.id), false);
1850 name_bindings.define_value(def, foreign_item.span, modifiers);
1852 self.with_type_parameter_rib(
1853 HasTypeParameters(generics,
1859 ForeignItemStatic(_, m) => {
1860 let def = DefStatic(local_def(foreign_item.id), m);
1861 name_bindings.define_value(def, foreign_item.span, modifiers);
1868 fn build_reduced_graph_for_block(&mut self,
1870 parent: ReducedGraphParent)
1871 -> ReducedGraphParent
1873 if self.block_needs_anonymous_module(block) {
1874 let block_id = block.id;
1876 debug!("(building reduced graph for block) creating a new \
1877 anonymous module for block {}",
1880 let parent_module = parent.module();
1881 let new_module = Rc::new(Module::new(
1882 BlockParentLink(parent_module.downgrade(), block_id),
1884 AnonymousModuleKind,
1887 parent_module.anonymous_children.borrow_mut()
1888 .insert(block_id, new_module.clone());
1889 ModuleReducedGraphParent(new_module)
1895 fn handle_external_def(&mut self,
1898 child_name_bindings: &NameBindings,
1901 new_parent: ReducedGraphParent) {
1902 debug!("(building reduced graph for \
1903 external crate) building external def, priv {}",
1905 let is_public = vis == ast::Public;
1906 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
1907 let is_exported = is_public && match new_parent {
1908 ModuleReducedGraphParent(ref module) => {
1909 match module.def_id.get() {
1911 Some(did) => self.external_exports.contains(&did)
1916 self.external_exports.insert(def.def_id());
1919 let kind = match def {
1920 DefTy(_, true) => EnumModuleKind,
1921 DefStruct(..) | DefTy(..) => ImplModuleKind,
1922 _ => NormalModuleKind
1926 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1927 DefTy(def_id, _) => {
1928 let type_def = child_name_bindings.type_def.borrow().clone();
1930 Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1931 debug!("(building reduced graph for external crate) \
1932 already created module");
1933 module_def.def_id.set(Some(def_id));
1936 debug!("(building reduced graph for \
1937 external crate) building module \
1939 let parent_link = self.get_parent_link(new_parent.clone(), name);
1941 child_name_bindings.define_module(parent_link,
1954 DefMod(_) | DefForeignMod(_) => {}
1955 DefVariant(_, variant_id, is_struct) => {
1956 debug!("(building reduced graph for external crate) building \
1959 // variants are always treated as importable to allow them to be
1961 let modifiers = PUBLIC | IMPORTABLE;
1963 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
1964 // Not adding fields for variants as they are not accessed with a self receiver
1965 self.structs.insert(variant_id, Vec::new());
1967 child_name_bindings.define_value(def, DUMMY_SP, modifiers);
1970 DefFn(ctor_id, true) => {
1971 child_name_bindings.define_value(
1972 csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
1973 .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
1975 DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
1976 debug!("(building reduced graph for external \
1977 crate) building value (fn/static) {}", final_ident);
1978 // impl methods have already been defined with the correct importability modifier
1979 let mut modifiers = match *child_name_bindings.value_def.borrow() {
1980 Some(ref def) => (modifiers & !IMPORTABLE) | (def.modifiers & IMPORTABLE),
1983 if new_parent.module().kind.get() != NormalModuleKind {
1984 modifiers = modifiers & !IMPORTABLE;
1986 child_name_bindings.define_value(def, DUMMY_SP, modifiers);
1988 DefTrait(def_id) => {
1989 debug!("(building reduced graph for external \
1990 crate) building type {}", final_ident);
1992 // If this is a trait, add all the trait item names to the trait
1995 let trait_item_def_ids =
1996 csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
1997 for trait_item_def_id in trait_item_def_ids.iter() {
1998 let (trait_item_name, trait_item_kind) =
1999 csearch::get_trait_item_name_and_kind(
2000 &self.session.cstore,
2001 trait_item_def_id.def_id());
2003 debug!("(building reduced graph for external crate) ... \
2004 adding trait item '{}'",
2005 token::get_name(trait_item_name));
2007 self.trait_item_map.insert((trait_item_name, def_id), trait_item_kind);
2010 self.external_exports
2011 .insert(trait_item_def_id.def_id());
2015 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
2017 // Define a module if necessary.
2018 let parent_link = self.get_parent_link(new_parent, name);
2019 child_name_bindings.set_module_kind(parent_link,
2026 DefTy(..) | DefAssociatedTy(..) => {
2027 debug!("(building reduced graph for external \
2028 crate) building type {}", final_ident);
2030 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
2032 DefStruct(def_id) => {
2033 debug!("(building reduced graph for external \
2034 crate) building type and value for {}",
2036 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
2037 let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
2039 }).collect::<Vec<_>>();
2041 if fields.len() == 0 {
2042 child_name_bindings.define_value(def, DUMMY_SP, modifiers);
2045 // Record the def ID and fields of this struct.
2046 self.structs.insert(def_id, fields);
2048 DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
2049 DefUse(..) | DefUpvar(..) | DefRegion(..) |
2050 DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
2051 panic!("didn't expect `{}`", def);
2056 /// Builds the reduced graph for a single item in an external crate.
2057 fn build_reduced_graph_for_external_crate_def(&mut self,
2061 visibility: Visibility) {
2064 // Add the new child item, if necessary.
2066 DefForeignMod(def_id) => {
2067 // Foreign modules have no names. Recur and populate
2069 csearch::each_child_of_item(&self.session.cstore,
2074 self.build_reduced_graph_for_external_crate_def(
2082 let child_name_bindings =
2083 self.add_child(name,
2084 ModuleReducedGraphParent(root.clone()),
2085 OverwriteDuplicates,
2088 self.handle_external_def(def,
2090 &*child_name_bindings,
2091 token::get_name(name).get(),
2093 ModuleReducedGraphParent(root));
2098 match csearch::get_type_name_if_impl(&self.session.cstore, def) {
2100 Some(final_name) => {
2102 csearch::get_methods_if_impl(&self.session.cstore, def);
2104 Some(ref methods) if
2105 methods.len() >= 1 => {
2106 debug!("(building reduced graph for \
2107 external crate) processing \
2108 static methods for type name {}",
2109 token::get_name(final_name));
2111 let child_name_bindings =
2114 ModuleReducedGraphParent(root.clone()),
2115 OverwriteDuplicates,
2118 // Process the static methods. First,
2119 // create the module.
2121 let type_def = child_name_bindings.type_def.borrow().clone();
2124 module_def: Some(module_def),
2127 // We already have a module. This
2129 type_module = module_def;
2131 // Mark it as an impl module if
2133 type_module.kind.set(ImplModuleKind);
2137 self.get_parent_link(ModuleReducedGraphParent(root),
2139 child_name_bindings.define_module(
2147 child_name_bindings.
2152 // Add each static method to the module.
2154 ModuleReducedGraphParent(type_module);
2155 for method_info in methods.iter() {
2156 let name = method_info.name;
2157 debug!("(building reduced graph for \
2158 external crate) creating \
2159 static method '{}'",
2160 token::get_name(name));
2162 let method_name_bindings =
2163 self.add_child(name,
2165 OverwriteDuplicates,
2167 let def = DefFn(method_info.def_id, false);
2169 // NB: not IMPORTABLE
2170 let modifiers = if visibility == ast::Public {
2173 DefModifiers::empty()
2175 method_name_bindings.define_value(
2176 def, DUMMY_SP, modifiers);
2180 // Otherwise, do nothing.
2181 Some(_) | None => {}
2187 debug!("(building reduced graph for external crate) \
2193 /// Builds the reduced graph rooted at the given external module.
2194 fn populate_external_module(&mut self, module: Rc<Module>) {
2195 debug!("(populating external module) attempting to populate {}",
2196 self.module_to_string(&*module));
2198 let def_id = match module.def_id.get() {
2200 debug!("(populating external module) ... no def ID!");
2203 Some(def_id) => def_id,
2206 csearch::each_child_of_item(&self.session.cstore,
2208 |def_like, child_name, visibility| {
2209 debug!("(populating external module) ... found ident: {}",
2210 token::get_name(child_name));
2211 self.build_reduced_graph_for_external_crate_def(module.clone(),
2216 module.populated.set(true)
2219 /// Ensures that the reduced graph rooted at the given external module
2220 /// is built, building it if it is not.
2221 fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
2222 if !module.populated.get() {
2223 self.populate_external_module(module.clone())
2225 assert!(module.populated.get())
2228 /// Builds the reduced graph rooted at the 'use' directive for an external
2230 fn build_reduced_graph_for_external_crate(&mut self, root: Rc<Module>) {
2231 csearch::each_top_level_item_of_crate(&self.session.cstore,
2236 |def_like, name, visibility| {
2237 self.build_reduced_graph_for_external_crate_def(root.clone(),
2244 /// Creates and adds an import directive to the given module.
2245 fn build_import_directive(&mut self,
2247 module_path: Vec<Name>,
2248 subclass: ImportDirectiveSubclass,
2253 module_.imports.borrow_mut().push(ImportDirective::new(module_path,
2259 self.unresolved_imports += 1;
2260 // Bump the reference count on the name. Or, if this is a glob, set
2261 // the appropriate flag.
2264 SingleImport(target, _) => {
2265 debug!("(building import directive) building import \
2267 self.names_to_string(module_.imports.borrow().last().unwrap()
2268 .module_path.as_slice()),
2269 token::get_name(target));
2271 let mut import_resolutions = module_.import_resolutions
2273 match import_resolutions.get_mut(&target) {
2274 Some(resolution) => {
2275 debug!("(building import directive) bumping \
2277 resolution.outstanding_references += 1;
2279 // the source of this name is different now
2280 resolution.type_id = id;
2281 resolution.value_id = id;
2282 resolution.is_public = is_public;
2287 debug!("(building import directive) creating new");
2288 let mut resolution = ImportResolution::new(id, is_public);
2289 resolution.outstanding_references = 1;
2290 import_resolutions.insert(target, resolution);
2293 // Set the glob flag. This tells us that we don't know the
2294 // module's exports ahead of time.
2296 module_.glob_count.set(module_.glob_count.get() + 1);
2301 // Import resolution
2303 // This is a fixed-point algorithm. We resolve imports until our efforts
2304 // are stymied by an unresolved import; then we bail out of the current
2305 // module and continue. We terminate successfully once no more imports
2306 // remain or unsuccessfully when no forward progress in resolving imports
2309 /// Resolves all imports for the crate. This method performs the fixed-
2310 /// point iteration.
2311 fn resolve_imports(&mut self) {
2313 let mut prev_unresolved_imports = 0;
2315 debug!("(resolving imports) iteration {}, {} imports left",
2316 i, self.unresolved_imports);
2318 let module_root = self.graph_root.get_module();
2319 self.resolve_imports_for_module_subtree(module_root.clone());
2321 if self.unresolved_imports == 0 {
2322 debug!("(resolving imports) success");
2326 if self.unresolved_imports == prev_unresolved_imports {
2327 self.report_unresolved_imports(module_root);
2332 prev_unresolved_imports = self.unresolved_imports;
2336 /// Attempts to resolve imports for the given module and all of its
2338 fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
2339 debug!("(resolving imports for module subtree) resolving {}",
2340 self.module_to_string(&*module_));
2341 let orig_module = replace(&mut self.current_module, module_.clone());
2342 self.resolve_imports_for_module(module_.clone());
2343 self.current_module = orig_module;
2345 self.populate_module_if_necessary(&module_);
2346 for (_, child_node) in module_.children.borrow().iter() {
2347 match child_node.get_module_if_available() {
2351 Some(child_module) => {
2352 self.resolve_imports_for_module_subtree(child_module);
2357 for (_, child_module) in module_.anonymous_children.borrow().iter() {
2358 self.resolve_imports_for_module_subtree(child_module.clone());
2362 /// Attempts to resolve imports for the given module only.
2363 fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
2364 if module.all_imports_resolved() {
2365 debug!("(resolving imports for module) all imports resolved for \
2367 self.module_to_string(&*module));
2371 let imports = module.imports.borrow();
2372 let import_count = imports.len();
2373 while module.resolved_import_count.get() < import_count {
2374 let import_index = module.resolved_import_count.get();
2375 let import_directive = &(*imports)[import_index];
2376 match self.resolve_import_for_module(module.clone(),
2379 let (span, help) = match err {
2380 Some((span, msg)) => (span, format!(". {}", msg)),
2381 None => (import_directive.span, String::new())
2383 let msg = format!("unresolved import `{}`{}",
2384 self.import_path_to_string(
2385 import_directive.module_path
2387 import_directive.subclass),
2389 self.resolve_error(span, msg.as_slice());
2391 Indeterminate => break, // Bail out. We'll come around next time.
2392 Success(()) => () // Good. Continue.
2395 module.resolved_import_count
2396 .set(module.resolved_import_count.get() + 1);
2400 fn names_to_string(&self, names: &[Name]) -> String {
2401 let mut first = true;
2402 let mut result = String::new();
2403 for name in names.iter() {
2407 result.push_str("::")
2409 result.push_str(token::get_name(*name).get());
2414 fn path_names_to_string(&self, path: &Path) -> String {
2415 let names: Vec<ast::Name> = path.segments
2417 .map(|seg| seg.identifier.name)
2419 self.names_to_string(names.as_slice())
2422 fn import_directive_subclass_to_string(&mut self,
2423 subclass: ImportDirectiveSubclass)
2426 SingleImport(_, source) => {
2427 token::get_name(source).get().to_string()
2429 GlobImport => "*".to_string()
2433 fn import_path_to_string(&mut self,
2435 subclass: ImportDirectiveSubclass)
2437 if names.is_empty() {
2438 self.import_directive_subclass_to_string(subclass)
2441 self.names_to_string(names),
2442 self.import_directive_subclass_to_string(
2443 subclass))).to_string()
2447 /// Attempts to resolve the given import. The return value indicates
2448 /// failure if we're certain the name does not exist, indeterminate if we
2449 /// don't know whether the name exists at the moment due to other
2450 /// currently-unresolved imports, or success if we know the name exists.
2451 /// If successful, the resolved bindings are written into the module.
2452 fn resolve_import_for_module(&mut self,
2453 module_: Rc<Module>,
2454 import_directive: &ImportDirective)
2455 -> ResolveResult<()> {
2456 let mut resolution_result = Failed(None);
2457 let module_path = &import_directive.module_path;
2459 debug!("(resolving import for module) resolving import `{}::...` in \
2461 self.names_to_string(module_path.as_slice()),
2462 self.module_to_string(&*module_));
2464 // First, resolve the module path for the directive, if necessary.
2465 let container = if module_path.len() == 0 {
2466 // Use the crate root.
2467 Some((self.graph_root.get_module(), LastMod(AllPublic)))
2469 match self.resolve_module_path(module_.clone(),
2470 module_path.as_slice(),
2471 DontUseLexicalScope,
2472 import_directive.span,
2475 resolution_result = Failed(err);
2479 resolution_result = Indeterminate;
2482 Success(container) => Some(container),
2488 Some((containing_module, lp)) => {
2489 // We found the module that the target is contained
2490 // within. Attempt to resolve the import within it.
2492 match import_directive.subclass {
2493 SingleImport(target, source) => {
2495 self.resolve_single_import(&*module_,
2504 self.resolve_glob_import(&*module_,
2513 // Decrement the count of unresolved imports.
2514 match resolution_result {
2516 assert!(self.unresolved_imports >= 1);
2517 self.unresolved_imports -= 1;
2520 // Nothing to do here; just return the error.
2524 // Decrement the count of unresolved globs if necessary. But only if
2525 // the resolution result is indeterminate -- otherwise we'll stop
2526 // processing imports here. (See the loop in
2527 // resolve_imports_for_module.)
2529 if !resolution_result.indeterminate() {
2530 match import_directive.subclass {
2532 assert!(module_.glob_count.get() >= 1);
2533 module_.glob_count.set(module_.glob_count.get() - 1);
2535 SingleImport(..) => {
2541 return resolution_result;
2544 fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
2546 type_def: RefCell::new(Some(TypeNsDef {
2547 modifiers: IMPORTABLE,
2548 module_def: Some(module),
2552 value_def: RefCell::new(None),
2556 fn resolve_single_import(&mut self,
2558 containing_module: Rc<Module>,
2561 directive: &ImportDirective,
2563 -> ResolveResult<()> {
2564 debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2565 `{}` id {}, last private {}",
2566 token::get_name(target),
2567 self.module_to_string(&*containing_module),
2568 token::get_name(source),
2569 self.module_to_string(module_),
2575 LastImport {..} => {
2577 .span_bug(directive.span,
2578 "not expecting Import here, must be LastMod")
2582 // We need to resolve both namespaces for this to succeed.
2585 let mut value_result = UnknownResult;
2586 let mut type_result = UnknownResult;
2588 // Search for direct children of the containing module.
2589 self.populate_module_if_necessary(&containing_module);
2591 match containing_module.children.borrow().get(&source) {
2595 Some(ref child_name_bindings) => {
2596 if child_name_bindings.defined_in_namespace(ValueNS) {
2597 debug!("(resolving single import) found value binding");
2598 value_result = BoundResult(containing_module.clone(),
2599 (*child_name_bindings).clone());
2601 if child_name_bindings.defined_in_namespace(TypeNS) {
2602 debug!("(resolving single import) found type binding");
2603 type_result = BoundResult(containing_module.clone(),
2604 (*child_name_bindings).clone());
2609 // Unless we managed to find a result in both namespaces (unlikely),
2610 // search imports as well.
2611 let mut value_used_reexport = false;
2612 let mut type_used_reexport = false;
2613 match (value_result.clone(), type_result.clone()) {
2614 (BoundResult(..), BoundResult(..)) => {} // Continue.
2616 // If there is an unresolved glob at this point in the
2617 // containing module, bail out. We don't know enough to be
2618 // able to resolve this import.
2620 if containing_module.glob_count.get() > 0 {
2621 debug!("(resolving single import) unresolved glob; \
2623 return Indeterminate;
2626 // Now search the exported imports within the containing module.
2627 match containing_module.import_resolutions.borrow().get(&source) {
2629 debug!("(resolving single import) no import");
2630 // The containing module definitely doesn't have an
2631 // exported import with the name in question. We can
2632 // therefore accurately report that the names are
2635 if value_result.is_unknown() {
2636 value_result = UnboundResult;
2638 if type_result.is_unknown() {
2639 type_result = UnboundResult;
2642 Some(import_resolution)
2643 if import_resolution.outstanding_references == 0 => {
2645 fn get_binding(this: &mut Resolver,
2646 import_resolution: &ImportResolution,
2647 namespace: Namespace)
2648 -> NamespaceResult {
2650 // Import resolutions must be declared with "pub"
2651 // in order to be exported.
2652 if !import_resolution.is_public {
2653 return UnboundResult;
2656 match import_resolution.
2657 target_for_namespace(namespace) {
2659 return UnboundResult;
2666 debug!("(resolving single import) found \
2667 import in ns {}", namespace);
2668 let id = import_resolution.id(namespace);
2669 // track used imports and extern crates as well
2670 this.used_imports.insert((id, namespace));
2671 match target_module.def_id.get() {
2672 Some(DefId{krate: kid, ..}) => {
2673 this.used_crates.insert(kid);
2677 return BoundResult(target_module, bindings);
2682 // The name is an import which has been fully
2683 // resolved. We can, therefore, just follow it.
2684 if value_result.is_unknown() {
2685 value_result = get_binding(self, import_resolution,
2687 value_used_reexport = import_resolution.is_public;
2689 if type_result.is_unknown() {
2690 type_result = get_binding(self, import_resolution,
2692 type_used_reexport = import_resolution.is_public;
2697 // If containing_module is the same module whose import we are resolving
2698 // and there it has an unresolved import with the same name as `source`,
2699 // then the user is actually trying to import an item that is declared
2700 // in the same scope
2703 // use self::submodule;
2704 // pub mod submodule;
2706 // In this case we continue as if we resolved the import and let the
2707 // check_for_conflicts_between_imports_and_items call below handle
2709 match (module_.def_id.get(), containing_module.def_id.get()) {
2710 (Some(id1), Some(id2)) if id1 == id2 => {
2711 if value_result.is_unknown() {
2712 value_result = UnboundResult;
2714 if type_result.is_unknown() {
2715 type_result = UnboundResult;
2719 // The import is unresolved. Bail out.
2720 debug!("(resolving single import) unresolved import; \
2722 return Indeterminate;
2730 // If we didn't find a result in the type namespace, search the
2731 // external modules.
2732 let mut value_used_public = false;
2733 let mut type_used_public = false;
2735 BoundResult(..) => {}
2737 match containing_module.external_module_children.borrow_mut()
2738 .get(&source).cloned() {
2739 None => {} // Continue.
2741 debug!("(resolving single import) found external \
2743 // track the module as used.
2744 match module.def_id.get() {
2745 Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
2749 Rc::new(Resolver::create_name_bindings_from_module(
2751 type_result = BoundResult(containing_module.clone(),
2753 type_used_public = true;
2759 // We've successfully resolved the import. Write the results in.
2760 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2761 let import_resolution = &mut (*import_resolutions)[target];
2763 match value_result {
2764 BoundResult(ref target_module, ref name_bindings) => {
2765 debug!("(resolving single import) found value target: {}",
2766 { name_bindings.value_def.borrow().clone().unwrap().def });
2767 self.check_for_conflicting_import(
2768 &import_resolution.value_target,
2773 self.check_that_import_is_importable(
2779 import_resolution.value_target =
2780 Some(Target::new(target_module.clone(),
2781 name_bindings.clone(),
2782 directive.shadowable));
2783 import_resolution.value_id = directive.id;
2784 import_resolution.is_public = directive.is_public;
2785 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2787 UnboundResult => { /* Continue. */ }
2789 panic!("value result should be known at this point");
2793 BoundResult(ref target_module, ref name_bindings) => {
2794 debug!("(resolving single import) found type target: {}",
2795 { name_bindings.type_def.borrow().clone().unwrap().type_def });
2796 self.check_for_conflicting_import(
2797 &import_resolution.type_target,
2802 self.check_that_import_is_importable(
2808 import_resolution.type_target =
2809 Some(Target::new(target_module.clone(),
2810 name_bindings.clone(),
2811 directive.shadowable));
2812 import_resolution.type_id = directive.id;
2813 import_resolution.is_public = directive.is_public;
2814 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2816 UnboundResult => { /* Continue. */ }
2818 panic!("type result should be known at this point");
2822 self.check_for_conflicts_between_imports_and_items(
2828 if value_result.is_unbound() && type_result.is_unbound() {
2829 let msg = format!("There is no `{}` in `{}`",
2830 token::get_name(source),
2831 self.module_to_string(&*containing_module));
2832 return Failed(Some((directive.span, msg)));
2834 let value_used_public = value_used_reexport || value_used_public;
2835 let type_used_public = type_used_reexport || type_used_public;
2837 assert!(import_resolution.outstanding_references >= 1);
2838 import_resolution.outstanding_references -= 1;
2840 // record what this import resolves to for later uses in documentation,
2841 // this may resolve to either a value or a type, but for documentation
2842 // purposes it's good enough to just favor one over the other.
2843 let value_private = match import_resolution.value_target {
2844 Some(ref target) => {
2845 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2846 self.def_map.borrow_mut().insert(directive.id, def);
2847 let did = def.def_id();
2848 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2850 // AllPublic here and below is a dummy value, it should never be used because
2851 // _exists is false.
2854 let type_private = match import_resolution.type_target {
2855 Some(ref target) => {
2856 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2857 self.def_map.borrow_mut().insert(directive.id, def);
2858 let did = def.def_id();
2859 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2864 self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2866 type_priv: type_private,
2869 debug!("(resolving single import) successfully resolved import");
2873 // Resolves a glob import. Note that this function cannot panic; it either
2874 // succeeds or bails out (as importing * from an empty module or a module
2875 // that exports nothing is valid).
2876 fn resolve_glob_import(&mut self,
2878 containing_module: Rc<Module>,
2879 import_directive: &ImportDirective,
2881 -> ResolveResult<()> {
2882 let id = import_directive.id;
2883 let is_public = import_directive.is_public;
2885 // This function works in a highly imperative manner; it eagerly adds
2886 // everything it can to the list of import resolutions of the module
2888 debug!("(resolving glob import) resolving glob import {}", id);
2890 // We must bail out if the node has unresolved imports of any kind
2891 // (including globs).
2892 if !(*containing_module).all_imports_resolved() {
2893 debug!("(resolving glob import) target module has unresolved \
2894 imports; bailing out");
2895 return Indeterminate;
2898 assert_eq!(containing_module.glob_count.get(), 0);
2900 // Add all resolved imports from the containing module.
2901 let import_resolutions = containing_module.import_resolutions
2903 for (ident, target_import_resolution) in import_resolutions.iter() {
2904 debug!("(resolving glob import) writing module resolution \
2906 target_import_resolution.type_target.is_none(),
2907 self.module_to_string(module_));
2909 if !target_import_resolution.is_public {
2910 debug!("(resolving glob import) nevermind, just kidding");
2914 // Here we merge two import resolutions.
2915 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2916 match import_resolutions.get_mut(ident) {
2917 Some(dest_import_resolution) => {
2918 // Merge the two import resolutions at a finer-grained
2921 match target_import_resolution.value_target {
2925 Some(ref value_target) => {
2926 dest_import_resolution.value_target =
2927 Some(value_target.clone());
2930 match target_import_resolution.type_target {
2934 Some(ref type_target) => {
2935 dest_import_resolution.type_target =
2936 Some(type_target.clone());
2939 dest_import_resolution.is_public = is_public;
2945 // Simple: just copy the old import resolution.
2946 let mut new_import_resolution = ImportResolution::new(id, is_public);
2947 new_import_resolution.value_target =
2948 target_import_resolution.value_target.clone();
2949 new_import_resolution.type_target =
2950 target_import_resolution.type_target.clone();
2952 import_resolutions.insert(*ident, new_import_resolution);
2955 // Add all children from the containing module.
2956 self.populate_module_if_necessary(&containing_module);
2958 for (&name, name_bindings) in containing_module.children
2960 self.merge_import_resolution(module_,
2961 containing_module.clone(),
2964 name_bindings.clone());
2968 // Add external module children from the containing module.
2969 for (&name, module) in containing_module.external_module_children
2972 Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
2973 self.merge_import_resolution(module_,
2974 containing_module.clone(),
2980 // Record the destination of this import
2981 match containing_module.def_id.get() {
2983 self.def_map.borrow_mut().insert(id, DefMod(did));
2984 self.last_private.insert(id, lp);
2989 debug!("(resolving glob import) successfully resolved import");
2993 fn merge_import_resolution(&mut self,
2995 containing_module: Rc<Module>,
2996 import_directive: &ImportDirective,
2998 name_bindings: Rc<NameBindings>) {
2999 let id = import_directive.id;
3000 let is_public = import_directive.is_public;
3002 let mut import_resolutions = module_.import_resolutions.borrow_mut();
3003 let dest_import_resolution = match import_resolutions.entry(name) {
3004 Occupied(entry) => entry.into_mut(),
3006 // Create a new import resolution from this child.
3007 entry.set(ImportResolution::new(id, is_public))
3011 debug!("(resolving glob import) writing resolution `{}` in `{}` \
3013 token::get_name(name).get().to_string(),
3014 self.module_to_string(&*containing_module),
3015 self.module_to_string(module_));
3017 // Merge the child item into the import resolution.
3018 if name_bindings.defined_in_namespace_with(ValueNS, IMPORTABLE | PUBLIC) {
3019 debug!("(resolving glob import) ... for value target");
3020 dest_import_resolution.value_target =
3021 Some(Target::new(containing_module.clone(),
3022 name_bindings.clone(),
3023 import_directive.shadowable));
3024 dest_import_resolution.value_id = id;
3026 if name_bindings.defined_in_namespace_with(TypeNS, IMPORTABLE | PUBLIC) {
3027 debug!("(resolving glob import) ... for type target");
3028 dest_import_resolution.type_target =
3029 Some(Target::new(containing_module,
3030 name_bindings.clone(),
3031 import_directive.shadowable));
3032 dest_import_resolution.type_id = id;
3034 dest_import_resolution.is_public = is_public;
3036 self.check_for_conflicts_between_imports_and_items(
3038 dest_import_resolution,
3039 import_directive.span,
3043 /// Checks that imported names and items don't have the same name.
3044 fn check_for_conflicting_import(&mut self,
3045 target: &Option<Target>,
3048 namespace: Namespace) {
3049 if self.session.features.borrow().import_shadowing {
3054 Some(ref target) if !target.shadowable => {
3055 let msg = format!("a {} named `{}` has already been imported \
3061 token::get_name(name).get());
3062 self.session.span_err(import_span, msg.as_slice());
3064 Some(_) | None => {}
3068 /// Checks that an import is actually importable
3069 fn check_that_import_is_importable(&mut self,
3070 name_bindings: &NameBindings,
3073 namespace: Namespace) {
3074 if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
3075 let msg = format!("`{}` is not directly importable",
3076 token::get_name(name));
3077 self.session.span_err(import_span, msg.as_slice());
3081 /// Checks that imported names and items don't have the same name.
3082 fn check_for_conflicts_between_imports_and_items(&mut self,
3088 if self.session.features.borrow().import_shadowing {
3092 // First, check for conflicts between imports and `extern crate`s.
3093 if module.external_module_children
3095 .contains_key(&name) {
3096 match import_resolution.type_target {
3097 Some(ref target) if !target.shadowable => {
3098 let msg = format!("import `{0}` conflicts with imported \
3099 crate in this module \
3100 (maybe you meant `use {0}::*`?)",
3101 token::get_name(name).get());
3102 self.session.span_err(import_span, msg.as_slice());
3104 Some(_) | None => {}
3108 // Check for item conflicts.
3109 let children = module.children.borrow();
3110 let name_bindings = match children.get(&name) {
3112 // There can't be any conflicts.
3115 Some(ref name_bindings) => (*name_bindings).clone(),
3118 match import_resolution.value_target {
3119 Some(ref target) if !target.shadowable => {
3120 if let Some(ref value) = *name_bindings.value_def.borrow() {
3121 let msg = format!("import `{}` conflicts with value \
3123 token::get_name(name).get());
3124 self.session.span_err(import_span, msg.as_slice());
3125 if let Some(span) = value.value_span {
3126 self.session.span_note(span,
3127 "conflicting value here");
3131 Some(_) | None => {}
3134 match import_resolution.type_target {
3135 Some(ref target) if !target.shadowable => {
3136 if let Some(ref ty) = *name_bindings.type_def.borrow() {
3137 match ty.module_def {
3139 let msg = format!("import `{}` conflicts with type in \
3141 token::get_name(name).get());
3142 self.session.span_err(import_span, msg.as_slice());
3143 if let Some(span) = ty.type_span {
3144 self.session.span_note(span,
3145 "note conflicting type here")
3148 Some(ref module_def) => {
3149 match module_def.kind.get() {
3151 if let Some(span) = ty.type_span {
3152 let msg = format!("inherent implementations \
3153 are only allowed on types \
3154 defined in the current module");
3155 self.session.span_err(span, msg.as_slice());
3156 self.session.span_note(import_span,
3157 "import from other module here")
3161 let msg = format!("import `{}` conflicts with existing \
3163 token::get_name(name).get());
3164 self.session.span_err(import_span, msg.as_slice());
3165 if let Some(span) = ty.type_span {
3166 self.session.span_note(span,
3167 "note conflicting module here")
3175 Some(_) | None => {}
3179 /// Checks that the names of external crates don't collide with other
3180 /// external crates.
3181 fn check_for_conflicts_between_external_crates(&self,
3185 if self.session.features.borrow().import_shadowing {
3189 if module.external_module_children.borrow().contains_key(&name) {
3192 format!("an external crate named `{}` has already \
3193 been imported into this module",
3194 token::get_name(name).get()).as_slice());
3198 /// Checks that the names of items don't collide with external crates.
3199 fn check_for_conflicts_between_external_crates_and_items(&self,
3203 if self.session.features.borrow().import_shadowing {
3207 if module.external_module_children.borrow().contains_key(&name) {
3210 format!("the name `{}` conflicts with an external \
3211 crate that has been imported into this \
3213 token::get_name(name).get()).as_slice());
3217 /// Resolves the given module path from the given root `module_`.
3218 fn resolve_module_path_from_root(&mut self,
3219 module_: Rc<Module>,
3220 module_path: &[Name],
3223 name_search_type: NameSearchType,
3225 -> ResolveResult<(Rc<Module>, LastPrivate)> {
3226 fn search_parent_externals(needle: Name, module: &Rc<Module>)
3227 -> Option<Rc<Module>> {
3228 module.external_module_children.borrow()
3229 .get(&needle).cloned()
3230 .map(|_| module.clone())
3232 match module.parent_link.clone() {
3233 ModuleParentLink(parent, _) => {
3234 search_parent_externals(needle,
3235 &parent.upgrade().unwrap())
3242 let mut search_module = module_;
3243 let mut index = index;
3244 let module_path_len = module_path.len();
3245 let mut closest_private = lp;
3247 // Resolve the module part of the path. This does not involve looking
3248 // upward though scope chains; we simply resolve names directly in
3249 // modules as we go.
3250 while index < module_path_len {
3251 let name = module_path[index];
3252 match self.resolve_name_in_module(search_module.clone(),
3258 let segment_name = token::get_name(name);
3259 let module_name = self.module_to_string(&*search_module);
3260 let mut span = span;
3261 let msg = if "???" == module_name.as_slice() {
3262 span.hi = span.lo + Pos::from_uint(segment_name.get().len());
3264 match search_parent_externals(name,
3265 &self.current_module) {
3267 let path_str = self.names_to_string(module_path);
3268 let target_mod_str = self.module_to_string(&*module);
3269 let current_mod_str =
3270 self.module_to_string(&*self.current_module);
3272 let prefix = if target_mod_str == current_mod_str {
3273 "self::".to_string()
3275 format!("{}::", target_mod_str)
3278 format!("Did you mean `{}{}`?", prefix, path_str)
3280 None => format!("Maybe a missing `extern crate {}`?",
3284 format!("Could not find `{}` in `{}`",
3289 return Failed(Some((span, msg)));
3291 Failed(err) => return Failed(err),
3293 debug!("(resolving module path for import) module \
3294 resolution is indeterminate: {}",
3295 token::get_name(name));
3296 return Indeterminate;
3298 Success((target, used_proxy)) => {
3299 // Check to see whether there are type bindings, and, if
3300 // so, whether there is a module within.
3301 match *target.bindings.type_def.borrow() {
3302 Some(ref type_def) => {
3303 match type_def.module_def {
3305 let msg = format!("Not a module `{}`",
3306 token::get_name(name));
3308 return Failed(Some((span, msg)));
3310 Some(ref module_def) => {
3311 search_module = module_def.clone();
3313 // track extern crates for unused_extern_crate lint
3314 if let Some(did) = module_def.def_id.get() {
3315 self.used_crates.insert(did.krate);
3318 // Keep track of the closest
3319 // private module used when
3320 // resolving this import chain.
3321 if !used_proxy && !search_module.is_public {
3322 if let Some(did) = search_module.def_id.get() {
3323 closest_private = LastMod(DependsOn(did));
3330 // There are no type bindings at all.
3331 let msg = format!("Not a module `{}`",
3332 token::get_name(name));
3333 return Failed(Some((span, msg)));
3342 return Success((search_module, closest_private));
3345 /// Attempts to resolve the module part of an import directive or path
3346 /// rooted at the given module.
3348 /// On success, returns the resolved module, and the closest *private*
3349 /// module found to the destination when resolving this path.
3350 fn resolve_module_path(&mut self,
3351 module_: Rc<Module>,
3352 module_path: &[Name],
3353 use_lexical_scope: UseLexicalScopeFlag,
3355 name_search_type: NameSearchType)
3356 -> ResolveResult<(Rc<Module>, LastPrivate)> {
3357 let module_path_len = module_path.len();
3358 assert!(module_path_len > 0);
3360 debug!("(resolving module path for import) processing `{}` rooted at \
3362 self.names_to_string(module_path),
3363 self.module_to_string(&*module_));
3365 // Resolve the module prefix, if any.
3366 let module_prefix_result = self.resolve_module_prefix(module_.clone(),
3372 match module_prefix_result {
3374 let mpath = self.names_to_string(module_path);
3375 let mpath = mpath.as_slice();
3376 match mpath.rfind(':') {
3378 let msg = format!("Could not find `{}` in `{}`",
3379 // idx +- 1 to account for the
3380 // colons on either side
3381 mpath.slice_from(idx + 1),
3382 mpath.slice_to(idx - 1));
3383 return Failed(Some((span, msg)));
3385 None => return Failed(None),
3388 Failed(err) => return Failed(err),
3390 debug!("(resolving module path for import) indeterminate; \
3392 return Indeterminate;
3394 Success(NoPrefixFound) => {
3395 // There was no prefix, so we're considering the first element
3396 // of the path. How we handle this depends on whether we were
3397 // instructed to use lexical scope or not.
3398 match use_lexical_scope {
3399 DontUseLexicalScope => {
3400 // This is a crate-relative path. We will start the
3401 // resolution process at index zero.
3402 search_module = self.graph_root.get_module();
3404 last_private = LastMod(AllPublic);
3406 UseLexicalScope => {
3407 // This is not a crate-relative path. We resolve the
3408 // first component of the path in the current lexical
3409 // scope and then proceed to resolve below that.
3410 match self.resolve_module_in_lexical_scope(
3413 Failed(err) => return Failed(err),
3415 debug!("(resolving module path for import) \
3416 indeterminate; bailing");
3417 return Indeterminate;
3419 Success(containing_module) => {
3420 search_module = containing_module;
3422 last_private = LastMod(AllPublic);
3428 Success(PrefixFound(ref containing_module, index)) => {
3429 search_module = containing_module.clone();
3430 start_index = index;
3431 last_private = LastMod(DependsOn(containing_module.def_id
3437 self.resolve_module_path_from_root(search_module,
3445 /// Invariant: This must only be called during main resolution, not during
3446 /// import resolution.
3447 fn resolve_item_in_lexical_scope(&mut self,
3448 module_: Rc<Module>,
3450 namespace: Namespace)
3451 -> ResolveResult<(Target, bool)> {
3452 debug!("(resolving item in lexical scope) resolving `{}` in \
3453 namespace {} in `{}`",
3454 token::get_name(name),
3456 self.module_to_string(&*module_));
3458 // The current module node is handled specially. First, check for
3459 // its immediate children.
3460 self.populate_module_if_necessary(&module_);
3462 match module_.children.borrow().get(&name) {
3464 if name_bindings.defined_in_namespace(namespace) => {
3465 debug!("top name bindings succeeded");
3466 return Success((Target::new(module_.clone(),
3467 name_bindings.clone(),
3471 Some(_) | None => { /* Not found; continue. */ }
3474 // Now check for its import directives. We don't have to have resolved
3475 // all its imports in the usual way; this is because chains of
3476 // adjacent import statements are processed as though they mutated the
3478 if let Some(import_resolution) = module_.import_resolutions.borrow().get(&name) {
3479 match (*import_resolution).target_for_namespace(namespace) {
3481 // Not found; continue.
3482 debug!("(resolving item in lexical scope) found \
3483 import resolution, but not in namespace {}",
3487 debug!("(resolving item in lexical scope) using \
3488 import resolution");
3489 // track used imports and extern crates as well
3490 self.used_imports.insert((import_resolution.id(namespace), namespace));
3491 if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
3492 self.used_crates.insert(kid);
3494 return Success((target, false));
3499 // Search for external modules.
3500 if namespace == TypeNS {
3501 if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
3503 Rc::new(Resolver::create_name_bindings_from_module(module));
3504 debug!("lower name bindings succeeded");
3505 return Success((Target::new(module_, name_bindings, false),
3510 // Finally, proceed up the scope chain looking for parent modules.
3511 let mut search_module = module_;
3513 // Go to the next parent.
3514 match search_module.parent_link.clone() {
3516 // No more parents. This module was unresolved.
3517 debug!("(resolving item in lexical scope) unresolved \
3519 return Failed(None);
3521 ModuleParentLink(parent_module_node, _) => {
3522 match search_module.kind.get() {
3523 NormalModuleKind => {
3524 // We stop the search here.
3525 debug!("(resolving item in lexical \
3526 scope) unresolved module: not \
3527 searching through module \
3529 return Failed(None);
3534 AnonymousModuleKind => {
3535 search_module = parent_module_node.upgrade().unwrap();
3539 BlockParentLink(ref parent_module_node, _) => {
3540 search_module = parent_module_node.upgrade().unwrap();
3544 // Resolve the name in the parent module.
3545 match self.resolve_name_in_module(search_module.clone(),
3550 Failed(Some((span, msg))) =>
3551 self.resolve_error(span, format!("failed to resolve. {}",
3553 Failed(None) => (), // Continue up the search chain.
3555 // We couldn't see through the higher scope because of an
3556 // unresolved import higher up. Bail.
3558 debug!("(resolving item in lexical scope) indeterminate \
3559 higher scope; bailing");
3560 return Indeterminate;
3562 Success((target, used_reexport)) => {
3563 // We found the module.
3564 debug!("(resolving item in lexical scope) found name \
3566 return Success((target, used_reexport));
3572 /// Resolves a module name in the current lexical scope.
3573 fn resolve_module_in_lexical_scope(&mut self,
3574 module_: Rc<Module>,
3576 -> ResolveResult<Rc<Module>> {
3577 // If this module is an anonymous module, resolve the item in the
3578 // lexical scope. Otherwise, resolve the item from the crate root.
3579 let resolve_result = self.resolve_item_in_lexical_scope(
3580 module_, name, TypeNS);
3581 match resolve_result {
3582 Success((target, _)) => {
3583 let bindings = &*target.bindings;
3584 match *bindings.type_def.borrow() {
3585 Some(ref type_def) => {
3586 match type_def.module_def {
3588 debug!("!!! (resolving module in lexical \
3589 scope) module wasn't actually a \
3591 return Failed(None);
3593 Some(ref module_def) => {
3594 return Success(module_def.clone());
3599 debug!("!!! (resolving module in lexical scope) module
3600 wasn't actually a module!");
3601 return Failed(None);
3606 debug!("(resolving module in lexical scope) indeterminate; \
3608 return Indeterminate;
3611 debug!("(resolving module in lexical scope) failed to resolve");
3617 /// Returns the nearest normal module parent of the given module.
3618 fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
3619 -> Option<Rc<Module>> {
3620 let mut module_ = module_;
3622 match module_.parent_link.clone() {
3623 NoParentLink => return None,
3624 ModuleParentLink(new_module, _) |
3625 BlockParentLink(new_module, _) => {
3626 let new_module = new_module.upgrade().unwrap();
3627 match new_module.kind.get() {
3628 NormalModuleKind => return Some(new_module),
3632 AnonymousModuleKind => module_ = new_module,
3639 /// Returns the nearest normal module parent of the given module, or the
3640 /// module itself if it is a normal module.
3641 fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
3643 match module_.kind.get() {
3644 NormalModuleKind => return module_,
3648 AnonymousModuleKind => {
3649 match self.get_nearest_normal_module_parent(module_.clone()) {
3651 Some(new_module) => new_module
3657 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3658 /// (b) some chain of `super::`.
3659 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3660 fn resolve_module_prefix(&mut self,
3661 module_: Rc<Module>,
3662 module_path: &[Name])
3663 -> ResolveResult<ModulePrefixResult> {
3664 // Start at the current module if we see `self` or `super`, or at the
3665 // top of the crate otherwise.
3666 let mut containing_module;
3668 let first_module_path_string = token::get_name(module_path[0]);
3669 if "self" == first_module_path_string.get() {
3671 self.get_nearest_normal_module_parent_or_self(module_);
3673 } else if "super" == first_module_path_string.get() {
3675 self.get_nearest_normal_module_parent_or_self(module_);
3676 i = 0; // We'll handle `super` below.
3678 return Success(NoPrefixFound);
3681 // Now loop through all the `super`s we find.
3682 while i < module_path.len() {
3683 let string = token::get_name(module_path[i]);
3684 if "super" != string.get() {
3687 debug!("(resolving module prefix) resolving `super` at {}",
3688 self.module_to_string(&*containing_module));
3689 match self.get_nearest_normal_module_parent(containing_module) {
3690 None => return Failed(None),
3691 Some(new_module) => {
3692 containing_module = new_module;
3698 debug!("(resolving module prefix) finished resolving prefix at {}",
3699 self.module_to_string(&*containing_module));
3701 return Success(PrefixFound(containing_module, i));
3704 /// Attempts to resolve the supplied name in the given module for the
3705 /// given namespace. If successful, returns the target corresponding to
3708 /// The boolean returned on success is an indicator of whether this lookup
3709 /// passed through a public re-export proxy.
3710 fn resolve_name_in_module(&mut self,
3711 module_: Rc<Module>,
3713 namespace: Namespace,
3714 name_search_type: NameSearchType,
3715 allow_private_imports: bool)
3716 -> ResolveResult<(Target, bool)> {
3717 debug!("(resolving name in module) resolving `{}` in `{}`",
3718 token::get_name(name).get(),
3719 self.module_to_string(&*module_));
3721 // First, check the direct children of the module.
3722 self.populate_module_if_necessary(&module_);
3724 match module_.children.borrow().get(&name) {
3726 if name_bindings.defined_in_namespace(namespace) => {
3727 debug!("(resolving name in module) found node as child");
3728 return Success((Target::new(module_.clone(),
3729 name_bindings.clone(),
3738 // Next, check the module's imports if necessary.
3740 // If this is a search of all imports, we should be done with glob
3741 // resolution at this point.
3742 if name_search_type == PathSearch {
3743 assert_eq!(module_.glob_count.get(), 0);
3746 // Check the list of resolved imports.
3747 match module_.import_resolutions.borrow().get(&name) {
3748 Some(import_resolution) if allow_private_imports ||
3749 import_resolution.is_public => {
3751 if import_resolution.is_public &&
3752 import_resolution.outstanding_references != 0 {
3753 debug!("(resolving name in module) import \
3754 unresolved; bailing out");
3755 return Indeterminate;
3757 match import_resolution.target_for_namespace(namespace) {
3759 debug!("(resolving name in module) name found, \
3760 but not in namespace {}",
3764 debug!("(resolving name in module) resolved to \
3766 // track used imports and extern crates as well
3767 self.used_imports.insert((import_resolution.id(namespace), namespace));
3768 if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
3769 self.used_crates.insert(kid);
3771 return Success((target, true));
3775 Some(..) | None => {} // Continue.
3778 // Finally, search through external children.
3779 if namespace == TypeNS {
3780 if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
3782 Rc::new(Resolver::create_name_bindings_from_module(module));
3783 return Success((Target::new(module_, name_bindings, false),
3788 // We're out of luck.
3789 debug!("(resolving name in module) failed to resolve `{}`",
3790 token::get_name(name).get());
3791 return Failed(None);
3794 fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
3795 let index = module_.resolved_import_count.get();
3796 let imports = module_.imports.borrow();
3797 let import_count = imports.len();
3798 if index != import_count {
3799 let sn = self.session
3801 .span_to_snippet((*imports)[index].span)
3803 if sn.contains("::") {
3804 self.resolve_error((*imports)[index].span,
3805 "unresolved import");
3807 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3808 sn.slice(0, sn.len()));
3809 self.resolve_error((*imports)[index].span, err.as_slice());
3813 // Descend into children and anonymous children.
3814 self.populate_module_if_necessary(&module_);
3816 for (_, child_node) in module_.children.borrow().iter() {
3817 match child_node.get_module_if_available() {
3821 Some(child_module) => {
3822 self.report_unresolved_imports(child_module);
3827 for (_, module_) in module_.anonymous_children.borrow().iter() {
3828 self.report_unresolved_imports(module_.clone());
3834 // This pass simply determines what all "export" keywords refer to and
3835 // writes the results into the export map.
3837 // FIXME #4953 This pass will be removed once exports change to per-item.
3838 // Then this operation can simply be performed as part of item (or import)
3841 fn record_exports(&mut self) {
3842 let root_module = self.graph_root.get_module();
3843 self.record_exports_for_module_subtree(root_module);
3846 fn record_exports_for_module_subtree(&mut self,
3847 module_: Rc<Module>) {
3848 // If this isn't a local krate, then bail out. We don't need to record
3849 // exports for nonlocal crates.
3851 match module_.def_id.get() {
3852 Some(def_id) if def_id.krate == LOCAL_CRATE => {
3854 debug!("(recording exports for module subtree) recording \
3855 exports for local module `{}`",
3856 self.module_to_string(&*module_));
3859 // Record exports for the root module.
3860 debug!("(recording exports for module subtree) recording \
3861 exports for root module `{}`",
3862 self.module_to_string(&*module_));
3866 debug!("(recording exports for module subtree) not recording \
3868 self.module_to_string(&*module_));
3873 self.record_exports_for_module(&*module_);
3874 self.populate_module_if_necessary(&module_);
3876 for (_, child_name_bindings) in module_.children.borrow().iter() {
3877 match child_name_bindings.get_module_if_available() {
3881 Some(child_module) => {
3882 self.record_exports_for_module_subtree(child_module);
3887 for (_, child_module) in module_.anonymous_children.borrow().iter() {
3888 self.record_exports_for_module_subtree(child_module.clone());
3892 fn record_exports_for_module(&mut self, module_: &Module) {
3893 let mut exports2 = Vec::new();
3895 self.add_exports_for_module(&mut exports2, module_);
3896 match module_.def_id.get() {
3898 self.export_map2.insert(def_id.node, exports2);
3899 debug!("(computing exports) writing exports for {} (some)",
3906 fn add_exports_of_namebindings(&mut self,
3907 exports2: &mut Vec<Export2> ,
3909 namebindings: &NameBindings,
3911 match namebindings.def_for_namespace(ns) {
3913 let name = token::get_name(name);
3914 debug!("(computing exports) YES: export '{}' => {}",
3916 exports2.push(Export2 {
3917 name: name.get().to_string(),
3922 debug!("(computing exports) NO: {}", d_opt);
3927 fn add_exports_for_module(&mut self,
3928 exports2: &mut Vec<Export2> ,
3930 for (name, importresolution) in module_.import_resolutions.borrow().iter() {
3931 if !importresolution.is_public {
3934 let xs = [TypeNS, ValueNS];
3935 for &ns in xs.iter() {
3936 match importresolution.target_for_namespace(ns) {
3938 debug!("(computing exports) maybe export '{}'",
3939 token::get_name(*name));
3940 self.add_exports_of_namebindings(exports2,
3953 // We maintain a list of value ribs and type ribs.
3955 // Simultaneously, we keep track of the current position in the module
3956 // graph in the `current_module` pointer. When we go to resolve a name in
3957 // the value or type namespaces, we first look through all the ribs and
3958 // then query the module graph. When we resolve a name in the module
3959 // namespace, we can skip all the ribs (since nested modules are not
3960 // allowed within blocks in Rust) and jump straight to the current module
3963 // Named implementations are handled separately. When we find a method
3964 // call, we consult the module node to find all of the implementations in
3965 // scope. This information is lazily cached in the module node. We then
3966 // generate a fake "implementation scope" containing all the
3967 // implementations thus found, for compatibility with old resolve pass.
3969 fn with_scope(&mut self, name: Option<Name>, f: |&mut Resolver|) {
3970 let orig_module = self.current_module.clone();
3972 // Move down in the graph.
3978 self.populate_module_if_necessary(&orig_module);
3980 match orig_module.children.borrow().get(&name) {
3982 debug!("!!! (with scope) didn't find `{}` in `{}`",
3983 token::get_name(name),
3984 self.module_to_string(&*orig_module));
3986 Some(name_bindings) => {
3987 match (*name_bindings).get_module_if_available() {
3989 debug!("!!! (with scope) didn't find module \
3991 token::get_name(name),
3992 self.module_to_string(&*orig_module));
3995 self.current_module = module_;
4005 self.current_module = orig_module;
4008 /// Wraps the given definition in the appropriate number of `DefUpvar`
4014 -> Option<DefLike> {
4016 DlDef(d @ DefUpvar(..)) => {
4017 self.session.span_bug(span,
4018 format!("unexpected {} in bindings", d).as_slice())
4020 DlDef(d @ DefLocal(_)) => {
4021 let node_id = d.def_id().node;
4023 let mut last_proc_body_id = ast::DUMMY_NODE_ID;
4024 for rib in ribs.iter() {
4027 // Nothing to do. Continue.
4029 ClosureRibKind(function_id, maybe_proc_body) => {
4031 if maybe_proc_body != ast::DUMMY_NODE_ID {
4032 last_proc_body_id = maybe_proc_body;
4034 def = DefUpvar(node_id, function_id, last_proc_body_id);
4036 let mut seen = self.freevars_seen.borrow_mut();
4037 let seen = match seen.entry(function_id) {
4038 Occupied(v) => v.into_mut(),
4039 Vacant(v) => v.set(NodeSet::new()),
4041 if seen.contains(&node_id) {
4044 match self.freevars.borrow_mut().entry(function_id) {
4045 Occupied(v) => v.into_mut(),
4046 Vacant(v) => v.set(vec![]),
4047 }.push(Freevar { def: prev_def, span: span });
4048 seen.insert(node_id);
4050 MethodRibKind(item_id, _) => {
4051 // If the def is a ty param, and came from the parent
4054 DefTyParam(_, did, _) if {
4055 self.def_map.borrow().get(&did.node).cloned()
4056 == Some(DefTyParamBinder(item_id))
4058 DefSelfTy(did) if did == item_id => {} // ok
4060 // This was an attempt to access an upvar inside a
4061 // named function item. This is not allowed, so we
4066 "can't capture dynamic environment in a fn item; \
4067 use the || { ... } closure form instead");
4074 // This was an attempt to access an upvar inside a
4075 // named function item. This is not allowed, so we
4080 "can't capture dynamic environment in a fn item; \
4081 use the || { ... } closure form instead");
4085 ConstantItemRibKind => {
4086 // Still doesn't deal with upvars
4087 self.resolve_error(span,
4088 "attempt to use a non-constant \
4089 value in a constant");
4096 DlDef(def @ DefTyParam(..)) |
4097 DlDef(def @ DefSelfTy(..)) => {
4098 for rib in ribs.iter() {
4100 NormalRibKind | ClosureRibKind(..) => {
4101 // Nothing to do. Continue.
4103 MethodRibKind(item_id, _) => {
4104 // If the def is a ty param, and came from the parent
4107 DefTyParam(_, did, _) if {
4108 self.def_map.borrow().get(&did.node).cloned()
4109 == Some(DefTyParamBinder(item_id))
4111 DefSelfTy(did) if did == item_id => {} // ok
4114 // This was an attempt to use a type parameter outside
4117 self.resolve_error(span,
4118 "can't use type parameters from \
4119 outer function; try using a local \
4120 type parameter instead");
4127 // This was an attempt to use a type parameter outside
4130 self.resolve_error(span,
4131 "can't use type parameters from \
4132 outer function; try using a local \
4133 type parameter instead");
4137 ConstantItemRibKind => {
4139 self.resolve_error(span,
4140 "cannot use an outer type \
4141 parameter in this context");
4152 fn search_ribs(&self,
4156 -> Option<DefLike> {
4157 // FIXME #4950: Try caching?
4159 for (i, rib) in ribs.iter().enumerate().rev() {
4160 match rib.bindings.get(&name).cloned() {
4162 return self.upvarify(ribs[i + 1..], def_like, span);
4173 fn resolve_crate(&mut self, krate: &ast::Crate) {
4174 debug!("(resolving crate) starting");
4176 visit::walk_crate(self, krate);
4179 fn resolve_item(&mut self, item: &Item) {
4180 let name = item.ident.name;
4182 debug!("(resolving item) resolving {}",
4183 token::get_name(name));
4187 // enum item: resolve all the variants' discrs,
4188 // then resolve the ty params
4189 ItemEnum(ref enum_def, ref generics) => {
4190 for variant in (*enum_def).variants.iter() {
4191 for dis_expr in variant.node.disr_expr.iter() {
4192 // resolve the discriminator expr
4194 self.with_constant_rib(|this| {
4195 this.resolve_expr(&**dis_expr);
4200 // n.b. the discr expr gets visited twice.
4201 // but maybe it's okay since the first time will signal an
4202 // error if there is one? -- tjc
4203 self.with_type_parameter_rib(HasTypeParameters(generics,
4208 this.resolve_type_parameters(&generics.ty_params);
4209 this.resolve_where_clause(&generics.where_clause);
4210 visit::walk_item(this, item);
4214 ItemTy(_, ref generics) => {
4215 self.with_type_parameter_rib(HasTypeParameters(generics,
4220 this.resolve_type_parameters(&generics.ty_params);
4221 visit::walk_item(this, item);
4225 ItemImpl(ref generics,
4226 ref implemented_traits,
4228 ref impl_items) => {
4229 self.resolve_implementation(item.id,
4233 impl_items.as_slice());
4236 ItemTrait(ref generics, ref unbound, ref bounds, ref trait_items) => {
4237 // Create a new rib for the self type.
4238 let mut self_type_rib = Rib::new(ItemRibKind);
4240 // plain insert (no renaming, types are not currently hygienic....)
4241 let name = self.type_self_name;
4242 self_type_rib.bindings.insert(name, DlDef(DefSelfTy(item.id)));
4243 self.type_ribs.push(self_type_rib);
4245 // Create a new rib for the trait-wide type parameters.
4246 self.with_type_parameter_rib(HasTypeParameters(generics,
4251 this.resolve_type_parameters(&generics.ty_params);
4252 this.resolve_where_clause(&generics.where_clause);
4254 this.resolve_type_parameter_bounds(item.id, bounds,
4259 this.resolve_trait_reference(item.id, tpb, TraitDerivation);
4264 for trait_item in (*trait_items).iter() {
4265 // Create a new rib for the trait_item-specific type
4268 // FIXME #4951: Do we need a node ID here?
4271 ast::RequiredMethod(ref ty_m) => {
4272 this.with_type_parameter_rib
4273 (HasTypeParameters(&ty_m.generics,
4276 MethodRibKind(item.id, RequiredMethod)),
4279 // Resolve the method-specific type
4281 this.resolve_type_parameters(
4282 &ty_m.generics.ty_params);
4283 this.resolve_where_clause(&ty_m.generics
4286 for argument in ty_m.decl.inputs.iter() {
4287 this.resolve_type(&*argument.ty);
4290 if let SelfExplicit(ref typ, _) = ty_m.explicit_self.node {
4291 this.resolve_type(&**typ)
4294 if let ast::Return(ref ret_ty) = ty_m.decl.output {
4295 this.resolve_type(&**ret_ty);
4299 ast::ProvidedMethod(ref m) => {
4300 this.resolve_method(MethodRibKind(item.id,
4301 ProvidedMethod(m.id)),
4304 ast::TypeTraitItem(ref data) => {
4305 this.resolve_type_parameter(&data.ty_param);
4306 visit::walk_trait_item(this, trait_item);
4312 self.type_ribs.pop();
4315 ItemStruct(ref struct_def, ref generics) => {
4316 self.resolve_struct(item.id,
4318 struct_def.fields.as_slice());
4321 ItemMod(ref module_) => {
4322 self.with_scope(Some(name), |this| {
4323 this.resolve_module(module_, item.span, name,
4328 ItemForeignMod(ref foreign_module) => {
4329 self.with_scope(Some(name), |this| {
4330 for foreign_item in foreign_module.items.iter() {
4331 match foreign_item.node {
4332 ForeignItemFn(_, ref generics) => {
4333 this.with_type_parameter_rib(
4335 generics, FnSpace, foreign_item.id,
4337 |this| visit::walk_foreign_item(this,
4340 ForeignItemStatic(..) => {
4341 visit::walk_foreign_item(this,
4349 ItemFn(ref fn_decl, _, _, ref generics, ref block) => {
4350 self.resolve_function(ItemRibKind,
4360 ItemConst(..) | ItemStatic(..) => {
4361 self.with_constant_rib(|this| {
4362 visit::walk_item(this, item);
4367 // do nothing, these are just around to be encoded
4372 fn with_type_parameter_rib(&mut self,
4373 type_parameters: TypeParameters,
4374 f: |&mut Resolver|) {
4375 match type_parameters {
4376 HasTypeParameters(generics, space, node_id, rib_kind) => {
4377 let mut function_type_rib = Rib::new(rib_kind);
4378 let mut seen_bindings = HashSet::new();
4379 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
4380 let name = type_parameter.ident.name;
4381 debug!("with_type_parameter_rib: {} {}", node_id,
4384 if seen_bindings.contains(&name) {
4385 self.resolve_error(type_parameter.span,
4386 format!("the name `{}` is already \
4388 parameter in this type \
4393 seen_bindings.insert(name);
4395 let def_like = DlDef(DefTyParam(space,
4396 local_def(type_parameter.id),
4398 // Associate this type parameter with
4399 // the item that bound it
4400 self.record_def(type_parameter.id,
4401 (DefTyParamBinder(node_id), LastMod(AllPublic)));
4402 // plain insert (no renaming)
4403 function_type_rib.bindings.insert(name, def_like);
4405 self.type_ribs.push(function_type_rib);
4408 NoTypeParameters => {
4415 match type_parameters {
4416 HasTypeParameters(..) => { self.type_ribs.pop(); }
4417 NoTypeParameters => { }
4421 fn with_label_rib(&mut self, f: |&mut Resolver|) {
4422 self.label_ribs.push(Rib::new(NormalRibKind));
4424 self.label_ribs.pop();
4427 fn with_constant_rib(&mut self, f: |&mut Resolver|) {
4428 self.value_ribs.push(Rib::new(ConstantItemRibKind));
4429 self.type_ribs.push(Rib::new(ConstantItemRibKind));
4431 self.type_ribs.pop();
4432 self.value_ribs.pop();
4435 fn resolve_function(&mut self,
4437 optional_declaration: Option<&FnDecl>,
4438 type_parameters: TypeParameters,
4440 // Create a value rib for the function.
4441 let function_value_rib = Rib::new(rib_kind);
4442 self.value_ribs.push(function_value_rib);
4444 // Create a label rib for the function.
4445 let function_label_rib = Rib::new(rib_kind);
4446 self.label_ribs.push(function_label_rib);
4448 // If this function has type parameters, add them now.
4449 self.with_type_parameter_rib(type_parameters, |this| {
4450 // Resolve the type parameters.
4451 match type_parameters {
4452 NoTypeParameters => {
4455 HasTypeParameters(ref generics, _, _, _) => {
4456 this.resolve_type_parameters(&generics.ty_params);
4457 this.resolve_where_clause(&generics.where_clause);
4461 // Add each argument to the rib.
4462 match optional_declaration {
4466 Some(declaration) => {
4467 let mut bindings_list = HashMap::new();
4468 for argument in declaration.inputs.iter() {
4469 this.resolve_pattern(&*argument.pat,
4470 ArgumentIrrefutableMode,
4471 &mut bindings_list);
4473 this.resolve_type(&*argument.ty);
4475 debug!("(resolving function) recorded argument");
4478 if let ast::Return(ref ret_ty) = declaration.output {
4479 this.resolve_type(&**ret_ty);
4484 // Resolve the function body.
4485 this.resolve_block(&*block);
4487 debug!("(resolving function) leaving function");
4490 self.label_ribs.pop();
4491 self.value_ribs.pop();
4494 fn resolve_type_parameters(&mut self,
4495 type_parameters: &OwnedSlice<TyParam>) {
4496 for type_parameter in type_parameters.iter() {
4497 self.resolve_type_parameter(type_parameter);
4501 fn resolve_type_parameter(&mut self,
4502 type_parameter: &TyParam) {
4503 for bound in type_parameter.bounds.iter() {
4504 self.resolve_type_parameter_bound(type_parameter.id, bound,
4505 TraitBoundingTypeParameter);
4507 match &type_parameter.unbound {
4508 &Some(ref unbound) =>
4509 self.resolve_trait_reference(
4510 type_parameter.id, unbound, TraitBoundingTypeParameter),
4513 match type_parameter.default {
4514 Some(ref ty) => self.resolve_type(&**ty),
4519 fn resolve_type_parameter_bounds(&mut self,
4521 type_parameter_bounds: &OwnedSlice<TyParamBound>,
4522 reference_type: TraitReferenceType) {
4523 for type_parameter_bound in type_parameter_bounds.iter() {
4524 self.resolve_type_parameter_bound(id, type_parameter_bound,
4529 fn resolve_type_parameter_bound(&mut self,
4531 type_parameter_bound: &TyParamBound,
4532 reference_type: TraitReferenceType) {
4533 match *type_parameter_bound {
4534 TraitTyParamBound(ref tref) => {
4535 self.resolve_poly_trait_reference(id, tref, reference_type)
4537 RegionTyParamBound(..) => {}
4541 fn resolve_poly_trait_reference(&mut self,
4543 poly_trait_reference: &PolyTraitRef,
4544 reference_type: TraitReferenceType) {
4545 self.resolve_trait_reference(id, &poly_trait_reference.trait_ref, reference_type)
4548 fn resolve_trait_reference(&mut self,
4550 trait_reference: &TraitRef,
4551 reference_type: TraitReferenceType) {
4552 match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
4554 let path_str = self.path_names_to_string(&trait_reference.path);
4555 let usage_str = match reference_type {
4556 TraitBoundingTypeParameter => "bound type parameter with",
4557 TraitImplementation => "implement",
4558 TraitDerivation => "derive",
4559 TraitObject => "reference",
4560 TraitQPath => "extract an associated type from",
4563 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
4564 self.resolve_error(trait_reference.path.span, msg.as_slice());
4568 (DefTrait(_), _) => {
4569 debug!("(resolving trait) found trait def: {}", def);
4570 self.record_def(trait_reference.ref_id, def);
4573 self.resolve_error(trait_reference.path.span,
4574 format!("`{}` is not a trait",
4575 self.path_names_to_string(
4576 &trait_reference.path)));
4578 // If it's a typedef, give a note
4579 if let DefTy(..) = def {
4580 self.session.span_note(
4581 trait_reference.path.span,
4582 format!("`type` aliases cannot be used for traits")
4591 fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
4592 for predicate in where_clause.predicates.iter() {
4593 match self.resolve_identifier(predicate.ident,
4597 Some((def @ DefTyParam(_, _, _), last_private)) => {
4598 self.record_def(predicate.id, (def, last_private));
4603 format!("undeclared type parameter `{}`",
4605 predicate.ident)).as_slice());
4609 for bound in predicate.bounds.iter() {
4610 self.resolve_type_parameter_bound(predicate.id, bound,
4611 TraitBoundingTypeParameter);
4616 fn resolve_struct(&mut self,
4618 generics: &Generics,
4619 fields: &[StructField]) {
4620 // If applicable, create a rib for the type parameters.
4621 self.with_type_parameter_rib(HasTypeParameters(generics,
4626 // Resolve the type parameters.
4627 this.resolve_type_parameters(&generics.ty_params);
4628 this.resolve_where_clause(&generics.where_clause);
4631 for field in fields.iter() {
4632 this.resolve_type(&*field.node.ty);
4637 // Does this really need to take a RibKind or is it always going
4638 // to be NormalRibKind?
4639 fn resolve_method(&mut self,
4641 method: &ast::Method) {
4642 let method_generics = method.pe_generics();
4643 let type_parameters = HasTypeParameters(method_generics,
4648 if let SelfExplicit(ref typ, _) = method.pe_explicit_self().node {
4649 self.resolve_type(&**typ);
4652 self.resolve_function(rib_kind,
4653 Some(method.pe_fn_decl()),
4658 fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
4659 // Handle nested impls (inside fn bodies)
4660 let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
4661 let result = f(self);
4662 self.current_self_type = previous_value;
4666 fn with_optional_trait_ref<T>(&mut self, id: NodeId,
4667 opt_trait_ref: &Option<TraitRef>,
4668 f: |&mut Resolver| -> T) -> T {
4669 let new_val = match *opt_trait_ref {
4670 Some(ref trait_ref) => {
4671 self.resolve_trait_reference(id, trait_ref, TraitImplementation);
4673 match self.def_map.borrow().get(&trait_ref.ref_id) {
4675 let did = def.def_id();
4676 Some((did, trait_ref.clone()))
4683 let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
4684 let result = f(self);
4685 self.current_trait_ref = original_trait_ref;
4689 fn resolve_implementation(&mut self,
4691 generics: &Generics,
4692 opt_trait_reference: &Option<TraitRef>,
4694 impl_items: &[ImplItem]) {
4695 // If applicable, create a rib for the type parameters.
4696 self.with_type_parameter_rib(HasTypeParameters(generics,
4701 // Resolve the type parameters.
4702 this.resolve_type_parameters(&generics.ty_params);
4703 this.resolve_where_clause(&generics.where_clause);
4705 // Resolve the trait reference, if necessary.
4706 this.with_optional_trait_ref(id, opt_trait_reference, |this| {
4707 // Resolve the self type.
4708 this.resolve_type(self_type);
4710 this.with_current_self_type(self_type, |this| {
4711 for impl_item in impl_items.iter() {
4713 MethodImplItem(ref method) => {
4714 // If this is a trait impl, ensure the method
4716 this.check_trait_item(method.pe_ident().name,
4719 // We also need a new scope for the method-
4720 // specific type parameters.
4721 this.resolve_method(
4722 MethodRibKind(id, ProvidedMethod(method.id)),
4725 TypeImplItem(ref typedef) => {
4726 // If this is a trait impl, ensure the method
4728 this.check_trait_item(typedef.ident.name,
4731 this.resolve_type(&*typedef.typ);
4739 // Check that the current type is indeed a type, if we have an anonymous impl
4740 if opt_trait_reference.is_none() {
4741 match self_type.node {
4742 // TyPath is the only thing that we handled in `build_reduced_graph_for_item`,
4743 // where we created a module with the name of the type in order to implement
4744 // an anonymous trait. In the case that the path does not resolve to an actual
4745 // type, the result will be that the type name resolves to a module but not
4746 // a type (shadowing any imported modules or types with this name), leading
4747 // to weird user-visible bugs. So we ward this off here. See #15060.
4748 TyPath(ref path, path_id) => {
4749 match self.def_map.borrow().get(&path_id) {
4750 // FIXME: should we catch other options and give more precise errors?
4751 Some(&DefMod(_)) => {
4752 self.resolve_error(path.span, "inherent implementations are not \
4753 allowed for types not defined in \
4754 the current module");
4764 fn check_trait_item(&self, name: Name, span: Span) {
4765 // If there is a TraitRef in scope for an impl, then the method must be in the trait.
4766 for &(did, ref trait_ref) in self.current_trait_ref.iter() {
4767 if self.trait_item_map.get(&(name, did)).is_none() {
4768 let path_str = self.path_names_to_string(&trait_ref.path);
4769 self.resolve_error(span,
4770 format!("method `{}` is not a member of trait `{}`",
4771 token::get_name(name),
4772 path_str).as_slice());
4777 fn resolve_module(&mut self, module: &Mod, _span: Span,
4778 _name: Name, id: NodeId) {
4779 // Write the implementations in scope into the module metadata.
4780 debug!("(resolving module) resolving module ID {}", id);
4781 visit::walk_mod(self, module);
4784 fn resolve_local(&mut self, local: &Local) {
4785 // Resolve the type.
4786 self.resolve_type(&*local.ty);
4788 // Resolve the initializer, if necessary.
4793 Some(ref initializer) => {
4794 self.resolve_expr(&**initializer);
4798 // Resolve the pattern.
4799 let mut bindings_list = HashMap::new();
4800 self.resolve_pattern(&*local.pat,
4801 LocalIrrefutableMode,
4802 &mut bindings_list);
4805 // build a map from pattern identifiers to binding-info's.
4806 // this is done hygienically. This could arise for a macro
4807 // that expands into an or-pattern where one 'x' was from the
4808 // user and one 'x' came from the macro.
4809 fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
4810 let mut result = HashMap::new();
4811 pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
4812 let name = mtwt::resolve(path1.node);
4814 binding_info {span: sp,
4815 binding_mode: binding_mode});
4820 // check that all of the arms in an or-pattern have exactly the
4821 // same set of bindings, with the same binding modes for each.
4822 fn check_consistent_bindings(&mut self, arm: &Arm) {
4823 if arm.pats.len() == 0 {
4826 let map_0 = self.binding_mode_map(&*arm.pats[0]);
4827 for (i, p) in arm.pats.iter().enumerate() {
4828 let map_i = self.binding_mode_map(&**p);
4830 for (&key, &binding_0) in map_0.iter() {
4831 match map_i.get(&key) {
4835 format!("variable `{}` from pattern #1 is \
4836 not bound in pattern #{}",
4837 token::get_name(key),
4840 Some(binding_i) => {
4841 if binding_0.binding_mode != binding_i.binding_mode {
4844 format!("variable `{}` is bound with different \
4845 mode in pattern #{} than in pattern #1",
4846 token::get_name(key),
4853 for (&key, &binding) in map_i.iter() {
4854 if !map_0.contains_key(&key) {
4857 format!("variable `{}` from pattern {}{} is \
4858 not bound in pattern {}1",
4859 token::get_name(key),
4860 "#", i + 1, "#").as_slice());
4866 fn resolve_arm(&mut self, arm: &Arm) {
4867 self.value_ribs.push(Rib::new(NormalRibKind));
4869 let mut bindings_list = HashMap::new();
4870 for pattern in arm.pats.iter() {
4871 self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
4874 // This has to happen *after* we determine which
4875 // pat_idents are variants
4876 self.check_consistent_bindings(arm);
4878 visit::walk_expr_opt(self, &arm.guard);
4879 self.resolve_expr(&*arm.body);
4881 self.value_ribs.pop();
4884 fn resolve_block(&mut self, block: &Block) {
4885 debug!("(resolving block) entering block");
4886 self.value_ribs.push(Rib::new(NormalRibKind));
4888 // Move down in the graph, if there's an anonymous module rooted here.
4889 let orig_module = self.current_module.clone();
4890 match orig_module.anonymous_children.borrow().get(&block.id) {
4891 None => { /* Nothing to do. */ }
4892 Some(anonymous_module) => {
4893 debug!("(resolving block) found anonymous module, moving \
4895 self.current_module = anonymous_module.clone();
4899 // Descend into the block.
4900 visit::walk_block(self, block);
4903 self.current_module = orig_module;
4905 self.value_ribs.pop();
4906 debug!("(resolving block) leaving block");
4909 fn resolve_type(&mut self, ty: &Ty) {
4911 // Like path expressions, the interpretation of path types depends
4912 // on whether the path has multiple elements in it or not.
4914 TyPath(ref path, path_id) => {
4915 // This is a path in the type namespace. Walk through scopes
4917 let mut result_def = None;
4919 // First, check to see whether the name is a primitive type.
4920 if path.segments.len() == 1 {
4921 let id = path.segments.last().unwrap().identifier;
4923 match self.primitive_type_table
4927 Some(&primitive_type) => {
4929 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4933 .any(|s| s.parameters.has_lifetimes()) {
4934 span_err!(self.session, path.span, E0157,
4935 "lifetime parameters are not allowed on this type");
4936 } else if path.segments
4938 .any(|s| !s.parameters.is_empty()) {
4939 span_err!(self.session, path.span, E0153,
4940 "type parameters are not allowed on this type");
4951 match self.resolve_path(ty.id, path, TypeNS, true) {
4953 debug!("(resolving type) resolved `{}` to \
4955 token::get_ident(path.segments
4959 result_def = Some(def);
4966 Some(_) => {} // Continue.
4971 // Write the result into the def map.
4972 debug!("(resolving type) writing resolution for `{}` \
4974 self.path_names_to_string(path),
4976 self.record_def(path_id, def);
4979 let msg = format!("use of undeclared type name `{}`",
4980 self.path_names_to_string(path));
4981 self.resolve_error(ty.span, msg.as_slice());
4986 TyObjectSum(ref ty, ref bound_vec) => {
4987 self.resolve_type(&**ty);
4988 self.resolve_type_parameter_bounds(ty.id, bound_vec,
4989 TraitBoundingTypeParameter);
4992 TyQPath(ref qpath) => {
4993 self.resolve_type(&*qpath.self_type);
4994 self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
4997 TyClosure(ref c) | TyProc(ref c) => {
4998 self.resolve_type_parameter_bounds(
5001 TraitBoundingTypeParameter);
5002 visit::walk_ty(self, ty);
5005 TyPolyTraitRef(ref bounds) => {
5006 self.resolve_type_parameter_bounds(
5010 visit::walk_ty(self, ty);
5013 // Just resolve embedded types.
5014 visit::walk_ty(self, ty);
5019 fn resolve_pattern(&mut self,
5021 mode: PatternBindingMode,
5022 // Maps idents to the node ID for the (outermost)
5023 // pattern that binds them
5024 bindings_list: &mut HashMap<Name, NodeId>) {
5025 let pat_id = pattern.id;
5026 walk_pat(pattern, |pattern| {
5027 match pattern.node {
5028 PatIdent(binding_mode, ref path1, _) => {
5030 // The meaning of pat_ident with no type parameters
5031 // depends on whether an enum variant or unit-like struct
5032 // with that name is in scope. The probing lookup has to
5033 // be careful not to emit spurious errors. Only matching
5034 // patterns (match) can match nullary variants or
5035 // unit-like structs. For binding patterns (let), matching
5036 // such a value is simply disallowed (since it's rarely
5039 let ident = path1.node;
5040 let renamed = mtwt::resolve(ident);
5042 match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
5043 FoundStructOrEnumVariant(ref def, lp)
5044 if mode == RefutableMode => {
5045 debug!("(resolving pattern) resolving `{}` to \
5046 struct or enum variant",
5047 token::get_name(renamed));
5049 self.enforce_default_binding_mode(
5053 self.record_def(pattern.id, (def.clone(), lp));
5055 FoundStructOrEnumVariant(..) => {
5058 format!("declaration of `{}` shadows an enum \
5059 variant or unit-like struct in \
5061 token::get_name(renamed)).as_slice());
5063 FoundConst(ref def, lp) if mode == RefutableMode => {
5064 debug!("(resolving pattern) resolving `{}` to \
5066 token::get_name(renamed));
5068 self.enforce_default_binding_mode(
5072 self.record_def(pattern.id, (def.clone(), lp));
5075 self.resolve_error(pattern.span,
5076 "only irrefutable patterns \
5079 BareIdentifierPatternUnresolved => {
5080 debug!("(resolving pattern) binding `{}`",
5081 token::get_name(renamed));
5083 let def = DefLocal(pattern.id);
5085 // Record the definition so that later passes
5086 // will be able to distinguish variants from
5087 // locals in patterns.
5089 self.record_def(pattern.id, (def, LastMod(AllPublic)));
5091 // Add the binding to the local ribs, if it
5092 // doesn't already exist in the bindings list. (We
5093 // must not add it if it's in the bindings list
5094 // because that breaks the assumptions later
5095 // passes make about or-patterns.)
5096 if !bindings_list.contains_key(&renamed) {
5097 let this = &mut *self;
5098 let last_rib = this.value_ribs.last_mut().unwrap();
5099 last_rib.bindings.insert(renamed, DlDef(def));
5100 bindings_list.insert(renamed, pat_id);
5101 } else if mode == ArgumentIrrefutableMode &&
5102 bindings_list.contains_key(&renamed) {
5103 // Forbid duplicate bindings in the same
5105 self.resolve_error(pattern.span,
5106 format!("identifier `{}` \
5114 } else if bindings_list.get(&renamed) ==
5116 // Then this is a duplicate variable in the
5117 // same disjunction, which is an error.
5118 self.resolve_error(pattern.span,
5119 format!("identifier `{}` is bound \
5120 more than once in the same \
5122 token::get_ident(ident)).as_slice());
5124 // Else, not bound in the same pattern: do
5130 PatEnum(ref path, _) => {
5131 // This must be an enum variant, struct or const.
5132 match self.resolve_path(pat_id, path, ValueNS, false) {
5133 Some(def @ (DefVariant(..), _)) |
5134 Some(def @ (DefStruct(..), _)) |
5135 Some(def @ (DefConst(..), _)) => {
5136 self.record_def(pattern.id, def);
5138 Some((DefStatic(..), _)) => {
5139 self.resolve_error(path.span,
5140 "static variables cannot be \
5141 referenced in a pattern, \
5142 use a `const` instead");
5145 self.resolve_error(path.span,
5146 format!("`{}` is not an enum variant, struct or const",
5151 .identifier)).as_slice());
5154 self.resolve_error(path.span,
5155 format!("unresolved enum variant, struct or const `{}`",
5160 .identifier)).as_slice());
5164 // Check the types in the path pattern.
5165 for ty in path.segments
5167 .flat_map(|s| s.parameters.types().into_iter()) {
5168 self.resolve_type(&**ty);
5172 PatLit(ref expr) => {
5173 self.resolve_expr(&**expr);
5176 PatRange(ref first_expr, ref last_expr) => {
5177 self.resolve_expr(&**first_expr);
5178 self.resolve_expr(&**last_expr);
5181 PatStruct(ref path, _, _) => {
5182 match self.resolve_path(pat_id, path, TypeNS, false) {
5183 Some(definition) => {
5184 self.record_def(pattern.id, definition);
5187 debug!("(resolving pattern) didn't find struct \
5189 let msg = format!("`{}` does not name a structure",
5190 self.path_names_to_string(path));
5191 self.resolve_error(path.span, msg.as_slice());
5204 fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
5205 -> BareIdentifierPatternResolution {
5206 let module = self.current_module.clone();
5207 match self.resolve_item_in_lexical_scope(module,
5210 Success((target, _)) => {
5211 debug!("(resolve bare identifier pattern) succeeded in \
5213 token::get_name(name),
5214 target.bindings.value_def.borrow());
5215 match *target.bindings.value_def.borrow() {
5217 panic!("resolved name in the value namespace to a \
5218 set of name bindings with no def?!");
5221 // For the two success cases, this lookup can be
5222 // considered as not having a private component because
5223 // the lookup happened only within the current module.
5225 def @ DefVariant(..) | def @ DefStruct(..) => {
5226 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
5228 def @ DefConst(..) => {
5229 return FoundConst(def, LastMod(AllPublic));
5232 self.resolve_error(span,
5233 "static variables cannot be \
5234 referenced in a pattern, \
5235 use a `const` instead");
5236 return BareIdentifierPatternUnresolved;
5239 return BareIdentifierPatternUnresolved;
5247 panic!("unexpected indeterminate result");
5251 Some((span, msg)) => {
5252 self.resolve_error(span, format!("failed to resolve: {}",
5258 debug!("(resolve bare identifier pattern) failed to find {}",
5259 token::get_name(name));
5260 return BareIdentifierPatternUnresolved;
5265 /// If `check_ribs` is true, checks the local definitions first; i.e.
5266 /// doesn't skip straight to the containing module.
5267 fn resolve_path(&mut self,
5270 namespace: Namespace,
5271 check_ribs: bool) -> Option<(Def, LastPrivate)> {
5272 // First, resolve the types.
5273 for ty in path.segments.iter().flat_map(|s| s.parameters.types().into_iter()) {
5274 self.resolve_type(&**ty);
5278 return self.resolve_crate_relative_path(path, namespace);
5281 let unqualified_def =
5282 self.resolve_identifier(path.segments
5289 if path.segments.len() > 1 {
5290 let def = self.resolve_module_relative_path(path, namespace);
5291 match (def, unqualified_def) {
5292 (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
5294 .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
5297 "unnecessary qualification".to_string());
5305 return unqualified_def;
5308 // resolve a single identifier (used as a varref)
5309 fn resolve_identifier(&mut self,
5311 namespace: Namespace,
5314 -> Option<(Def, LastPrivate)> {
5316 match self.resolve_identifier_in_local_ribs(identifier,
5320 return Some((def, LastMod(AllPublic)));
5328 return self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace);
5331 // FIXME #4952: Merge me with resolve_name_in_module?
5332 fn resolve_definition_of_name_in_module(&mut self,
5333 containing_module: Rc<Module>,
5335 namespace: Namespace)
5337 // First, search children.
5338 self.populate_module_if_necessary(&containing_module);
5340 match containing_module.children.borrow().get(&name) {
5341 Some(child_name_bindings) => {
5342 match child_name_bindings.def_for_namespace(namespace) {
5344 // Found it. Stop the search here.
5345 let p = child_name_bindings.defined_in_public_namespace(
5347 let lp = if p {LastMod(AllPublic)} else {
5348 LastMod(DependsOn(def.def_id()))
5350 return ChildNameDefinition(def, lp);
5358 // Next, search import resolutions.
5359 match containing_module.import_resolutions.borrow().get(&name) {
5360 Some(import_resolution) if import_resolution.is_public => {
5361 if let Some(target) = (*import_resolution).target_for_namespace(namespace) {
5362 match target.bindings.def_for_namespace(namespace) {
5365 let id = import_resolution.id(namespace);
5366 // track imports and extern crates as well
5367 self.used_imports.insert((id, namespace));
5368 match target.target_module.def_id.get() {
5369 Some(DefId{krate: kid, ..}) => {
5370 self.used_crates.insert(kid);
5374 return ImportNameDefinition(def, LastMod(AllPublic));
5377 // This can happen with external impls, due to
5378 // the imperfect way we read the metadata.
5383 Some(..) | None => {} // Continue.
5386 // Finally, search through external children.
5387 if namespace == TypeNS {
5388 if let Some(module) = containing_module.external_module_children.borrow()
5389 .get(&name).cloned() {
5390 if let Some(def_id) = module.def_id.get() {
5391 // track used crates
5392 self.used_crates.insert(def_id.krate);
5393 let lp = if module.is_public {LastMod(AllPublic)} else {
5394 LastMod(DependsOn(def_id))
5396 return ChildNameDefinition(DefMod(def_id), lp);
5401 return NoNameDefinition;
5404 // resolve a "module-relative" path, e.g. a::b::c
5405 fn resolve_module_relative_path(&mut self,
5407 namespace: Namespace)
5408 -> Option<(Def, LastPrivate)> {
5409 let module_path = path.segments.init().iter()
5410 .map(|ps| ps.identifier.name)
5411 .collect::<Vec<_>>();
5413 let containing_module;
5415 let module = self.current_module.clone();
5416 match self.resolve_module_path(module,
5417 module_path.as_slice(),
5422 let (span, msg) = match err {
5423 Some((span, msg)) => (span, msg),
5425 let msg = format!("Use of undeclared module `{}`",
5426 self.names_to_string(
5427 module_path.as_slice()));
5432 self.resolve_error(span, format!("failed to resolve. {}",
5436 Indeterminate => panic!("indeterminate unexpected"),
5437 Success((resulting_module, resulting_last_private)) => {
5438 containing_module = resulting_module;
5439 last_private = resulting_last_private;
5443 let name = path.segments.last().unwrap().identifier.name;
5444 let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
5447 NoNameDefinition => {
5448 // We failed to resolve the name. Report an error.
5451 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
5452 (def, last_private.or(lp))
5455 if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
5456 self.used_crates.insert(kid);
5461 /// Invariant: This must be called only during main resolution, not during
5462 /// import resolution.
5463 fn resolve_crate_relative_path(&mut self,
5465 namespace: Namespace)
5466 -> Option<(Def, LastPrivate)> {
5467 let module_path = path.segments.init().iter()
5468 .map(|ps| ps.identifier.name)
5469 .collect::<Vec<_>>();
5471 let root_module = self.graph_root.get_module();
5473 let containing_module;
5475 match self.resolve_module_path_from_root(root_module,
5476 module_path.as_slice(),
5480 LastMod(AllPublic)) {
5482 let (span, msg) = match err {
5483 Some((span, msg)) => (span, msg),
5485 let msg = format!("Use of undeclared module `::{}`",
5486 self.names_to_string(module_path.as_slice()));
5491 self.resolve_error(span, format!("failed to resolve. {}",
5497 panic!("indeterminate unexpected");
5500 Success((resulting_module, resulting_last_private)) => {
5501 containing_module = resulting_module;
5502 last_private = resulting_last_private;
5506 let name = path.segments.last().unwrap().identifier.name;
5507 match self.resolve_definition_of_name_in_module(containing_module,
5510 NoNameDefinition => {
5511 // We failed to resolve the name. Report an error.
5514 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
5515 return Some((def, last_private.or(lp)));
5520 fn resolve_identifier_in_local_ribs(&mut self,
5522 namespace: Namespace,
5525 // Check the local set of ribs.
5526 let search_result = match namespace {
5528 let renamed = mtwt::resolve(ident);
5529 self.search_ribs(self.value_ribs.as_slice(),
5533 let name = ident.name;
5534 self.search_ribs(self.type_ribs.as_slice(), name, span)
5538 match search_result {
5539 Some(DlDef(def)) => {
5540 debug!("(resolving path in local ribs) resolved `{}` to \
5542 token::get_ident(ident),
5546 Some(DlField) | Some(DlImpl(_)) | None => {
5552 fn resolve_item_by_name_in_lexical_scope(&mut self,
5554 namespace: Namespace)
5555 -> Option<(Def, LastPrivate)> {
5557 let module = self.current_module.clone();
5558 match self.resolve_item_in_lexical_scope(module,
5561 Success((target, _)) => {
5562 match (*target.bindings).def_for_namespace(namespace) {
5564 // This can happen if we were looking for a type and
5565 // found a module instead. Modules don't have defs.
5566 debug!("(resolving item path by identifier in lexical \
5567 scope) failed to resolve {} after success...",
5568 token::get_name(name));
5572 debug!("(resolving item path in lexical scope) \
5573 resolved `{}` to item",
5574 token::get_name(name));
5575 // This lookup is "all public" because it only searched
5576 // for one identifier in the current module (couldn't
5577 // have passed through reexports or anything like that.
5578 return Some((def, LastMod(AllPublic)));
5583 panic!("unexpected indeterminate result");
5587 Some((span, msg)) =>
5588 self.resolve_error(span, format!("failed to resolve. {}", msg)),
5592 debug!("(resolving item path by identifier in lexical scope) \
5593 failed to resolve {}", token::get_name(name));
5599 fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
5600 self.emit_errors = false;
5602 self.emit_errors = true;
5606 fn resolve_error<T: Str>(&self, span: Span, s: T) {
5607 if self.emit_errors {
5608 self.session.span_err(span, s.as_slice());
5612 fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
5613 fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
5614 -> Option<(Path, NodeId, FallbackChecks)> {
5616 TyPath(ref path, node_id) => Some((path.clone(), node_id, allow)),
5617 TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
5618 TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
5619 // This doesn't handle the remaining `Ty` variants as they are not
5620 // that commonly the self_type, it might be interesting to provide
5621 // support for those in future.
5626 fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
5627 -> Option<Rc<Module>> {
5628 let root = this.current_module.clone();
5629 let last_name = name_path.last().unwrap();
5631 if name_path.len() == 1 {
5632 match this.primitive_type_table.primitive_types.get(last_name) {
5635 match this.current_module.children.borrow().get(last_name) {
5636 Some(child) => child.get_module_if_available(),
5642 match this.resolve_module_path(root,
5643 name_path.as_slice(),
5647 Success((module, _)) => Some(module),
5653 let (path, node_id, allowed) = match self.current_self_type {
5654 Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
5656 None => return NoSuggestion,
5658 None => return NoSuggestion,
5661 if allowed == Everything {
5662 // Look for a field with the same name in the current self_type.
5663 match self.def_map.borrow().get(&node_id) {
5664 Some(&DefTy(did, _))
5665 | Some(&DefStruct(did))
5666 | Some(&DefVariant(_, did, _)) => match self.structs.get(&did) {
5669 if fields.iter().any(|&field_name| name == field_name) {
5674 _ => {} // Self type didn't resolve properly
5678 let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
5680 // Look for a method in the current self type's impl module.
5681 match get_module(self, path.span, name_path.as_slice()) {
5682 Some(module) => match module.children.borrow().get(&name) {
5684 let p_str = self.path_names_to_string(&path);
5685 match binding.def_for_namespace(ValueNS) {
5686 Some(DefStaticMethod(_, provenance)) => {
5688 FromImpl(_) => return StaticMethod(p_str),
5689 FromTrait(_) => unreachable!()
5692 Some(DefMethod(_, None, _)) if allowed == Everything => return Method,
5693 Some(DefMethod(_, Some(_), _)) => return TraitItem,
5702 // Look for a method in the current trait.
5703 match self.current_trait_ref {
5704 Some((did, ref trait_ref)) => {
5705 let path_str = self.path_names_to_string(&trait_ref.path);
5707 match self.trait_item_map.get(&(name, did)) {
5708 Some(&StaticMethodTraitItemKind) => {
5709 return TraitMethod(path_str)
5711 Some(_) => return TraitItem,
5721 fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5723 let this = &mut *self;
5725 let mut maybes: Vec<token::InternedString> = Vec::new();
5726 let mut values: Vec<uint> = Vec::new();
5728 for rib in this.value_ribs.iter().rev() {
5729 for (&k, _) in rib.bindings.iter() {
5730 maybes.push(token::get_name(k));
5731 values.push(uint::MAX);
5735 let mut smallest = 0;
5736 for (i, other) in maybes.iter().enumerate() {
5737 values[i] = name.lev_distance(other.get());
5739 if values[i] <= values[smallest] {
5744 if values.len() > 0 &&
5745 values[smallest] != uint::MAX &&
5746 values[smallest] < name.len() + 2 &&
5747 values[smallest] <= max_distance &&
5748 name != maybes[smallest].get() {
5750 Some(maybes[smallest].get().to_string())
5757 fn resolve_expr(&mut self, expr: &Expr) {
5758 // First, record candidate traits for this expression if it could
5759 // result in the invocation of a method call.
5761 self.record_candidate_traits_for_expr_if_necessary(expr);
5763 // Next, resolve the node.
5765 // The interpretation of paths depends on whether the path has
5766 // multiple elements in it or not.
5768 ExprPath(ref path) => {
5769 // This is a local path in the value namespace. Walk through
5770 // scopes looking for it.
5772 match self.resolve_path(expr.id, path, ValueNS, true) {
5774 // Write the result into the def map.
5775 debug!("(resolving expr) resolved `{}`",
5776 self.path_names_to_string(path));
5778 self.record_def(expr.id, def);
5781 let wrong_name = self.path_names_to_string(path);
5782 // Be helpful if the name refers to a struct
5783 // (The pattern matching def_tys where the id is in self.structs
5784 // matches on regular structs while excluding tuple- and enum-like
5785 // structs, which wouldn't result in this error.)
5786 match self.with_no_errors(|this|
5787 this.resolve_path(expr.id, path, TypeNS, false)) {
5788 Some((DefTy(struct_id, _), _))
5789 if self.structs.contains_key(&struct_id) => {
5790 self.resolve_error(expr.span,
5791 format!("`{}` is a structure name, but \
5793 uses it like a function name",
5794 wrong_name).as_slice());
5796 self.session.span_help(expr.span,
5797 format!("Did you mean to write: \
5798 `{} {{ /* fields */ }}`?",
5799 wrong_name).as_slice());
5803 let mut method_scope = false;
5804 self.value_ribs.iter().rev().all(|rib| {
5805 let res = match *rib {
5806 Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
5807 Rib { bindings: _, kind: ItemRibKind } => false,
5808 _ => return true, // Keep advancing
5812 false // Stop advancing
5815 if method_scope && token::get_name(self.self_name).get()
5819 "`self` is not available \
5820 in a static method. Maybe a \
5821 `self` argument is missing?");
5823 let last_name = path.segments.last().unwrap().identifier.name;
5824 let mut msg = match self.find_fallback_in_self_type(last_name) {
5826 // limit search to 5 to reduce the number
5827 // of stupid suggestions
5828 self.find_best_match_for_name(wrong_name.as_slice(), 5)
5829 .map_or("".to_string(),
5830 |x| format!("`{}`", x))
5833 format!("`self.{}`", wrong_name),
5836 format!("to call `self.{}`", wrong_name),
5837 TraitMethod(path_str)
5838 | StaticMethod(path_str) =>
5839 format!("to call `{}::{}`", path_str, wrong_name)
5843 msg = format!(". Did you mean {}?", msg)
5848 format!("unresolved name `{}`{}",
5857 visit::walk_expr(self, expr);
5860 ExprClosure(capture_clause, _, ref fn_decl, ref block) => {
5861 self.capture_mode_map.insert(expr.id, capture_clause);
5862 self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
5863 Some(&**fn_decl), NoTypeParameters,
5867 ExprProc(ref fn_decl, ref block) => {
5868 self.capture_mode_map.insert(expr.id, ast::CaptureByValue);
5869 self.resolve_function(ClosureRibKind(expr.id, block.id),
5870 Some(&**fn_decl), NoTypeParameters,
5874 ExprStruct(ref path, _, _) => {
5875 // Resolve the path to the structure it goes to. We don't
5876 // check to ensure that the path is actually a structure; that
5877 // is checked later during typeck.
5878 match self.resolve_path(expr.id, path, TypeNS, false) {
5879 Some(definition) => self.record_def(expr.id, definition),
5881 debug!("(resolving expression) didn't find struct \
5883 let msg = format!("`{}` does not name a structure",
5884 self.path_names_to_string(path));
5885 self.resolve_error(path.span, msg.as_slice());
5889 visit::walk_expr(self, expr);
5892 ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
5893 self.with_label_rib(|this| {
5894 let def_like = DlDef(DefLabel(expr.id));
5897 let rib = this.label_ribs.last_mut().unwrap();
5898 let renamed = mtwt::resolve(label);
5899 rib.bindings.insert(renamed, def_like);
5902 visit::walk_expr(this, expr);
5906 ExprForLoop(ref pattern, ref head, ref body, optional_label) => {
5907 self.resolve_expr(&**head);
5909 self.value_ribs.push(Rib::new(NormalRibKind));
5911 self.resolve_pattern(&**pattern,
5912 LocalIrrefutableMode,
5913 &mut HashMap::new());
5915 match optional_label {
5919 .push(Rib::new(NormalRibKind));
5920 let def_like = DlDef(DefLabel(expr.id));
5923 let rib = self.label_ribs.last_mut().unwrap();
5924 let renamed = mtwt::resolve(label);
5925 rib.bindings.insert(renamed, def_like);
5930 self.resolve_block(&**body);
5932 if optional_label.is_some() {
5933 drop(self.label_ribs.pop())
5936 self.value_ribs.pop();
5939 ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5940 let renamed = mtwt::resolve(label);
5941 match self.search_ribs(self.label_ribs.as_slice(),
5942 renamed, expr.span) {
5946 format!("use of undeclared label `{}`",
5947 token::get_ident(label)).as_slice())
5949 Some(DlDef(def @ DefLabel(_))) => {
5950 // Since this def is a label, it is never read.
5951 self.record_def(expr.id, (def, LastMod(AllPublic)))
5954 self.session.span_bug(expr.span,
5955 "label wasn't mapped to a \
5962 visit::walk_expr(self, expr);
5967 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5969 ExprField(_, ident) => {
5970 // FIXME(#6890): Even though you can't treat a method like a
5971 // field, we need to add any trait methods we find that match
5972 // the field name so that we can do some nice error reporting
5973 // later on in typeck.
5974 let traits = self.search_for_traits_containing_method(ident.node.name);
5975 self.trait_map.insert(expr.id, traits);
5977 ExprMethodCall(ident, _, _) => {
5978 debug!("(recording candidate traits for expr) recording \
5981 let traits = self.search_for_traits_containing_method(ident.node.name);
5982 self.trait_map.insert(expr.id, traits);
5990 fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
5991 debug!("(searching for traits containing method) looking for '{}'",
5992 token::get_name(name));
5994 fn add_trait_info(found_traits: &mut Vec<DefId>,
5995 trait_def_id: DefId,
5997 debug!("(adding trait info) found trait {}:{} for method '{}'",
6000 token::get_name(name));
6001 found_traits.push(trait_def_id);
6004 let mut found_traits = Vec::new();
6005 let mut search_module = self.current_module.clone();
6007 // Look for the current trait.
6008 match self.current_trait_ref {
6009 Some((trait_def_id, _)) => {
6010 if self.trait_item_map.contains_key(&(name, trait_def_id)) {
6011 add_trait_info(&mut found_traits, trait_def_id, name);
6014 None => {} // Nothing to do.
6017 // Look for trait children.
6018 self.populate_module_if_necessary(&search_module);
6021 for (_, child_names) in search_module.children.borrow().iter() {
6022 let def = match child_names.def_for_namespace(TypeNS) {
6026 let trait_def_id = match def {
6027 DefTrait(trait_def_id) => trait_def_id,
6030 if self.trait_item_map.contains_key(&(name, trait_def_id)) {
6031 add_trait_info(&mut found_traits, trait_def_id, name);
6036 // Look for imports.
6037 for (_, import) in search_module.import_resolutions.borrow().iter() {
6038 let target = match import.target_for_namespace(TypeNS) {
6040 Some(target) => target,
6042 let did = match target.bindings.def_for_namespace(TypeNS) {
6043 Some(DefTrait(trait_def_id)) => trait_def_id,
6044 Some(..) | None => continue,
6046 if self.trait_item_map.contains_key(&(name, did)) {
6047 add_trait_info(&mut found_traits, did, name);
6048 self.used_imports.insert((import.type_id, TypeNS));
6049 if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
6050 self.used_crates.insert(kid);
6055 match search_module.parent_link.clone() {
6056 NoParentLink | ModuleParentLink(..) => break,
6057 BlockParentLink(parent_module, _) => {
6058 search_module = parent_module.upgrade().unwrap();
6066 fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
6067 debug!("(recording def) recording {} for {}, last private {}",
6069 assert!(match lp {LastImport{..} => false, _ => true},
6070 "Import should only be used for `use` directives");
6071 self.last_private.insert(node_id, lp);
6073 match self.def_map.borrow_mut().entry(node_id) {
6074 // Resolve appears to "resolve" the same ID multiple
6075 // times, so here is a sanity check it at least comes to
6076 // the same conclusion! - nmatsakis
6077 Occupied(entry) => if def != *entry.get() {
6079 .bug(format!("node_id {} resolved first to {} and \
6085 Vacant(entry) => { entry.set(def); },
6089 fn enforce_default_binding_mode(&mut self,
6091 pat_binding_mode: BindingMode,
6093 match pat_binding_mode {
6094 BindByValue(_) => {}
6096 self.resolve_error(pat.span,
6097 format!("cannot use `ref` binding mode \
6105 // Unused import checking
6107 // Although this is mostly a lint pass, it lives in here because it depends on
6108 // resolve data structures and because it finalises the privacy information for
6109 // `use` directives.
6112 fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
6113 let mut visitor = UnusedImportCheckVisitor{ resolver: self };
6114 visit::walk_crate(&mut visitor, krate);
6117 fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
6118 // Ignore is_public import statements because there's no way to be sure
6119 // whether they're used or not. Also ignore imports with a dummy span
6120 // because this means that they were generated in some fashion by the
6121 // compiler and we don't need to consider them.
6122 if vi.vis == Public { return }
6123 if vi.span == DUMMY_SP { return }
6126 ViewItemExternCrate(_, _, id) => {
6127 if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) {
6128 if !self.used_crates.contains(&crate_num) {
6129 self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
6132 "unused extern crate".to_string());
6136 ViewItemUse(ref p) => {
6138 ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
6140 ViewPathList(_, ref list, _) => {
6141 for i in list.iter() {
6142 self.finalize_import(i.node.id(), i.span);
6145 ViewPathGlob(_, id) => {
6146 if !self.used_imports.contains(&(id, TypeNS)) &&
6147 !self.used_imports.contains(&(id, ValueNS)) {
6149 .add_lint(lint::builtin::UNUSED_IMPORTS,
6152 "unused import".to_string());
6160 // We have information about whether `use` (import) directives are actually used now.
6161 // If an import is not used at all, we signal a lint error. If an import is only used
6162 // for a single namespace, we remove the other namespace from the recorded privacy
6163 // information. That means in privacy.rs, we will only check imports and namespaces
6164 // which are used. In particular, this means that if an import could name either a
6165 // public or private item, we will check the correct thing, dependent on how the import
6167 fn finalize_import(&mut self, id: NodeId, span: Span) {
6168 debug!("finalizing import uses for {}",
6169 self.session.codemap().span_to_snippet(span));
6171 if !self.used_imports.contains(&(id, TypeNS)) &&
6172 !self.used_imports.contains(&(id, ValueNS)) {
6173 self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
6176 "unused import".to_string());
6179 let (v_priv, t_priv) = match self.last_private.get(&id) {
6187 panic!("we should only have LastImport for `use` directives")
6192 let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
6197 let t_used = if self.used_imports.contains(&(id, TypeNS)) {
6203 match (v_priv, t_priv) {
6204 // Since some items may be both in the value _and_ type namespaces (e.g., structs)
6205 // we might have two LastPrivates pointing at the same thing. There is no point
6206 // checking both, so lets not check the value one.
6207 (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
6211 self.last_private.insert(id, LastImport{value_priv: v_priv,
6214 type_used: t_used});
6220 // Diagnostics are not particularly efficient, because they're rarely
6224 /// A somewhat inefficient routine to obtain the name of a module.
6225 fn module_to_string(&self, module: &Module) -> String {
6226 let mut names = Vec::new();
6228 fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
6229 match module.parent_link {
6231 ModuleParentLink(ref module, name) => {
6233 collect_mod(names, &*module.upgrade().unwrap());
6235 BlockParentLink(ref module, _) => {
6236 // danger, shouldn't be ident?
6237 names.push(special_idents::opaque.name);
6238 collect_mod(names, &*module.upgrade().unwrap());
6242 collect_mod(&mut names, module);
6244 if names.len() == 0 {
6245 return "???".to_string();
6247 self.names_to_string(names.into_iter().rev()
6248 .collect::<Vec<ast::Name>>()
6252 #[allow(dead_code)] // useful for debugging
6253 fn dump_module(&mut self, module_: Rc<Module>) {
6254 debug!("Dump of module `{}`:", self.module_to_string(&*module_));
6256 debug!("Children:");
6257 self.populate_module_if_necessary(&module_);
6258 for (&name, _) in module_.children.borrow().iter() {
6259 debug!("* {}", token::get_name(name));
6262 debug!("Import resolutions:");
6263 let import_resolutions = module_.import_resolutions.borrow();
6264 for (&name, import_resolution) in import_resolutions.iter() {
6266 match import_resolution.target_for_namespace(ValueNS) {
6267 None => { value_repr = "".to_string(); }
6269 value_repr = " value:?".to_string();
6275 match import_resolution.target_for_namespace(TypeNS) {
6276 None => { type_repr = "".to_string(); }
6278 type_repr = " type:?".to_string();
6283 debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
6288 pub struct CrateMap {
6289 pub def_map: DefMap,
6290 pub freevars: RefCell<FreevarMap>,
6291 pub capture_mode_map: RefCell<CaptureModeMap>,
6292 pub exp_map2: ExportMap2,
6293 pub trait_map: TraitMap,
6294 pub external_exports: ExternalExports,
6295 pub last_private_map: LastPrivateMap,
6298 /// Entry point to crate resolution.
6299 pub fn resolve_crate(session: &Session,
6303 let mut resolver = Resolver::new(session, krate.span);
6304 resolver.resolve(krate);
6306 def_map: resolver.def_map,
6307 freevars: resolver.freevars,
6308 capture_mode_map: RefCell::new(resolver.capture_mode_map),
6309 exp_map2: resolver.export_map2,
6310 trait_map: resolver.trait_map,
6311 external_exports: resolver.external_exports,
6312 last_private_map: resolver.last_private,