1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 #![allow(non_camel_case_types)]
13 use driver::session::Session;
14 use metadata::csearch;
15 use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
16 use middle::lang_items::LanguageItems;
17 use middle::lint::{UnnecessaryQualification, UnusedImports};
18 use middle::pat_util::pat_bindings;
19 use util::nodemap::{NodeMap, DefIdSet, FnvHashSet};
23 use syntax::ast_util::{def_id_of_def, local_def};
24 use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
25 use syntax::ext::mtwt;
26 use syntax::parse::token::special_idents;
27 use syntax::parse::token;
28 use syntax::print::pprust::path_to_str;
29 use syntax::codemap::{Span, DUMMY_SP, Pos};
30 use syntax::owned_slice::OwnedSlice;
32 use syntax::visit::Visitor;
34 use collections::{HashMap, HashSet};
35 use std::cell::{Cell, RefCell};
36 use std::mem::replace;
37 use std::rc::{Rc, Weak};
38 use std::strbuf::StrBuf;
42 pub type DefMap = RefCell<NodeMap<Def>>;
46 binding_mode: BindingMode,
49 // Map from the name in a pattern to its binding mode.
50 type BindingMap = HashMap<Name,binding_info>;
52 // Trait method resolution
53 pub type TraitMap = NodeMap<Vec<DefId> >;
55 // This is the replacement export map. It maps a module to all of the exports
57 pub type ExportMap2 = RefCell<NodeMap<Vec<Export2> >>;
60 pub name: ~str, // The name of the target.
61 pub def_id: DefId, // The definition of the target.
64 // This set contains all exported definitions from external crates. The set does
65 // not contain any entries from local crates.
66 pub type ExternalExports = DefIdSet;
69 pub type LastPrivateMap = NodeMap<LastPrivate>;
71 pub enum LastPrivate {
73 // `use` directives (imports) can refer to two separate definitions in the
74 // type and value namespaces. We record here the last private node for each
75 // and whether the import is in fact used for each.
76 // If the Option<PrivateDep> fields are None, it means there is no definition
78 LastImport{pub value_priv: Option<PrivateDep>,
79 pub value_used: ImportUse,
80 pub type_priv: Option<PrivateDep>,
81 pub type_used: ImportUse},
89 // How an import is used.
92 Unused, // The import is not used.
93 Used, // The import is used.
97 fn or(self, other: LastPrivate) -> LastPrivate {
99 (me, LastMod(AllPublic)) => me,
106 enum PatternBindingMode {
108 LocalIrrefutableMode,
109 ArgumentIrrefutableMode,
112 #[deriving(Eq, TotalEq, Hash)]
119 enum NamespaceError {
126 /// A NamespaceResult represents the result of resolving an import in
127 /// a particular namespace. The result is either definitely-resolved,
128 /// definitely- unresolved, or unknown.
130 enum NamespaceResult {
131 /// Means that resolve hasn't gathered enough information yet to determine
132 /// whether the name is bound in this namespace. (That is, it hasn't
133 /// resolved all `use` directives yet.)
135 /// Means that resolve has determined that the name is definitely
136 /// not bound in the namespace.
138 /// Means that resolve has determined that the name is bound in the Module
139 /// argument, and specified by the NameBindings argument.
140 BoundResult(Rc<Module>, Rc<NameBindings>)
143 impl NamespaceResult {
144 fn is_unknown(&self) -> bool {
146 UnknownResult => true,
150 fn is_unbound(&self) -> bool {
152 UnboundResult => true,
158 enum NameDefinition {
159 NoNameDefinition, //< The name was unbound.
160 ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
161 ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
164 impl<'a> Visitor<()> for Resolver<'a> {
165 fn visit_item(&mut self, item: &Item, _: ()) {
166 self.resolve_item(item);
168 fn visit_arm(&mut self, arm: &Arm, _: ()) {
169 self.resolve_arm(arm);
171 fn visit_block(&mut self, block: &Block, _: ()) {
172 self.resolve_block(block);
174 fn visit_expr(&mut self, expr: &Expr, _: ()) {
175 self.resolve_expr(expr);
177 fn visit_local(&mut self, local: &Local, _: ()) {
178 self.resolve_local(local);
180 fn visit_ty(&mut self, ty: &Ty, _: ()) {
181 self.resolve_type(ty);
185 /// Contains data for specific types of import directives.
186 enum ImportDirectiveSubclass {
187 SingleImport(Ident /* target */, Ident /* source */),
191 /// The context that we thread through while building the reduced graph.
193 enum ReducedGraphParent {
194 ModuleReducedGraphParent(Rc<Module>)
197 impl ReducedGraphParent {
198 fn module(&self) -> Rc<Module> {
200 ModuleReducedGraphParent(ref m) => {
207 enum ResolveResult<T> {
208 Failed, // Failed to resolve the name.
209 Indeterminate, // Couldn't determine due to unresolved globs.
210 Success(T) // Successfully resolved the import.
213 impl<T> ResolveResult<T> {
214 fn indeterminate(&self) -> bool {
215 match *self { Indeterminate => true, _ => false }
219 enum TypeParameters<'a> {
220 NoTypeParameters, //< No type parameters.
221 HasTypeParameters(&'a Generics, //< Type parameters.
222 NodeId, //< ID of the enclosing item
224 // The index to start numbering the type parameters at.
225 // This is zero if this is the outermost set of type
226 // parameters, or equal to the number of outer type
227 // parameters. For example, if we have:
230 // fn method<U>() { ... }
233 // The index at the method site will be 1, because the
234 // outer T had index 0.
237 // The kind of the rib used for type parameters.
241 // The rib kind controls the translation of argument or local definitions
242 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
245 // No translation needs to be applied.
248 // We passed through a function scope at the given node ID. Translate
249 // upvars as appropriate.
250 FunctionRibKind(NodeId /* func id */, NodeId /* body id */),
252 // We passed through an impl or trait and are now in one of its
253 // methods. Allow references to ty params that impl or trait
254 // binds. Disallow any other upvars (including other ty params that are
256 // parent; method itself
257 MethodRibKind(NodeId, MethodSort),
259 // We passed through a function *item* scope. Disallow upvars.
260 OpaqueFunctionRibKind,
262 // We're in a constant item. Can't refer to dynamic stuff.
266 // Methods can be required or provided. Required methods only occur in traits.
272 enum UseLexicalScopeFlag {
277 enum SearchThroughModulesFlag {
278 DontSearchThroughModules,
282 enum ModulePrefixResult {
284 PrefixFound(Rc<Module>, uint)
288 enum NameSearchType {
289 /// We're doing a name search in order to resolve a `use` directive.
292 /// We're doing a name search in order to resolve a path type, a path
293 /// expression, or a path pattern.
297 enum BareIdentifierPatternResolution {
298 FoundStructOrEnumVariant(Def, LastPrivate),
299 FoundConst(Def, LastPrivate),
300 BareIdentifierPatternUnresolved
303 // Specifies how duplicates should be handled when adding a child item if
304 // another item exists with the same name in some namespace.
306 enum DuplicateCheckingMode {
307 ForbidDuplicateModules,
308 ForbidDuplicateTypes,
309 ForbidDuplicateValues,
310 ForbidDuplicateTypesAndValues,
316 bindings: RefCell<HashMap<Name, DefLike>>,
321 fn new(kind: RibKind) -> Rib {
323 bindings: RefCell::new(HashMap::new()),
329 /// One import directive.
330 struct ImportDirective {
331 module_path: Vec<Ident>,
332 subclass: ImportDirectiveSubclass,
335 is_public: bool, // see note in ImportResolution about how to use this
338 impl ImportDirective {
339 fn new(module_path: Vec<Ident> ,
340 subclass: ImportDirectiveSubclass,
346 module_path: module_path,
350 is_public: is_public,
355 /// The item that an import resolves to.
358 target_module: Rc<Module>,
359 bindings: Rc<NameBindings>,
363 fn new(target_module: Rc<Module>, bindings: Rc<NameBindings>) -> Target {
365 target_module: target_module,
371 /// An ImportResolution represents a particular `use` directive.
372 struct ImportResolution {
373 /// Whether this resolution came from a `use` or a `pub use`. Note that this
374 /// should *not* be used whenever resolution is being performed, this is
375 /// only looked at for glob imports statements currently. Privacy testing
376 /// occurs during a later phase of compilation.
379 // The number of outstanding references to this name. When this reaches
380 // zero, outside modules can count on the targets being correct. Before
381 // then, all bets are off; future imports could override this name.
382 outstanding_references: uint,
384 /// The value that this `use` directive names, if there is one.
385 value_target: Option<Target>,
386 /// The source node of the `use` directive leading to the value target
390 /// The type that this `use` directive names, if there is one.
391 type_target: Option<Target>,
392 /// The source node of the `use` directive leading to the type target
397 impl ImportResolution {
398 fn new(id: NodeId, is_public: bool) -> ImportResolution {
402 outstanding_references: 0,
405 is_public: is_public,
409 fn target_for_namespace(&self, namespace: Namespace)
412 TypeNS => self.type_target.clone(),
413 ValueNS => self.value_target.clone(),
417 fn id(&self, namespace: Namespace) -> NodeId {
419 TypeNS => self.type_id,
420 ValueNS => self.value_id,
425 /// The link from a module up to its nearest parent node.
429 ModuleParentLink(Weak<Module>, Ident),
430 BlockParentLink(Weak<Module>, NodeId)
433 /// The type of module this is.
443 /// One node in the tree of modules.
445 parent_link: ParentLink,
446 def_id: Cell<Option<DefId>>,
447 kind: Cell<ModuleKind>,
450 children: RefCell<HashMap<Name, Rc<NameBindings>>>,
451 imports: RefCell<Vec<ImportDirective>>,
453 // The external module children of this node that were declared with
455 external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
457 // The anonymous children of this node. Anonymous children are pseudo-
458 // modules that are implicitly created around items contained within
461 // For example, if we have this:
469 // There will be an anonymous module created around `g` with the ID of the
470 // entry block for `f`.
471 anonymous_children: RefCell<NodeMap<Rc<Module>>>,
473 // The status of resolving each import in this module.
474 import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
476 // The number of unresolved globs that this module exports.
477 glob_count: Cell<uint>,
479 // The index of the import we're resolving.
480 resolved_import_count: Cell<uint>,
482 // Whether this module is populated. If not populated, any attempt to
483 // access the children must be preceded with a
484 // `populate_module_if_necessary` call.
485 populated: Cell<bool>,
489 fn new(parent_link: ParentLink,
490 def_id: Option<DefId>,
496 parent_link: parent_link,
497 def_id: Cell::new(def_id),
498 kind: Cell::new(kind),
499 is_public: is_public,
500 children: RefCell::new(HashMap::new()),
501 imports: RefCell::new(Vec::new()),
502 external_module_children: RefCell::new(HashMap::new()),
503 anonymous_children: RefCell::new(NodeMap::new()),
504 import_resolutions: RefCell::new(HashMap::new()),
505 glob_count: Cell::new(0),
506 resolved_import_count: Cell::new(0),
507 populated: Cell::new(!external),
511 fn all_imports_resolved(&self) -> bool {
512 self.imports.borrow().len() == self.resolved_import_count.get()
516 // Records a possibly-private type definition.
519 is_public: bool, // see note in ImportResolution about how to use this
520 module_def: Option<Rc<Module>>,
521 type_def: Option<Def>,
522 type_span: Option<Span>
525 // Records a possibly-private value definition.
528 is_public: bool, // see note in ImportResolution about how to use this
530 value_span: Option<Span>,
533 // Records the definitions (at most one for each namespace) that a name is
535 struct NameBindings {
536 type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
537 value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
540 /// Ways in which a trait can be referenced
541 enum TraitReferenceType {
542 TraitImplementation, // impl SomeTrait for T { ... }
543 TraitDerivation, // trait T : SomeTrait { ... }
544 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
548 /// Creates a new module in this set of name bindings.
549 fn define_module(&self,
550 parent_link: ParentLink,
551 def_id: Option<DefId>,
556 // Merges the module with the existing type def or creates a new one.
557 let module_ = Rc::new(Module::new(parent_link, def_id, kind, external,
559 let type_def = self.type_def.borrow().clone();
562 *self.type_def.borrow_mut() = Some(TypeNsDef {
563 is_public: is_public,
564 module_def: Some(module_),
570 *self.type_def.borrow_mut() = Some(TypeNsDef {
571 is_public: is_public,
572 module_def: Some(module_),
574 type_def: type_def.type_def
580 /// Sets the kind of the module, creating a new one if necessary.
581 fn set_module_kind(&self,
582 parent_link: ParentLink,
583 def_id: Option<DefId>,
588 let type_def = self.type_def.borrow().clone();
591 let module = Module::new(parent_link, def_id, kind,
592 external, is_public);
593 *self.type_def.borrow_mut() = Some(TypeNsDef {
594 is_public: is_public,
595 module_def: Some(Rc::new(module)),
601 match type_def.module_def {
603 let module = Module::new(parent_link,
608 *self.type_def.borrow_mut() = Some(TypeNsDef {
609 is_public: is_public,
610 module_def: Some(Rc::new(module)),
611 type_def: type_def.type_def,
615 Some(module_def) => module_def.kind.set(kind),
621 /// Records a type definition.
622 fn define_type(&self, def: Def, sp: Span, is_public: bool) {
623 // Merges the type with the existing type def or creates a new one.
624 let type_def = self.type_def.borrow().clone();
627 *self.type_def.borrow_mut() = Some(TypeNsDef {
631 is_public: is_public,
635 *self.type_def.borrow_mut() = Some(TypeNsDef {
638 module_def: type_def.module_def,
639 is_public: is_public,
645 /// Records a value definition.
646 fn define_value(&self, def: Def, sp: Span, is_public: bool) {
647 *self.value_def.borrow_mut() = Some(ValueNsDef {
649 value_span: Some(sp),
650 is_public: is_public,
654 /// Returns the module node if applicable.
655 fn get_module_if_available(&self) -> Option<Rc<Module>> {
656 match *self.type_def.borrow() {
657 Some(ref type_def) => type_def.module_def.clone(),
663 * Returns the module node. Fails if this node does not have a module
666 fn get_module(&self) -> Rc<Module> {
667 match self.get_module_if_available() {
669 fail!("get_module called on a node with no module \
672 Some(module_def) => module_def
676 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
678 TypeNS => return self.type_def.borrow().is_some(),
679 ValueNS => return self.value_def.borrow().is_some()
683 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
685 TypeNS => match *self.type_def.borrow() {
686 Some(ref def) => def.is_public, None => false
688 ValueNS => match *self.value_def.borrow() {
689 Some(ref def) => def.is_public, None => false
694 fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
697 match *self.type_def.borrow() {
699 Some(ref type_def) => {
700 match type_def.type_def {
701 Some(type_def) => Some(type_def),
703 match type_def.module_def {
704 Some(ref module) => {
705 match module.def_id.get() {
706 Some(did) => Some(DefMod(did)),
718 match *self.value_def.borrow() {
720 Some(value_def) => Some(value_def.def)
726 fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
727 if self.defined_in_namespace(namespace) {
730 match *self.type_def.borrow() {
732 Some(ref type_def) => type_def.type_span
736 match *self.value_def.borrow() {
738 Some(ref value_def) => value_def.value_span
748 fn NameBindings() -> NameBindings {
750 type_def: RefCell::new(None),
751 value_def: RefCell::new(None),
755 /// Interns the names of the primitive types.
756 struct PrimitiveTypeTable {
757 primitive_types: HashMap<Name, PrimTy>,
760 impl PrimitiveTypeTable {
761 fn intern(&mut self, string: &str, primitive_type: PrimTy) {
762 self.primitive_types.insert(token::intern(string), primitive_type);
766 fn PrimitiveTypeTable() -> PrimitiveTypeTable {
767 let mut table = PrimitiveTypeTable {
768 primitive_types: HashMap::new()
771 table.intern("bool", TyBool);
772 table.intern("char", TyChar);
773 table.intern("f32", TyFloat(TyF32));
774 table.intern("f64", TyFloat(TyF64));
775 table.intern("f128", TyFloat(TyF128));
776 table.intern("int", TyInt(TyI));
777 table.intern("i8", TyInt(TyI8));
778 table.intern("i16", TyInt(TyI16));
779 table.intern("i32", TyInt(TyI32));
780 table.intern("i64", TyInt(TyI64));
781 table.intern("str", TyStr);
782 table.intern("uint", TyUint(TyU));
783 table.intern("u8", TyUint(TyU8));
784 table.intern("u16", TyUint(TyU16));
785 table.intern("u32", TyUint(TyU32));
786 table.intern("u64", TyUint(TyU64));
792 fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
795 ModuleError => "module",
797 ValueError => "value",
801 fn Resolver<'a>(session: &'a Session,
802 lang_items: &'a LanguageItems,
803 crate_span: Span) -> Resolver<'a> {
804 let graph_root = NameBindings();
806 graph_root.define_module(NoParentLink,
807 Some(DefId { krate: 0, node: 0 }),
813 let current_module = graph_root.get_module();
815 let this = Resolver {
817 lang_items: lang_items,
819 // The outermost module has def ID 0; this is not reflected in the
822 graph_root: graph_root,
824 method_set: RefCell::new(FnvHashSet::new()),
825 structs: HashSet::new(),
827 unresolved_imports: 0,
829 current_module: current_module,
830 value_ribs: RefCell::new(Vec::new()),
831 type_ribs: RefCell::new(Vec::new()),
832 label_ribs: RefCell::new(Vec::new()),
834 current_trait_refs: None,
836 self_ident: special_idents::self_,
837 type_self_ident: special_idents::type_self,
839 primitive_type_table: PrimitiveTypeTable(),
841 namespaces: vec!(TypeNS, ValueNS),
843 def_map: RefCell::new(NodeMap::new()),
844 export_map2: RefCell::new(NodeMap::new()),
845 trait_map: NodeMap::new(),
846 used_imports: HashSet::new(),
847 external_exports: DefIdSet::new(),
848 last_private: NodeMap::new(),
856 /// The main resolver class.
857 struct Resolver<'a> {
858 session: &'a Session,
859 lang_items: &'a LanguageItems,
861 graph_root: NameBindings,
863 method_set: RefCell<FnvHashSet<(Name, DefId)>>,
864 structs: HashSet<DefId>,
866 // The number of imports that are currently unresolved.
867 unresolved_imports: uint,
869 // The module that represents the current item scope.
870 current_module: Rc<Module>,
872 // The current set of local scopes, for values.
873 // FIXME #4948: Reuse ribs to avoid allocation.
874 value_ribs: RefCell<Vec<Rib>>,
876 // The current set of local scopes, for types.
877 type_ribs: RefCell<Vec<Rib>>,
879 // The current set of local scopes, for labels.
880 label_ribs: RefCell<Vec<Rib>>,
882 // The trait that the current context can refer to.
883 current_trait_refs: Option<Vec<DefId> >,
885 // The ident for the keyword "self".
887 // The ident for the non-keyword "Self".
888 type_self_ident: Ident,
890 // The idents for the primitive types.
891 primitive_type_table: PrimitiveTypeTable,
893 // The four namespaces.
894 namespaces: Vec<Namespace> ,
897 export_map2: ExportMap2,
899 external_exports: ExternalExports,
900 last_private: LastPrivateMap,
902 // Whether or not to print error messages. Can be set to true
903 // when getting additional info for error message suggestions,
904 // so as to avoid printing duplicate errors
907 used_imports: HashSet<(NodeId, Namespace)>,
910 struct BuildReducedGraphVisitor<'a, 'b> {
911 resolver: &'a mut Resolver<'b>,
914 impl<'a, 'b> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a, 'b> {
916 fn visit_item(&mut self, item: &Item, context: ReducedGraphParent) {
917 let p = self.resolver.build_reduced_graph_for_item(item, context);
918 visit::walk_item(self, item, p);
921 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem,
922 context: ReducedGraphParent) {
923 self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
926 let mut v = BuildReducedGraphVisitor{ resolver: r };
927 visit::walk_foreign_item(&mut v, foreign_item, context.clone());
931 fn visit_view_item(&mut self, view_item: &ViewItem, context: ReducedGraphParent) {
932 self.resolver.build_reduced_graph_for_view_item(view_item, context);
935 fn visit_block(&mut self, block: &Block, context: ReducedGraphParent) {
936 let np = self.resolver.build_reduced_graph_for_block(block, context);
937 visit::walk_block(self, block, np);
942 struct UnusedImportCheckVisitor<'a, 'b> { resolver: &'a mut Resolver<'b> }
944 impl<'a, 'b> Visitor<()> for UnusedImportCheckVisitor<'a, 'b> {
945 fn visit_view_item(&mut self, vi: &ViewItem, _: ()) {
946 self.resolver.check_for_item_unused_imports(vi);
947 visit::walk_view_item(self, vi, ());
951 impl<'a> Resolver<'a> {
952 /// The main name resolution procedure.
953 fn resolve(&mut self, krate: &ast::Crate) {
954 self.build_reduced_graph(krate);
955 self.session.abort_if_errors();
957 self.resolve_imports();
958 self.session.abort_if_errors();
960 self.record_exports();
961 self.session.abort_if_errors();
963 self.resolve_crate(krate);
964 self.session.abort_if_errors();
966 self.check_for_unused_imports(krate);
970 // Reduced graph building
972 // Here we build the "reduced graph": the graph of the module tree without
973 // any imports resolved.
976 /// Constructs the reduced graph for the entire crate.
977 fn build_reduced_graph(&mut self, krate: &ast::Crate) {
979 ModuleReducedGraphParent(self.graph_root.get_module());
981 let mut visitor = BuildReducedGraphVisitor { resolver: self, };
982 visit::walk_crate(&mut visitor, krate, initial_parent);
986 * Adds a new child item to the module definition of the parent node and
987 * returns its corresponding name bindings as well as the current parent.
988 * Or, if we're inside a block, creates (or reuses) an anonymous module
989 * corresponding to the innermost block ID and returns the name bindings
990 * as well as the newly-created parent.
992 * If this node does not have a module definition and we are not inside
997 reduced_graph_parent: ReducedGraphParent,
998 duplicate_checking_mode: DuplicateCheckingMode,
999 // For printing errors
1001 -> Rc<NameBindings> {
1002 // If this is the immediate descendant of a module, then we add the
1003 // child name directly. Otherwise, we create or reuse an anonymous
1004 // module and add the child to that.
1006 let module_ = reduced_graph_parent.module();
1008 // Add or reuse the child.
1009 let child = module_.children.borrow().find_copy(&name.name);
1012 let child = Rc::new(NameBindings());
1013 module_.children.borrow_mut().insert(name.name, child.clone());
1017 // Enforce the duplicate checking mode:
1019 // * If we're requesting duplicate module checking, check that
1020 // there isn't a module in the module with the same name.
1022 // * If we're requesting duplicate type checking, check that
1023 // there isn't a type in the module with the same name.
1025 // * If we're requesting duplicate value checking, check that
1026 // there isn't a value in the module with the same name.
1028 // * If we're requesting duplicate type checking and duplicate
1029 // value checking, check that there isn't a duplicate type
1030 // and a duplicate value with the same name.
1032 // * If no duplicate checking was requested at all, do
1035 let mut duplicate_type = NoError;
1036 let ns = match duplicate_checking_mode {
1037 ForbidDuplicateModules => {
1038 if child.get_module_if_available().is_some() {
1039 duplicate_type = ModuleError;
1043 ForbidDuplicateTypes => {
1044 match child.def_for_namespace(TypeNS) {
1045 Some(DefMod(_)) | None => {}
1046 Some(_) => duplicate_type = TypeError
1050 ForbidDuplicateValues => {
1051 if child.defined_in_namespace(ValueNS) {
1052 duplicate_type = ValueError;
1056 ForbidDuplicateTypesAndValues => {
1058 match child.def_for_namespace(TypeNS) {
1059 Some(DefMod(_)) | None => {}
1062 duplicate_type = TypeError;
1065 if child.defined_in_namespace(ValueNS) {
1066 duplicate_type = ValueError;
1071 OverwriteDuplicates => None
1073 if duplicate_type != NoError {
1074 // Return an error here by looking up the namespace that
1075 // had the duplicate.
1076 let ns = ns.unwrap();
1077 self.resolve_error(sp,
1078 format!("duplicate definition of {} `{}`",
1079 namespace_error_to_str(duplicate_type),
1080 token::get_ident(name)));
1082 let r = child.span_for_namespace(ns);
1083 for sp in r.iter() {
1084 self.session.span_note(*sp,
1085 format!("first definition of {} `{}` here",
1086 namespace_error_to_str(duplicate_type),
1087 token::get_ident(name)));
1096 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1097 // If the block has view items, we need an anonymous module.
1098 if block.view_items.len() > 0 {
1102 // Check each statement.
1103 for statement in block.stmts.iter() {
1104 match statement.node {
1105 StmtDecl(declaration, _) => {
1106 match declaration.node {
1121 // If we found neither view items nor items, we don't need to create
1122 // an anonymous module.
1127 fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Ident)
1130 ModuleReducedGraphParent(module_) => {
1131 return ModuleParentLink(module_.downgrade(), name);
1136 /// Constructs the reduced graph for one item.
1137 fn build_reduced_graph_for_item(&mut self,
1139 parent: ReducedGraphParent)
1140 -> ReducedGraphParent
1142 let ident = item.ident;
1144 let is_public = item.vis == ast::Public;
1149 self.add_child(ident, parent.clone(), ForbidDuplicateModules, sp);
1151 let parent_link = self.get_parent_link(parent, ident);
1152 let def_id = DefId { krate: 0, node: item.id };
1153 name_bindings.define_module(parent_link,
1157 item.vis == ast::Public,
1160 ModuleReducedGraphParent(name_bindings.get_module())
1163 ItemForeignMod(..) => parent,
1165 // These items live in the value namespace.
1166 ItemStatic(_, m, _) => {
1168 self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
1169 let mutbl = m == ast::MutMutable;
1171 name_bindings.define_value
1172 (DefStatic(local_def(item.id), mutbl), sp, is_public);
1175 ItemFn(_, fn_style, _, _, _) => {
1177 self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
1179 let def = DefFn(local_def(item.id), fn_style);
1180 name_bindings.define_value(def, sp, is_public);
1184 // These items live in the type namespace.
1187 self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp);
1189 name_bindings.define_type
1190 (DefTy(local_def(item.id)), sp, is_public);
1194 ItemEnum(ref enum_definition, _) => {
1196 self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp);
1198 name_bindings.define_type
1199 (DefTy(local_def(item.id)), sp, is_public);
1201 for &variant in (*enum_definition).variants.iter() {
1202 self.build_reduced_graph_for_variant(
1211 // These items live in both the type and value namespaces.
1212 ItemStruct(struct_def, _) => {
1213 // Adding to both Type and Value namespaces or just Type?
1214 let (forbid, ctor_id) = match struct_def.ctor_id {
1215 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1216 None => (ForbidDuplicateTypes, None)
1219 let name_bindings = self.add_child(ident, parent.clone(), forbid, sp);
1221 // Define a name in the type namespace.
1222 name_bindings.define_type(DefTy(local_def(item.id)), sp, is_public);
1224 // If this is a newtype or unit-like struct, define a name
1225 // in the value namespace as well
1226 ctor_id.while_some(|cid| {
1227 name_bindings.define_value(DefStruct(local_def(cid)), sp,
1232 // Record the def ID of this struct.
1233 self.structs.insert(local_def(item.id));
1238 ItemImpl(_, None, ty, ref methods) => {
1239 // If this implements an anonymous trait, then add all the
1240 // methods within to a new module, if the type was defined
1241 // within this module.
1243 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1244 // should modify anonymous traits to only be implementable in
1245 // the same module that declared the type.
1247 // Create the module and add all methods.
1249 TyPath(ref path, _, _) if path.segments.len() == 1 => {
1250 let name = path_to_ident(path);
1252 let parent_opt = parent.module().children.borrow()
1253 .find_copy(&name.name);
1254 let new_parent = match parent_opt {
1255 // It already exists
1256 Some(ref child) if child.get_module_if_available()
1258 child.get_module().kind.get() ==
1260 ModuleReducedGraphParent(child.get_module())
1262 // Create the module
1265 self.add_child(name,
1267 ForbidDuplicateModules,
1271 self.get_parent_link(parent.clone(), ident);
1272 let def_id = local_def(item.id);
1275 !name_bindings.defined_in_namespace(ns) ||
1276 name_bindings.defined_in_public_namespace(ns);
1278 name_bindings.define_module(parent_link,
1285 ModuleReducedGraphParent(
1286 name_bindings.get_module())
1290 // For each method...
1291 for method in methods.iter() {
1292 // Add the method to the module.
1293 let ident = method.ident;
1294 let method_name_bindings =
1295 self.add_child(ident,
1297 ForbidDuplicateValues,
1299 let def = match method.explicit_self.node {
1301 // Static methods become
1302 // `def_static_method`s.
1303 DefStaticMethod(local_def(method.id),
1309 // Non-static methods become
1311 DefMethod(local_def(method.id), None)
1315 let is_public = method.vis == ast::Public;
1316 method_name_bindings.define_value(def,
1327 ItemImpl(_, Some(_), _, _) => parent,
1329 ItemTrait(_, _, _, ref methods) => {
1331 self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp);
1333 // Add all the methods within to a new module.
1334 let parent_link = self.get_parent_link(parent.clone(), ident);
1335 name_bindings.define_module(parent_link,
1336 Some(local_def(item.id)),
1339 item.vis == ast::Public,
1341 let module_parent = ModuleReducedGraphParent(name_bindings.
1344 let def_id = local_def(item.id);
1346 // Add the names of all the methods to the trait info.
1347 for method in methods.iter() {
1348 let ty_m = trait_method_to_ty_method(method);
1350 let ident = ty_m.ident;
1352 // Add it as a name in the trait module.
1353 let def = match ty_m.explicit_self.node {
1355 // Static methods become `def_static_method`s.
1356 DefStaticMethod(local_def(ty_m.id),
1357 FromTrait(local_def(item.id)),
1361 // Non-static methods become `def_method`s.
1362 DefMethod(local_def(ty_m.id),
1363 Some(local_def(item.id)))
1367 let method_name_bindings =
1368 self.add_child(ident,
1369 module_parent.clone(),
1370 ForbidDuplicateValues,
1372 method_name_bindings.define_value(def, ty_m.span, true);
1374 // Add it to the trait info if not static.
1375 if ty_m.explicit_self.node != SelfStatic {
1376 self.method_set.borrow_mut().insert((ident.name, def_id));
1380 name_bindings.define_type(DefTrait(def_id), sp, is_public);
1383 ItemMac(..) => parent
1387 // Constructs the reduced graph for one variant. Variants exist in the
1388 // type and/or value namespaces.
1389 fn build_reduced_graph_for_variant(&mut self,
1392 parent: ReducedGraphParent,
1394 let ident = variant.node.name;
1396 match variant.node.kind {
1397 TupleVariantKind(_) => {
1398 let child = self.add_child(ident, parent, ForbidDuplicateValues, variant.span);
1399 child.define_value(DefVariant(item_id,
1400 local_def(variant.node.id), false),
1401 variant.span, is_public);
1403 StructVariantKind(_) => {
1404 let child = self.add_child(ident, parent,
1405 ForbidDuplicateTypesAndValues,
1407 child.define_type(DefVariant(item_id,
1408 local_def(variant.node.id), true),
1409 variant.span, is_public);
1410 self.structs.insert(local_def(variant.node.id));
1415 /// Constructs the reduced graph for one 'view item'. View items consist
1416 /// of imports and use directives.
1417 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1418 parent: ReducedGraphParent) {
1419 match view_item.node {
1420 ViewItemUse(ref view_paths) => {
1421 for view_path in view_paths.iter() {
1422 // Extract and intern the module part of the path. For
1423 // globs and lists, the path is found directly in the AST;
1424 // for simple paths we have to munge the path a little.
1426 let mut module_path = Vec::new();
1427 match view_path.node {
1428 ViewPathSimple(_, ref full_path, _) => {
1429 let path_len = full_path.segments.len();
1430 assert!(path_len != 0);
1432 for (i, segment) in full_path.segments
1435 if i != path_len - 1 {
1436 module_path.push(segment.identifier)
1441 ViewPathGlob(ref module_ident_path, _) |
1442 ViewPathList(ref module_ident_path, _, _) => {
1443 for segment in module_ident_path.segments.iter() {
1444 module_path.push(segment.identifier)
1449 // Build up the import directives.
1450 let module_ = parent.module();
1451 let is_public = view_item.vis == ast::Public;
1452 match view_path.node {
1453 ViewPathSimple(binding, ref full_path, id) => {
1455 full_path.segments.last().unwrap().identifier;
1456 let subclass = SingleImport(binding,
1458 self.build_import_directive(&*module_,
1465 ViewPathList(_, ref source_idents, _) => {
1466 for source_ident in source_idents.iter() {
1467 let name = source_ident.node.name;
1468 self.build_import_directive(
1470 module_path.clone(),
1471 SingleImport(name, name),
1473 source_ident.node.id,
1477 ViewPathGlob(_, id) => {
1478 self.build_import_directive(&*module_,
1489 ViewItemExternCrate(name, _, node_id) => {
1490 // n.b. we don't need to look at the path option here, because cstore already did
1491 match self.session.cstore.find_extern_mod_stmt_cnum(node_id) {
1493 let def_id = DefId { krate: crate_id, node: 0 };
1494 self.external_exports.insert(def_id);
1495 let parent_link = ModuleParentLink
1496 (parent.module().downgrade(), name);
1497 let external_module = Rc::new(Module::new(parent_link,
1503 parent.module().external_module_children
1504 .borrow_mut().insert(name.name,
1505 external_module.clone());
1507 self.build_reduced_graph_for_external_crate(
1510 None => {} // Ignore.
1516 /// Constructs the reduced graph for one foreign item.
1517 fn build_reduced_graph_for_foreign_item(&mut self,
1518 foreign_item: &ForeignItem,
1519 parent: ReducedGraphParent,
1520 f: |&mut Resolver|) {
1521 let name = foreign_item.ident;
1522 let is_public = foreign_item.vis == ast::Public;
1524 self.add_child(name, parent, ForbidDuplicateValues,
1527 match foreign_item.node {
1528 ForeignItemFn(_, ref generics) => {
1529 let def = DefFn(local_def(foreign_item.id), UnsafeFn);
1530 name_bindings.define_value(def, foreign_item.span, is_public);
1532 self.with_type_parameter_rib(
1533 HasTypeParameters(generics,
1539 ForeignItemStatic(_, m) => {
1540 let def = DefStatic(local_def(foreign_item.id), m);
1541 name_bindings.define_value(def, foreign_item.span, is_public);
1548 fn build_reduced_graph_for_block(&mut self,
1550 parent: ReducedGraphParent)
1551 -> ReducedGraphParent
1553 if self.block_needs_anonymous_module(block) {
1554 let block_id = block.id;
1556 debug!("(building reduced graph for block) creating a new \
1557 anonymous module for block {}",
1560 let parent_module = parent.module();
1561 let new_module = Rc::new(Module::new(
1562 BlockParentLink(parent_module.downgrade(), block_id),
1564 AnonymousModuleKind,
1567 parent_module.anonymous_children.borrow_mut()
1568 .insert(block_id, new_module.clone());
1569 ModuleReducedGraphParent(new_module)
1575 fn handle_external_def(&mut self,
1578 child_name_bindings: &NameBindings,
1581 new_parent: ReducedGraphParent) {
1582 debug!("(building reduced graph for \
1583 external crate) building external def, priv {:?}",
1585 let is_public = vis == ast::Public;
1586 let is_exported = is_public && match new_parent {
1587 ModuleReducedGraphParent(ref module) => {
1588 match module.def_id.get() {
1590 Some(did) => self.external_exports.contains(&did)
1595 self.external_exports.insert(def_id_of_def(def));
1598 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1600 let type_def = child_name_bindings.type_def.borrow().clone();
1602 Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1603 debug!("(building reduced graph for external crate) \
1604 already created module");
1605 module_def.def_id.set(Some(def_id));
1608 debug!("(building reduced graph for \
1609 external crate) building module \
1611 let parent_link = self.get_parent_link(new_parent.clone(), ident);
1613 child_name_bindings.define_module(parent_link,
1626 DefMod(_) | DefForeignMod(_) => {}
1627 DefVariant(_, variant_id, is_struct) => {
1628 debug!("(building reduced graph for external crate) building \
1631 // We assume the parent is visible, or else we wouldn't have seen
1632 // it. Also variants are public-by-default if the parent was also
1635 child_name_bindings.define_type(def, DUMMY_SP, true);
1636 self.structs.insert(variant_id);
1638 child_name_bindings.define_value(def, DUMMY_SP, true);
1641 DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
1642 debug!("(building reduced graph for external \
1643 crate) building value (fn/static) {}", final_ident);
1644 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1646 DefTrait(def_id) => {
1647 debug!("(building reduced graph for external \
1648 crate) building type {}", final_ident);
1650 // If this is a trait, add all the method names
1651 // to the trait info.
1653 let method_def_ids =
1654 csearch::get_trait_method_def_ids(&self.session.cstore, def_id);
1655 for &method_def_id in method_def_ids.iter() {
1656 let (method_name, explicit_self) =
1657 csearch::get_method_name_and_explicit_self(&self.session.cstore,
1660 debug!("(building reduced graph for \
1661 external crate) ... adding \
1663 token::get_ident(method_name));
1665 // Add it to the trait info if not static.
1666 if explicit_self != SelfStatic {
1667 self.method_set.borrow_mut().insert((method_name.name, def_id));
1670 self.external_exports.insert(method_def_id);
1674 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1676 // Define a module if necessary.
1677 let parent_link = self.get_parent_link(new_parent, ident);
1678 child_name_bindings.set_module_kind(parent_link,
1686 debug!("(building reduced graph for external \
1687 crate) building type {}", final_ident);
1689 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1691 DefStruct(def_id) => {
1692 debug!("(building reduced graph for external \
1693 crate) building type and value for {}",
1695 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1696 if csearch::get_struct_fields(&self.session.cstore, def_id).len() == 0 {
1697 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1699 self.structs.insert(def_id);
1702 debug!("(building reduced graph for external crate) \
1703 ignoring {:?}", def);
1704 // Ignored; handled elsewhere.
1706 DefArg(..) | DefLocal(..) | DefPrimTy(..) |
1707 DefTyParam(..) | DefBinding(..) |
1708 DefUse(..) | DefUpvar(..) | DefRegion(..) |
1709 DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
1710 fail!("didn't expect `{:?}`", def);
1715 /// Builds the reduced graph for a single item in an external crate.
1716 fn build_reduced_graph_for_external_crate_def(&mut self,
1720 visibility: Visibility) {
1723 // Add the new child item, if necessary.
1725 DefForeignMod(def_id) => {
1726 // Foreign modules have no names. Recur and populate
1728 csearch::each_child_of_item(&self.session.cstore,
1733 self.build_reduced_graph_for_external_crate_def(
1741 let child_name_bindings =
1742 self.add_child(ident,
1743 ModuleReducedGraphParent(root.clone()),
1744 OverwriteDuplicates,
1747 self.handle_external_def(def,
1749 &*child_name_bindings,
1750 token::get_ident(ident).get(),
1752 ModuleReducedGraphParent(root));
1757 // We only process static methods of impls here.
1758 match csearch::get_type_name_if_impl(&self.session.cstore, def) {
1760 Some(final_ident) => {
1761 let static_methods_opt =
1762 csearch::get_static_methods_if_impl(&self.session.cstore, def);
1763 match static_methods_opt {
1764 Some(ref static_methods) if
1765 static_methods.len() >= 1 => {
1766 debug!("(building reduced graph for \
1767 external crate) processing \
1768 static methods for type name {}",
1769 token::get_ident(final_ident));
1771 let child_name_bindings =
1774 ModuleReducedGraphParent(root.clone()),
1775 OverwriteDuplicates,
1778 // Process the static methods. First,
1779 // create the module.
1781 let type_def = child_name_bindings.type_def.borrow().clone();
1784 module_def: Some(module_def),
1787 // We already have a module. This
1789 type_module = module_def;
1791 // Mark it as an impl module if
1793 type_module.kind.set(ImplModuleKind);
1797 self.get_parent_link(ModuleReducedGraphParent(root),
1799 child_name_bindings.define_module(
1807 child_name_bindings.
1812 // Add each static method to the module.
1814 ModuleReducedGraphParent(type_module);
1815 for static_method_info in
1816 static_methods.iter() {
1817 let ident = static_method_info.ident;
1818 debug!("(building reduced graph for \
1819 external crate) creating \
1820 static method '{}'",
1821 token::get_ident(ident));
1823 let method_name_bindings =
1824 self.add_child(ident,
1826 OverwriteDuplicates,
1829 static_method_info.def_id,
1830 static_method_info.fn_style);
1832 method_name_bindings.define_value(
1834 visibility == ast::Public);
1838 // Otherwise, do nothing.
1839 Some(_) | None => {}
1845 debug!("(building reduced graph for external crate) \
1851 /// Builds the reduced graph rooted at the given external module.
1852 fn populate_external_module(&mut self, module: Rc<Module>) {
1853 debug!("(populating external module) attempting to populate {}",
1854 self.module_to_str(&*module));
1856 let def_id = match module.def_id.get() {
1858 debug!("(populating external module) ... no def ID!");
1861 Some(def_id) => def_id,
1864 csearch::each_child_of_item(&self.session.cstore,
1866 |def_like, child_ident, visibility| {
1867 debug!("(populating external module) ... found ident: {}",
1868 token::get_ident(child_ident));
1869 self.build_reduced_graph_for_external_crate_def(module.clone(),
1874 module.populated.set(true)
1877 /// Ensures that the reduced graph rooted at the given external module
1878 /// is built, building it if it is not.
1879 fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
1880 if !module.populated.get() {
1881 self.populate_external_module(module.clone())
1883 assert!(module.populated.get())
1886 /// Builds the reduced graph rooted at the 'use' directive for an external
1888 fn build_reduced_graph_for_external_crate(&mut self, root: Rc<Module>) {
1889 csearch::each_top_level_item_of_crate(&self.session.cstore,
1894 |def_like, ident, visibility| {
1895 self.build_reduced_graph_for_external_crate_def(root.clone(),
1902 /// Creates and adds an import directive to the given module.
1903 fn build_import_directive(&mut self,
1905 module_path: Vec<Ident> ,
1906 subclass: ImportDirectiveSubclass,
1910 module_.imports.borrow_mut().push(ImportDirective::new(module_path,
1914 self.unresolved_imports += 1;
1915 // Bump the reference count on the name. Or, if this is a glob, set
1916 // the appropriate flag.
1919 SingleImport(target, _) => {
1920 debug!("(building import directive) building import \
1922 self.idents_to_str(module_.imports.borrow().last().unwrap()
1923 .module_path.as_slice()),
1924 token::get_ident(target));
1926 let mut import_resolutions = module_.import_resolutions
1928 match import_resolutions.find_mut(&target.name) {
1929 Some(resolution) => {
1930 debug!("(building import directive) bumping \
1932 resolution.outstanding_references += 1;
1934 // the source of this name is different now
1935 resolution.type_id = id;
1936 resolution.value_id = id;
1937 resolution.is_public = is_public;
1942 debug!("(building import directive) creating new");
1943 let mut resolution = ImportResolution::new(id, is_public);
1944 resolution.outstanding_references = 1;
1945 import_resolutions.insert(target.name, resolution);
1948 // Set the glob flag. This tells us that we don't know the
1949 // module's exports ahead of time.
1951 module_.glob_count.set(module_.glob_count.get() + 1);
1956 // Import resolution
1958 // This is a fixed-point algorithm. We resolve imports until our efforts
1959 // are stymied by an unresolved import; then we bail out of the current
1960 // module and continue. We terminate successfully once no more imports
1961 // remain or unsuccessfully when no forward progress in resolving imports
1964 /// Resolves all imports for the crate. This method performs the fixed-
1965 /// point iteration.
1966 fn resolve_imports(&mut self) {
1968 let mut prev_unresolved_imports = 0;
1970 debug!("(resolving imports) iteration {}, {} imports left",
1971 i, self.unresolved_imports);
1973 let module_root = self.graph_root.get_module();
1974 self.resolve_imports_for_module_subtree(module_root.clone());
1976 if self.unresolved_imports == 0 {
1977 debug!("(resolving imports) success");
1981 if self.unresolved_imports == prev_unresolved_imports {
1982 self.report_unresolved_imports(module_root);
1987 prev_unresolved_imports = self.unresolved_imports;
1991 /// Attempts to resolve imports for the given module and all of its
1993 fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
1994 debug!("(resolving imports for module subtree) resolving {}",
1995 self.module_to_str(&*module_));
1996 self.resolve_imports_for_module(module_.clone());
1998 self.populate_module_if_necessary(&module_);
1999 for (_, child_node) in module_.children.borrow().iter() {
2000 match child_node.get_module_if_available() {
2004 Some(child_module) => {
2005 self.resolve_imports_for_module_subtree(child_module);
2010 for (_, child_module) in module_.anonymous_children.borrow().iter() {
2011 self.resolve_imports_for_module_subtree(child_module.clone());
2015 /// Attempts to resolve imports for the given module only.
2016 fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
2017 if module.all_imports_resolved() {
2018 debug!("(resolving imports for module) all imports resolved for \
2020 self.module_to_str(&*module));
2024 let mut imports = module.imports.borrow_mut();
2025 let import_count = imports.len();
2026 while module.resolved_import_count.get() < import_count {
2027 let import_index = module.resolved_import_count.get();
2028 let import_directive = imports.get(import_index);
2029 match self.resolve_import_for_module(module.clone(), import_directive) {
2031 // We presumably emitted an error. Continue.
2032 let msg = format!("failed to resolve import `{}`",
2033 self.import_path_to_str(
2034 import_directive.module_path
2036 import_directive.subclass));
2037 self.resolve_error(import_directive.span, msg);
2040 // Bail out. We'll come around next time.
2048 module.resolved_import_count
2049 .set(module.resolved_import_count.get() + 1);
2053 fn idents_to_str(&mut self, idents: &[Ident]) -> ~str {
2054 let mut first = true;
2055 let mut result = StrBuf::new();
2056 for ident in idents.iter() {
2060 result.push_str("::")
2062 result.push_str(token::get_ident(*ident).get());
2067 fn path_idents_to_str(&mut self, path: &Path) -> ~str {
2068 let identifiers: Vec<ast::Ident> = path.segments
2070 .map(|seg| seg.identifier)
2072 self.idents_to_str(identifiers.as_slice())
2075 fn import_directive_subclass_to_str(&mut self,
2076 subclass: ImportDirectiveSubclass)
2079 SingleImport(_, source) => {
2080 token::get_ident(source).get().to_str()
2082 GlobImport => "*".to_owned()
2086 fn import_path_to_str(&mut self,
2088 subclass: ImportDirectiveSubclass)
2090 if idents.is_empty() {
2091 self.import_directive_subclass_to_str(subclass)
2094 self.idents_to_str(idents),
2095 self.import_directive_subclass_to_str(subclass)))
2099 /// Attempts to resolve the given import. The return value indicates
2100 /// failure if we're certain the name does not exist, indeterminate if we
2101 /// don't know whether the name exists at the moment due to other
2102 /// currently-unresolved imports, or success if we know the name exists.
2103 /// If successful, the resolved bindings are written into the module.
2104 fn resolve_import_for_module(&mut self,
2105 module_: Rc<Module>,
2106 import_directive: &ImportDirective)
2107 -> ResolveResult<()> {
2108 let mut resolution_result = Failed;
2109 let module_path = &import_directive.module_path;
2111 debug!("(resolving import for module) resolving import `{}::...` in \
2113 self.idents_to_str(module_path.as_slice()),
2114 self.module_to_str(&*module_));
2116 // First, resolve the module path for the directive, if necessary.
2117 let container = if module_path.len() == 0 {
2118 // Use the crate root.
2119 Some((self.graph_root.get_module(), LastMod(AllPublic)))
2121 match self.resolve_module_path(module_.clone(),
2122 module_path.as_slice(),
2123 DontUseLexicalScope,
2124 import_directive.span,
2129 resolution_result = Indeterminate;
2132 Success(container) => Some(container),
2138 Some((containing_module, lp)) => {
2139 // We found the module that the target is contained
2140 // within. Attempt to resolve the import within it.
2142 match import_directive.subclass {
2143 SingleImport(target, source) => {
2145 self.resolve_single_import(&*module_,
2154 self.resolve_glob_import(&*module_,
2156 import_directive.id,
2157 import_directive.is_public,
2164 // Decrement the count of unresolved imports.
2165 match resolution_result {
2167 assert!(self.unresolved_imports >= 1);
2168 self.unresolved_imports -= 1;
2171 // Nothing to do here; just return the error.
2175 // Decrement the count of unresolved globs if necessary. But only if
2176 // the resolution result is indeterminate -- otherwise we'll stop
2177 // processing imports here. (See the loop in
2178 // resolve_imports_for_module.)
2180 if !resolution_result.indeterminate() {
2181 match import_directive.subclass {
2183 assert!(module_.glob_count.get() >= 1);
2184 module_.glob_count.set(module_.glob_count.get() - 1);
2186 SingleImport(..) => {
2192 return resolution_result;
2195 fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
2197 type_def: RefCell::new(Some(TypeNsDef {
2199 module_def: Some(module),
2203 value_def: RefCell::new(None),
2207 fn resolve_single_import(&mut self,
2209 containing_module: Rc<Module>,
2212 directive: &ImportDirective,
2214 -> ResolveResult<()> {
2215 debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2216 `{}` id {}, last private {:?}",
2217 token::get_ident(target),
2218 self.module_to_str(&*containing_module),
2219 token::get_ident(source),
2220 self.module_to_str(module_),
2226 LastImport{..} => self.session.span_bug(directive.span,
2227 "Not expecting Import here, must be LastMod"),
2230 // We need to resolve both namespaces for this to succeed.
2233 let mut value_result = UnknownResult;
2234 let mut type_result = UnknownResult;
2236 // Search for direct children of the containing module.
2237 self.populate_module_if_necessary(&containing_module);
2239 match containing_module.children.borrow().find(&source.name) {
2243 Some(ref child_name_bindings) => {
2244 if child_name_bindings.defined_in_namespace(ValueNS) {
2245 debug!("(resolving single import) found value binding");
2246 value_result = BoundResult(containing_module.clone(),
2247 (*child_name_bindings).clone());
2249 if child_name_bindings.defined_in_namespace(TypeNS) {
2250 debug!("(resolving single import) found type binding");
2251 type_result = BoundResult(containing_module.clone(),
2252 (*child_name_bindings).clone());
2257 // Unless we managed to find a result in both namespaces (unlikely),
2258 // search imports as well.
2259 let mut value_used_reexport = false;
2260 let mut type_used_reexport = false;
2261 match (value_result.clone(), type_result.clone()) {
2262 (BoundResult(..), BoundResult(..)) => {} // Continue.
2264 // If there is an unresolved glob at this point in the
2265 // containing module, bail out. We don't know enough to be
2266 // able to resolve this import.
2268 if containing_module.glob_count.get() > 0 {
2269 debug!("(resolving single import) unresolved glob; \
2271 return Indeterminate;
2274 // Now search the exported imports within the containing module.
2275 match containing_module.import_resolutions.borrow().find(&source.name) {
2277 debug!("(resolving single import) no import");
2278 // The containing module definitely doesn't have an
2279 // exported import with the name in question. We can
2280 // therefore accurately report that the names are
2283 if value_result.is_unknown() {
2284 value_result = UnboundResult;
2286 if type_result.is_unknown() {
2287 type_result = UnboundResult;
2290 Some(import_resolution)
2291 if import_resolution.outstanding_references == 0 => {
2293 fn get_binding(this: &mut Resolver,
2294 import_resolution: &ImportResolution,
2295 namespace: Namespace)
2296 -> NamespaceResult {
2298 // Import resolutions must be declared with "pub"
2299 // in order to be exported.
2300 if !import_resolution.is_public {
2301 return UnboundResult;
2304 match import_resolution.
2305 target_for_namespace(namespace) {
2307 return UnboundResult;
2309 Some(Target {target_module, bindings}) => {
2310 debug!("(resolving single import) found \
2311 import in ns {:?}", namespace);
2312 let id = import_resolution.id(namespace);
2313 this.used_imports.insert((id, namespace));
2314 return BoundResult(target_module, bindings);
2319 // The name is an import which has been fully
2320 // resolved. We can, therefore, just follow it.
2321 if value_result.is_unknown() {
2322 value_result = get_binding(self, import_resolution,
2324 value_used_reexport = import_resolution.is_public;
2326 if type_result.is_unknown() {
2327 type_result = get_binding(self, import_resolution,
2329 type_used_reexport = import_resolution.is_public;
2334 // The import is unresolved. Bail out.
2335 debug!("(resolving single import) unresolved import; \
2337 return Indeterminate;
2343 // If we didn't find a result in the type namespace, search the
2344 // external modules.
2345 let mut value_used_public = false;
2346 let mut type_used_public = false;
2348 BoundResult(..) => {}
2350 match containing_module.external_module_children.borrow_mut()
2351 .find_copy(&source.name) {
2352 None => {} // Continue.
2354 debug!("(resolving single import) found external \
2357 Rc::new(Resolver::create_name_bindings_from_module(
2359 type_result = BoundResult(containing_module.clone(),
2361 type_used_public = true;
2367 // We've successfully resolved the import. Write the results in.
2368 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2369 let import_resolution = import_resolutions.get_mut(&target.name);
2371 match value_result {
2372 BoundResult(ref target_module, ref name_bindings) => {
2373 debug!("(resolving single import) found value target");
2374 import_resolution.value_target = Some(Target::new(target_module.clone(),
2375 name_bindings.clone()));
2376 import_resolution.value_id = directive.id;
2377 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2379 UnboundResult => { /* Continue. */ }
2381 fail!("value result should be known at this point");
2385 BoundResult(ref target_module, ref name_bindings) => {
2386 debug!("(resolving single import) found type target: {:?}",
2387 { name_bindings.type_def.borrow().clone().unwrap().type_def });
2388 import_resolution.type_target =
2389 Some(Target::new(target_module.clone(), name_bindings.clone()));
2390 import_resolution.type_id = directive.id;
2391 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2393 UnboundResult => { /* Continue. */ }
2395 fail!("type result should be known at this point");
2399 if value_result.is_unbound() && type_result.is_unbound() {
2400 let msg = format!("unresolved import: there is no \
2402 token::get_ident(source),
2403 self.module_to_str(&*containing_module));
2404 self.resolve_error(directive.span, msg);
2407 let value_used_public = value_used_reexport || value_used_public;
2408 let type_used_public = type_used_reexport || type_used_public;
2410 assert!(import_resolution.outstanding_references >= 1);
2411 import_resolution.outstanding_references -= 1;
2413 // record what this import resolves to for later uses in documentation,
2414 // this may resolve to either a value or a type, but for documentation
2415 // purposes it's good enough to just favor one over the other.
2416 let value_private = match import_resolution.value_target {
2417 Some(ref target) => {
2418 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2419 self.def_map.borrow_mut().insert(directive.id, def);
2420 let did = def_id_of_def(def);
2421 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2423 // AllPublic here and below is a dummy value, it should never be used because
2424 // _exists is false.
2427 let type_private = match import_resolution.type_target {
2428 Some(ref target) => {
2429 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2430 self.def_map.borrow_mut().insert(directive.id, def);
2431 let did = def_id_of_def(def);
2432 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2437 self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2439 type_priv: type_private,
2442 debug!("(resolving single import) successfully resolved import");
2446 // Resolves a glob import. Note that this function cannot fail; it either
2447 // succeeds or bails out (as importing * from an empty module or a module
2448 // that exports nothing is valid).
2449 fn resolve_glob_import(&mut self,
2451 containing_module: Rc<Module>,
2455 -> ResolveResult<()> {
2456 // This function works in a highly imperative manner; it eagerly adds
2457 // everything it can to the list of import resolutions of the module
2459 debug!("(resolving glob import) resolving glob import {}", id);
2461 // We must bail out if the node has unresolved imports of any kind
2462 // (including globs).
2463 if !(*containing_module).all_imports_resolved() {
2464 debug!("(resolving glob import) target module has unresolved \
2465 imports; bailing out");
2466 return Indeterminate;
2469 assert_eq!(containing_module.glob_count.get(), 0);
2471 // Add all resolved imports from the containing module.
2472 let import_resolutions = containing_module.import_resolutions
2474 for (ident, target_import_resolution) in import_resolutions.iter() {
2475 debug!("(resolving glob import) writing module resolution \
2477 target_import_resolution.type_target.is_none(),
2478 self.module_to_str(module_));
2480 if !target_import_resolution.is_public {
2481 debug!("(resolving glob import) nevermind, just kidding");
2485 // Here we merge two import resolutions.
2486 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2487 match import_resolutions.find_mut(ident) {
2488 Some(dest_import_resolution) => {
2489 // Merge the two import resolutions at a finer-grained
2492 match target_import_resolution.value_target {
2496 Some(ref value_target) => {
2497 dest_import_resolution.value_target =
2498 Some(value_target.clone());
2501 match target_import_resolution.type_target {
2505 Some(ref type_target) => {
2506 dest_import_resolution.type_target =
2507 Some(type_target.clone());
2510 dest_import_resolution.is_public = is_public;
2516 // Simple: just copy the old import resolution.
2517 let mut new_import_resolution = ImportResolution::new(id, is_public);
2518 new_import_resolution.value_target =
2519 target_import_resolution.value_target.clone();
2520 new_import_resolution.type_target =
2521 target_import_resolution.type_target.clone();
2523 import_resolutions.insert(*ident, new_import_resolution);
2526 // Add all children from the containing module.
2527 self.populate_module_if_necessary(&containing_module);
2529 for (&name, name_bindings) in containing_module.children
2531 self.merge_import_resolution(module_, containing_module.clone(),
2533 name, name_bindings.clone());
2536 // Add external module children from the containing module.
2537 for (&name, module) in containing_module.external_module_children
2540 Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
2541 self.merge_import_resolution(module_, containing_module.clone(),
2543 name, name_bindings);
2546 // Record the destination of this import
2547 match containing_module.def_id.get() {
2549 self.def_map.borrow_mut().insert(id, DefMod(did));
2550 self.last_private.insert(id, lp);
2555 debug!("(resolving glob import) successfully resolved import");
2559 fn merge_import_resolution(&mut self,
2561 containing_module: Rc<Module>,
2565 name_bindings: Rc<NameBindings>) {
2566 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2567 let dest_import_resolution = import_resolutions.find_or_insert_with(name, |_| {
2568 // Create a new import resolution from this child.
2569 ImportResolution::new(id, is_public)
2572 debug!("(resolving glob import) writing resolution `{}` in `{}` \
2574 token::get_name(name).get().to_str(),
2575 self.module_to_str(&*containing_module),
2576 self.module_to_str(module_));
2578 // Merge the child item into the import resolution.
2579 if name_bindings.defined_in_public_namespace(ValueNS) {
2580 debug!("(resolving glob import) ... for value target");
2581 dest_import_resolution.value_target =
2582 Some(Target::new(containing_module.clone(), name_bindings.clone()));
2583 dest_import_resolution.value_id = id;
2585 if name_bindings.defined_in_public_namespace(TypeNS) {
2586 debug!("(resolving glob import) ... for type target");
2587 dest_import_resolution.type_target =
2588 Some(Target::new(containing_module, name_bindings.clone()));
2589 dest_import_resolution.type_id = id;
2591 dest_import_resolution.is_public = is_public;
2594 /// Resolves the given module path from the given root `module_`.
2595 fn resolve_module_path_from_root(&mut self,
2596 module_: Rc<Module>,
2597 module_path: &[Ident],
2600 name_search_type: NameSearchType,
2602 -> ResolveResult<(Rc<Module>, LastPrivate)> {
2603 let mut search_module = module_;
2604 let mut index = index;
2605 let module_path_len = module_path.len();
2606 let mut closest_private = lp;
2608 // Resolve the module part of the path. This does not involve looking
2609 // upward though scope chains; we simply resolve names directly in
2610 // modules as we go.
2611 while index < module_path_len {
2612 let name = module_path[index];
2613 match self.resolve_name_in_module(search_module.clone(),
2619 let segment_name = token::get_ident(name);
2620 let module_name = self.module_to_str(&*search_module);
2621 if "???" == module_name {
2624 hi: span.lo + Pos::from_uint(segment_name.get().len()),
2625 expn_info: span.expn_info,
2627 self.resolve_error(span,
2628 format!("unresolved import. maybe \
2629 a missing `extern crate \
2634 self.resolve_error(span, format!("unresolved import: could not find `{}` in \
2635 `{}`.", segment_name, module_name));
2639 debug!("(resolving module path for import) module \
2640 resolution is indeterminate: {}",
2641 token::get_ident(name));
2642 return Indeterminate;
2644 Success((target, used_proxy)) => {
2645 // Check to see whether there are type bindings, and, if
2646 // so, whether there is a module within.
2647 match *target.bindings.type_def.borrow() {
2648 Some(ref type_def) => {
2649 match type_def.module_def {
2652 self.resolve_error(span, format!("not a module `{}`",
2653 token::get_ident(name)));
2656 Some(ref module_def) => {
2657 // If we're doing the search for an
2658 // import, do not allow traits and impls
2660 match (name_search_type,
2661 module_def.kind.get()) {
2662 (ImportSearch, TraitModuleKind) |
2663 (ImportSearch, ImplModuleKind) => {
2666 "cannot import from a trait \
2667 or type implementation");
2671 search_module = module_def.clone();
2673 // Keep track of the closest
2674 // private module used when
2675 // resolving this import chain.
2677 !search_module.is_public {
2678 match search_module.def_id
2682 LastMod(DependsOn(did));
2693 // There are no type bindings at all.
2694 self.resolve_error(span,
2695 format!("not a module `{}`",
2696 token::get_ident(name)));
2706 return Success((search_module, closest_private));
2709 /// Attempts to resolve the module part of an import directive or path
2710 /// rooted at the given module.
2712 /// On success, returns the resolved module, and the closest *private*
2713 /// module found to the destination when resolving this path.
2714 fn resolve_module_path(&mut self,
2715 module_: Rc<Module>,
2716 module_path: &[Ident],
2717 use_lexical_scope: UseLexicalScopeFlag,
2719 name_search_type: NameSearchType)
2720 -> ResolveResult<(Rc<Module>, LastPrivate)> {
2721 let module_path_len = module_path.len();
2722 assert!(module_path_len > 0);
2724 debug!("(resolving module path for import) processing `{}` rooted at \
2726 self.idents_to_str(module_path),
2727 self.module_to_str(&*module_));
2729 // Resolve the module prefix, if any.
2730 let module_prefix_result = self.resolve_module_prefix(module_.clone(),
2736 match module_prefix_result {
2738 let mpath = self.idents_to_str(module_path);
2739 match mpath.rfind(':') {
2741 self.resolve_error(span, format!("unresolved import: could not find `{}` \
2743 // idx +- 1 to account for the colons
2745 mpath.slice_from(idx + 1),
2746 mpath.slice_to(idx - 1)));
2753 debug!("(resolving module path for import) indeterminate; \
2755 return Indeterminate;
2757 Success(NoPrefixFound) => {
2758 // There was no prefix, so we're considering the first element
2759 // of the path. How we handle this depends on whether we were
2760 // instructed to use lexical scope or not.
2761 match use_lexical_scope {
2762 DontUseLexicalScope => {
2763 // This is a crate-relative path. We will start the
2764 // resolution process at index zero.
2765 search_module = self.graph_root.get_module();
2767 last_private = LastMod(AllPublic);
2769 UseLexicalScope => {
2770 // This is not a crate-relative path. We resolve the
2771 // first component of the path in the current lexical
2772 // scope and then proceed to resolve below that.
2773 let result = self.resolve_module_in_lexical_scope(
2778 self.resolve_error(span, "unresolved name");
2782 debug!("(resolving module path for import) \
2783 indeterminate; bailing");
2784 return Indeterminate;
2786 Success(containing_module) => {
2787 search_module = containing_module;
2789 last_private = LastMod(AllPublic);
2795 Success(PrefixFound(ref containing_module, index)) => {
2796 search_module = containing_module.clone();
2797 start_index = index;
2798 last_private = LastMod(DependsOn(containing_module.def_id
2804 self.resolve_module_path_from_root(search_module,
2812 /// Invariant: This must only be called during main resolution, not during
2813 /// import resolution.
2814 fn resolve_item_in_lexical_scope(&mut self,
2815 module_: Rc<Module>,
2817 namespace: Namespace,
2818 search_through_modules:
2819 SearchThroughModulesFlag)
2820 -> ResolveResult<(Target, bool)> {
2821 debug!("(resolving item in lexical scope) resolving `{}` in \
2822 namespace {:?} in `{}`",
2823 token::get_ident(name),
2825 self.module_to_str(&*module_));
2827 // The current module node is handled specially. First, check for
2828 // its immediate children.
2829 self.populate_module_if_necessary(&module_);
2831 match module_.children.borrow().find(&name.name) {
2833 if name_bindings.defined_in_namespace(namespace) => {
2834 debug!("top name bindings succeeded");
2835 return Success((Target::new(module_.clone(), name_bindings.clone()),
2838 Some(_) | None => { /* Not found; continue. */ }
2841 // Now check for its import directives. We don't have to have resolved
2842 // all its imports in the usual way; this is because chains of
2843 // adjacent import statements are processed as though they mutated the
2845 match module_.import_resolutions.borrow().find(&name.name) {
2847 // Not found; continue.
2849 Some(import_resolution) => {
2850 match (*import_resolution).target_for_namespace(namespace) {
2852 // Not found; continue.
2853 debug!("(resolving item in lexical scope) found \
2854 import resolution, but not in namespace {:?}",
2858 debug!("(resolving item in lexical scope) using \
2859 import resolution");
2860 self.used_imports.insert((import_resolution.id(namespace), namespace));
2861 return Success((target, false));
2867 // Search for external modules.
2868 if namespace == TypeNS {
2869 match module_.external_module_children.borrow().find_copy(&name.name) {
2873 Rc::new(Resolver::create_name_bindings_from_module(module));
2874 debug!("lower name bindings succeeded");
2875 return Success((Target::new(module_, name_bindings), false));
2880 // Finally, proceed up the scope chain looking for parent modules.
2881 let mut search_module = module_;
2883 // Go to the next parent.
2884 match search_module.parent_link.clone() {
2886 // No more parents. This module was unresolved.
2887 debug!("(resolving item in lexical scope) unresolved \
2891 ModuleParentLink(parent_module_node, _) => {
2892 match search_through_modules {
2893 DontSearchThroughModules => {
2894 match search_module.kind.get() {
2895 NormalModuleKind => {
2896 // We stop the search here.
2897 debug!("(resolving item in lexical \
2898 scope) unresolved module: not \
2899 searching through module \
2906 AnonymousModuleKind => {
2907 search_module = parent_module_node.upgrade().unwrap();
2911 SearchThroughModules => {
2912 search_module = parent_module_node.upgrade().unwrap();
2916 BlockParentLink(ref parent_module_node, _) => {
2917 search_module = parent_module_node.upgrade().unwrap();
2921 // Resolve the name in the parent module.
2922 match self.resolve_name_in_module(search_module.clone(),
2928 // Continue up the search chain.
2931 // We couldn't see through the higher scope because of an
2932 // unresolved import higher up. Bail.
2934 debug!("(resolving item in lexical scope) indeterminate \
2935 higher scope; bailing");
2936 return Indeterminate;
2938 Success((target, used_reexport)) => {
2939 // We found the module.
2940 debug!("(resolving item in lexical scope) found name \
2942 return Success((target, used_reexport));
2948 /// Resolves a module name in the current lexical scope.
2949 fn resolve_module_in_lexical_scope(&mut self,
2950 module_: Rc<Module>,
2952 -> ResolveResult<Rc<Module>> {
2953 // If this module is an anonymous module, resolve the item in the
2954 // lexical scope. Otherwise, resolve the item from the crate root.
2955 let resolve_result = self.resolve_item_in_lexical_scope(
2956 module_, name, TypeNS, DontSearchThroughModules);
2957 match resolve_result {
2958 Success((target, _)) => {
2959 let bindings = &*target.bindings;
2960 match *bindings.type_def.borrow() {
2961 Some(ref type_def) => {
2962 match type_def.module_def {
2964 error!("!!! (resolving module in lexical \
2965 scope) module wasn't actually a \
2969 Some(ref module_def) => {
2970 return Success(module_def.clone());
2975 error!("!!! (resolving module in lexical scope) module
2976 wasn't actually a module!");
2982 debug!("(resolving module in lexical scope) indeterminate; \
2984 return Indeterminate;
2987 debug!("(resolving module in lexical scope) failed to \
2994 /// Returns the nearest normal module parent of the given module.
2995 fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
2996 -> Option<Rc<Module>> {
2997 let mut module_ = module_;
2999 match module_.parent_link.clone() {
3000 NoParentLink => return None,
3001 ModuleParentLink(new_module, _) |
3002 BlockParentLink(new_module, _) => {
3003 let new_module = new_module.upgrade().unwrap();
3004 match new_module.kind.get() {
3005 NormalModuleKind => return Some(new_module),
3009 AnonymousModuleKind => module_ = new_module,
3016 /// Returns the nearest normal module parent of the given module, or the
3017 /// module itself if it is a normal module.
3018 fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
3020 match module_.kind.get() {
3021 NormalModuleKind => return module_,
3025 AnonymousModuleKind => {
3026 match self.get_nearest_normal_module_parent(module_.clone()) {
3028 Some(new_module) => new_module
3034 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3035 /// (b) some chain of `super::`.
3036 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3037 fn resolve_module_prefix(&mut self,
3038 module_: Rc<Module>,
3039 module_path: &[Ident])
3040 -> ResolveResult<ModulePrefixResult> {
3041 // Start at the current module if we see `self` or `super`, or at the
3042 // top of the crate otherwise.
3043 let mut containing_module;
3045 let first_module_path_string = token::get_ident(module_path[0]);
3046 if "self" == first_module_path_string.get() {
3048 self.get_nearest_normal_module_parent_or_self(module_);
3050 } else if "super" == first_module_path_string.get() {
3052 self.get_nearest_normal_module_parent_or_self(module_);
3053 i = 0; // We'll handle `super` below.
3055 return Success(NoPrefixFound);
3058 // Now loop through all the `super`s we find.
3059 while i < module_path.len() {
3060 let string = token::get_ident(module_path[i]);
3061 if "super" != string.get() {
3064 debug!("(resolving module prefix) resolving `super` at {}",
3065 self.module_to_str(&*containing_module));
3066 match self.get_nearest_normal_module_parent(containing_module) {
3067 None => return Failed,
3068 Some(new_module) => {
3069 containing_module = new_module;
3075 debug!("(resolving module prefix) finished resolving prefix at {}",
3076 self.module_to_str(&*containing_module));
3078 return Success(PrefixFound(containing_module, i));
3081 /// Attempts to resolve the supplied name in the given module for the
3082 /// given namespace. If successful, returns the target corresponding to
3085 /// The boolean returned on success is an indicator of whether this lookup
3086 /// passed through a public re-export proxy.
3087 fn resolve_name_in_module(&mut self,
3088 module_: Rc<Module>,
3090 namespace: Namespace,
3091 name_search_type: NameSearchType,
3092 allow_private_imports: bool)
3093 -> ResolveResult<(Target, bool)> {
3094 debug!("(resolving name in module) resolving `{}` in `{}`",
3095 token::get_ident(name),
3096 self.module_to_str(&*module_));
3098 // First, check the direct children of the module.
3099 self.populate_module_if_necessary(&module_);
3101 match module_.children.borrow().find(&name.name) {
3103 if name_bindings.defined_in_namespace(namespace) => {
3104 debug!("(resolving name in module) found node as child");
3105 return Success((Target::new(module_.clone(), name_bindings.clone()),
3113 // Next, check the module's imports if necessary.
3115 // If this is a search of all imports, we should be done with glob
3116 // resolution at this point.
3117 if name_search_type == PathSearch {
3118 assert_eq!(module_.glob_count.get(), 0);
3121 // Check the list of resolved imports.
3122 match module_.import_resolutions.borrow().find(&name.name) {
3123 Some(import_resolution) if allow_private_imports ||
3124 import_resolution.is_public => {
3126 if import_resolution.is_public &&
3127 import_resolution.outstanding_references != 0 {
3128 debug!("(resolving name in module) import \
3129 unresolved; bailing out");
3130 return Indeterminate;
3132 match import_resolution.target_for_namespace(namespace) {
3134 debug!("(resolving name in module) name found, \
3135 but not in namespace {:?}",
3139 debug!("(resolving name in module) resolved to \
3141 self.used_imports.insert((import_resolution.id(namespace), namespace));
3142 return Success((target, true));
3146 Some(..) | None => {} // Continue.
3149 // Finally, search through external children.
3150 if namespace == TypeNS {
3151 match module_.external_module_children.borrow().find_copy(&name.name) {
3155 Rc::new(Resolver::create_name_bindings_from_module(module));
3156 return Success((Target::new(module_, name_bindings), false));
3161 // We're out of luck.
3162 debug!("(resolving name in module) failed to resolve `{}`",
3163 token::get_ident(name));
3167 fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
3168 let index = module_.resolved_import_count.get();
3169 let imports = module_.imports.borrow();
3170 let import_count = imports.len();
3171 if index != import_count {
3172 let sn = self.session
3174 .span_to_snippet(imports.get(index).span)
3176 if sn.contains("::") {
3177 self.resolve_error(imports.get(index).span,
3178 "unresolved import");
3180 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3181 sn.slice(0, sn.len()));
3182 self.resolve_error(imports.get(index).span, err);
3186 // Descend into children and anonymous children.
3187 self.populate_module_if_necessary(&module_);
3189 for (_, child_node) in module_.children.borrow().iter() {
3190 match child_node.get_module_if_available() {
3194 Some(child_module) => {
3195 self.report_unresolved_imports(child_module);
3200 for (_, module_) in module_.anonymous_children.borrow().iter() {
3201 self.report_unresolved_imports(module_.clone());
3207 // This pass simply determines what all "export" keywords refer to and
3208 // writes the results into the export map.
3210 // FIXME #4953 This pass will be removed once exports change to per-item.
3211 // Then this operation can simply be performed as part of item (or import)
3214 fn record_exports(&mut self) {
3215 let root_module = self.graph_root.get_module();
3216 self.record_exports_for_module_subtree(root_module);
3219 fn record_exports_for_module_subtree(&mut self,
3220 module_: Rc<Module>) {
3221 // If this isn't a local krate, then bail out. We don't need to record
3222 // exports for nonlocal crates.
3224 match module_.def_id.get() {
3225 Some(def_id) if def_id.krate == LOCAL_CRATE => {
3227 debug!("(recording exports for module subtree) recording \
3228 exports for local module `{}`",
3229 self.module_to_str(&*module_));
3232 // Record exports for the root module.
3233 debug!("(recording exports for module subtree) recording \
3234 exports for root module `{}`",
3235 self.module_to_str(&*module_));
3239 debug!("(recording exports for module subtree) not recording \
3241 self.module_to_str(&*module_));
3246 self.record_exports_for_module(&*module_);
3247 self.populate_module_if_necessary(&module_);
3249 for (_, child_name_bindings) in module_.children.borrow().iter() {
3250 match child_name_bindings.get_module_if_available() {
3254 Some(child_module) => {
3255 self.record_exports_for_module_subtree(child_module);
3260 for (_, child_module) in module_.anonymous_children.borrow().iter() {
3261 self.record_exports_for_module_subtree(child_module.clone());
3265 fn record_exports_for_module(&mut self, module_: &Module) {
3266 let mut exports2 = Vec::new();
3268 self.add_exports_for_module(&mut exports2, module_);
3269 match module_.def_id.get() {
3271 self.export_map2.borrow_mut().insert(def_id.node, exports2);
3272 debug!("(computing exports) writing exports for {} (some)",
3279 fn add_exports_of_namebindings(&mut self,
3280 exports2: &mut Vec<Export2> ,
3282 namebindings: &NameBindings,
3284 match namebindings.def_for_namespace(ns) {
3286 let name = token::get_name(name);
3287 debug!("(computing exports) YES: export '{}' => {:?}",
3288 name, def_id_of_def(d));
3289 exports2.push(Export2 {
3290 name: name.get().to_str(),
3291 def_id: def_id_of_def(d)
3295 debug!("(computing exports) NO: {:?}", d_opt);
3300 fn add_exports_for_module(&mut self,
3301 exports2: &mut Vec<Export2> ,
3303 for (name, importresolution) in module_.import_resolutions.borrow().iter() {
3304 if !importresolution.is_public {
3307 let xs = [TypeNS, ValueNS];
3308 for &ns in xs.iter() {
3309 match importresolution.target_for_namespace(ns) {
3311 debug!("(computing exports) maybe export '{}'",
3312 token::get_name(*name));
3313 self.add_exports_of_namebindings(exports2,
3326 // We maintain a list of value ribs and type ribs.
3328 // Simultaneously, we keep track of the current position in the module
3329 // graph in the `current_module` pointer. When we go to resolve a name in
3330 // the value or type namespaces, we first look through all the ribs and
3331 // then query the module graph. When we resolve a name in the module
3332 // namespace, we can skip all the ribs (since nested modules are not
3333 // allowed within blocks in Rust) and jump straight to the current module
3336 // Named implementations are handled separately. When we find a method
3337 // call, we consult the module node to find all of the implementations in
3338 // scope. This information is lazily cached in the module node. We then
3339 // generate a fake "implementation scope" containing all the
3340 // implementations thus found, for compatibility with old resolve pass.
3342 fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
3343 let orig_module = self.current_module.clone();
3345 // Move down in the graph.
3351 self.populate_module_if_necessary(&orig_module);
3353 match orig_module.children.borrow().find(&name.name) {
3355 debug!("!!! (with scope) didn't find `{}` in `{}`",
3356 token::get_ident(name),
3357 self.module_to_str(&*orig_module));
3359 Some(name_bindings) => {
3360 match (*name_bindings).get_module_if_available() {
3362 debug!("!!! (with scope) didn't find module \
3364 token::get_ident(name),
3365 self.module_to_str(&*orig_module));
3368 self.current_module = module_;
3378 self.current_module = orig_module;
3381 /// Wraps the given definition in the appropriate number of `def_upvar`
3388 -> Option<DefLike> {
3393 DlDef(d @ DefLocal(..)) | DlDef(d @ DefUpvar(..)) |
3394 DlDef(d @ DefArg(..)) | DlDef(d @ DefBinding(..)) => {
3396 is_ty_param = false;
3398 DlDef(d @ DefTyParam(..)) => {
3403 return Some(def_like);
3407 let mut rib_index = rib_index + 1;
3408 while rib_index < ribs.len() {
3409 match ribs[rib_index].kind {
3411 // Nothing to do. Continue.
3413 FunctionRibKind(function_id, body_id) => {
3415 def = DefUpvar(def_id_of_def(def).node,
3421 MethodRibKind(item_id, _) => {
3422 // If the def is a ty param, and came from the parent
3425 DefTyParam(did, _) if {
3426 self.def_map.borrow().find(&did.node).map(|x| *x)
3427 == Some(DefTyParamBinder(item_id))
3433 // This was an attempt to access an upvar inside a
3434 // named function item. This is not allowed, so we
3439 "can't capture dynamic environment in a fn item; \
3440 use the || { ... } closure form instead");
3442 // This was an attempt to use a type parameter outside
3445 self.resolve_error(span,
3446 "can't use type parameters from \
3447 outer function; try using a local \
3448 type parameter instead");
3455 OpaqueFunctionRibKind => {
3457 // This was an attempt to access an upvar inside a
3458 // named function item. This is not allowed, so we
3463 "can't capture dynamic environment in a fn item; \
3464 use the || { ... } closure form instead");
3466 // This was an attempt to use a type parameter outside
3469 self.resolve_error(span,
3470 "can't use type parameters from \
3471 outer function; try using a local \
3472 type parameter instead");
3477 ConstantItemRibKind => {
3480 self.resolve_error(span,
3481 "cannot use an outer type \
3482 parameter in this context");
3484 // Still doesn't deal with upvars
3485 self.resolve_error(span,
3486 "attempt to use a non-constant \
3487 value in a constant");
3496 return Some(DlDef(def));
3499 fn search_ribs(&self,
3503 -> Option<DefLike> {
3504 // FIXME #4950: This should not use a while loop.
3505 // FIXME #4950: Try caching?
3507 let mut i = ribs.len();
3510 let binding_opt = ribs[i].bindings.borrow().find_copy(&name);
3513 return self.upvarify(ribs, i, def_like, span);
3524 fn resolve_crate(&mut self, krate: &ast::Crate) {
3525 debug!("(resolving crate) starting");
3527 visit::walk_crate(self, krate, ());
3530 fn resolve_item(&mut self, item: &Item) {
3531 debug!("(resolving item) resolving {}",
3532 token::get_ident(item.ident));
3536 // enum item: resolve all the variants' discrs,
3537 // then resolve the ty params
3538 ItemEnum(ref enum_def, ref generics) => {
3539 for variant in (*enum_def).variants.iter() {
3540 for dis_expr in variant.node.disr_expr.iter() {
3541 // resolve the discriminator expr
3543 self.with_constant_rib(|this| {
3544 this.resolve_expr(*dis_expr);
3549 // n.b. the discr expr gets visited twice.
3550 // but maybe it's okay since the first time will signal an
3551 // error if there is one? -- tjc
3552 self.with_type_parameter_rib(HasTypeParameters(generics,
3557 visit::walk_item(this, item, ());
3561 ItemTy(_, ref generics) => {
3562 self.with_type_parameter_rib(HasTypeParameters(generics,
3567 visit::walk_item(this, item, ());
3571 ItemImpl(ref generics,
3572 ref implemented_traits,
3575 self.resolve_implementation(item.id,
3579 methods.as_slice());
3582 ItemTrait(ref generics, _, ref traits, ref methods) => {
3583 // Create a new rib for the self type.
3584 let self_type_rib = Rib::new(NormalRibKind);
3585 // plain insert (no renaming)
3586 let name = self.type_self_ident.name;
3587 self_type_rib.bindings.borrow_mut()
3588 .insert(name, DlDef(DefSelfTy(item.id)));
3589 self.type_ribs.borrow_mut().push(self_type_rib);
3591 // Create a new rib for the trait-wide type parameters.
3592 self.with_type_parameter_rib(HasTypeParameters(generics,
3597 this.resolve_type_parameters(&generics.ty_params);
3599 // Resolve derived traits.
3600 for trt in traits.iter() {
3601 this.resolve_trait_reference(item.id, trt, TraitDerivation);
3604 for method in (*methods).iter() {
3605 // Create a new rib for the method-specific type
3608 // FIXME #4951: Do we need a node ID here?
3611 ast::Required(ref ty_m) => {
3612 this.with_type_parameter_rib
3613 (HasTypeParameters(&ty_m.generics,
3615 generics.ty_params.len(),
3616 MethodRibKind(item.id, Required)),
3619 // Resolve the method-specific type
3621 this.resolve_type_parameters(
3622 &ty_m.generics.ty_params);
3624 for argument in ty_m.decl.inputs.iter() {
3625 this.resolve_type(argument.ty);
3628 this.resolve_type(ty_m.decl.output);
3631 ast::Provided(m) => {
3632 this.resolve_method(MethodRibKind(item.id,
3635 generics.ty_params.len())
3641 self.type_ribs.borrow_mut().pop();
3644 ItemStruct(ref struct_def, ref generics) => {
3645 self.resolve_struct(item.id,
3647 struct_def.super_struct,
3648 struct_def.fields.as_slice());
3651 ItemMod(ref module_) => {
3652 self.with_scope(Some(item.ident), |this| {
3653 this.resolve_module(module_, item.span, item.ident,
3658 ItemForeignMod(ref foreign_module) => {
3659 self.with_scope(Some(item.ident), |this| {
3660 for foreign_item in foreign_module.items.iter() {
3661 match foreign_item.node {
3662 ForeignItemFn(_, ref generics) => {
3663 this.with_type_parameter_rib(
3665 generics, foreign_item.id, 0,
3667 |this| visit::walk_foreign_item(this,
3671 ForeignItemStatic(..) => {
3672 visit::walk_foreign_item(this,
3681 ItemFn(fn_decl, _, _, ref generics, block) => {
3682 self.resolve_function(OpaqueFunctionRibKind,
3688 OpaqueFunctionRibKind),
3693 self.with_constant_rib(|this| {
3694 visit::walk_item(this, item, ());
3699 // do nothing, these are just around to be encoded
3704 fn with_type_parameter_rib(&mut self,
3705 type_parameters: TypeParameters,
3706 f: |&mut Resolver|) {
3707 match type_parameters {
3708 HasTypeParameters(generics, node_id, initial_index,
3711 let function_type_rib = Rib::new(rib_kind);
3713 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
3714 let ident = type_parameter.ident;
3715 debug!("with_type_parameter_rib: {} {}", node_id,
3717 let def_like = DlDef(DefTyParam
3718 (local_def(type_parameter.id),
3719 index + initial_index));
3720 // Associate this type parameter with
3721 // the item that bound it
3722 self.record_def(type_parameter.id,
3723 (DefTyParamBinder(node_id), LastMod(AllPublic)));
3724 // plain insert (no renaming)
3725 function_type_rib.bindings.borrow_mut()
3726 .insert(ident.name, def_like);
3728 self.type_ribs.borrow_mut().push(function_type_rib);
3731 NoTypeParameters => {
3738 match type_parameters {
3739 HasTypeParameters(..) => { self.type_ribs.borrow_mut().pop(); }
3740 NoTypeParameters => { }
3744 fn with_label_rib(&mut self, f: |&mut Resolver|) {
3745 self.label_ribs.borrow_mut().push(Rib::new(NormalRibKind));
3747 self.label_ribs.borrow_mut().pop();
3750 fn with_constant_rib(&mut self, f: |&mut Resolver|) {
3751 self.value_ribs.borrow_mut().push(Rib::new(ConstantItemRibKind));
3752 self.type_ribs.borrow_mut().push(Rib::new(ConstantItemRibKind));
3754 self.type_ribs.borrow_mut().pop();
3755 self.value_ribs.borrow_mut().pop();
3758 fn resolve_function(&mut self,
3760 optional_declaration: Option<P<FnDecl>>,
3761 type_parameters: TypeParameters,
3763 // Create a value rib for the function.
3764 let function_value_rib = Rib::new(rib_kind);
3765 self.value_ribs.borrow_mut().push(function_value_rib);
3767 // Create a label rib for the function.
3768 let function_label_rib = Rib::new(rib_kind);
3769 self.label_ribs.borrow_mut().push(function_label_rib);
3771 // If this function has type parameters, add them now.
3772 self.with_type_parameter_rib(type_parameters, |this| {
3773 // Resolve the type parameters.
3774 match type_parameters {
3775 NoTypeParameters => {
3778 HasTypeParameters(ref generics, _, _, _) => {
3779 this.resolve_type_parameters(&generics.ty_params);
3783 // Add each argument to the rib.
3784 match optional_declaration {
3788 Some(declaration) => {
3789 for argument in declaration.inputs.iter() {
3790 this.resolve_pattern(argument.pat,
3791 ArgumentIrrefutableMode,
3794 this.resolve_type(argument.ty);
3796 debug!("(resolving function) recorded argument");
3799 this.resolve_type(declaration.output);
3803 // Resolve the function body.
3804 this.resolve_block(block);
3806 debug!("(resolving function) leaving function");
3809 self.label_ribs.borrow_mut().pop();
3810 self.value_ribs.borrow_mut().pop();
3813 fn resolve_type_parameters(&mut self,
3814 type_parameters: &OwnedSlice<TyParam>) {
3815 for type_parameter in type_parameters.iter() {
3816 for bound in type_parameter.bounds.iter() {
3817 self.resolve_type_parameter_bound(type_parameter.id, bound);
3819 match type_parameter.default {
3820 Some(ty) => self.resolve_type(ty),
3826 fn resolve_type_parameter_bound(&mut self,
3828 type_parameter_bound: &TyParamBound) {
3829 match *type_parameter_bound {
3830 TraitTyParamBound(ref tref) => {
3831 self.resolve_trait_reference(id, tref, TraitBoundingTypeParameter)
3833 RegionTyParamBound => {}
3837 fn resolve_trait_reference(&mut self,
3839 trait_reference: &TraitRef,
3840 reference_type: TraitReferenceType) {
3841 match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
3843 let path_str = self.path_idents_to_str(&trait_reference.path);
3844 let usage_str = match reference_type {
3845 TraitBoundingTypeParameter => "bound type parameter with",
3846 TraitImplementation => "implement",
3847 TraitDerivation => "derive"
3850 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
3851 self.resolve_error(trait_reference.path.span, msg);
3854 debug!("(resolving trait) found trait def: {:?}", def);
3855 self.record_def(trait_reference.ref_id, def);
3860 fn resolve_struct(&mut self,
3862 generics: &Generics,
3863 super_struct: Option<P<Ty>>,
3864 fields: &[StructField]) {
3865 // If applicable, create a rib for the type parameters.
3866 self.with_type_parameter_rib(HasTypeParameters(generics,
3869 OpaqueFunctionRibKind),
3871 // Resolve the type parameters.
3872 this.resolve_type_parameters(&generics.ty_params);
3874 // Resolve the super struct.
3875 match super_struct {
3876 Some(t) => match t.node {
3877 TyPath(ref path, None, path_id) => {
3878 match this.resolve_path(id, path, TypeNS, true) {
3879 Some((DefTy(def_id), lp)) if this.structs.contains(&def_id) => {
3880 let def = DefStruct(def_id);
3881 debug!("(resolving struct) resolved `{}` to type {:?}",
3882 token::get_ident(path.segments
3886 debug!("(resolving struct) writing resolution for `{}` (id {})",
3887 this.path_idents_to_str(path),
3889 this.record_def(path_id, (def, lp));
3891 Some((DefStruct(_), _)) => {
3892 this.session.span_err(t.span,
3893 "super-struct is defined \
3894 in a different crate")
3896 Some(_) => this.session.span_err(t.span,
3897 "super-struct is not a struct type"),
3898 None => this.session.span_err(t.span,
3899 "super-struct could not be resolved"),
3902 _ => this.session.span_bug(t.span, "path not mapped to a TyPath")
3908 for field in fields.iter() {
3909 this.resolve_type(field.node.ty);
3914 // Does this really need to take a RibKind or is it always going
3915 // to be NormalRibKind?
3916 fn resolve_method(&mut self,
3919 outer_type_parameter_count: uint) {
3920 let method_generics = &method.generics;
3921 let type_parameters =
3922 HasTypeParameters(method_generics,
3924 outer_type_parameter_count,
3927 self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
3930 fn resolve_implementation(&mut self,
3932 generics: &Generics,
3933 opt_trait_reference: &Option<TraitRef>,
3935 methods: &[@Method]) {
3936 // If applicable, create a rib for the type parameters.
3937 let outer_type_parameter_count = generics.ty_params.len();
3938 self.with_type_parameter_rib(HasTypeParameters(generics,
3943 // Resolve the type parameters.
3944 this.resolve_type_parameters(&generics.ty_params);
3946 // Resolve the trait reference, if necessary.
3947 let original_trait_refs;
3948 match opt_trait_reference {
3949 &Some(ref trait_reference) => {
3950 this.resolve_trait_reference(id, trait_reference,
3951 TraitImplementation);
3953 // Record the current set of trait references.
3954 let mut new_trait_refs = Vec::new();
3955 for &def in this.def_map.borrow()
3956 .find(&trait_reference.ref_id).iter() {
3957 new_trait_refs.push(def_id_of_def(*def));
3959 original_trait_refs = Some(replace(
3960 &mut this.current_trait_refs,
3961 Some(new_trait_refs)));
3964 original_trait_refs = None;
3968 // Resolve the self type.
3969 this.resolve_type(self_type);
3971 for method in methods.iter() {
3972 // We also need a new scope for the method-specific
3974 this.resolve_method(MethodRibKind(
3976 Provided(method.id)),
3978 outer_type_parameter_count);
3980 let borrowed_type_parameters = &method.tps;
3981 self.resolve_function(MethodRibKind(
3983 Provided(method.id)),
3986 (borrowed_type_parameters,
3988 outer_type_parameter_count,
3994 // Restore the original trait references.
3995 match original_trait_refs {
3996 Some(r) => { this.current_trait_refs = r; }
4002 fn resolve_module(&mut self, module: &Mod, _span: Span,
4003 _name: Ident, id: NodeId) {
4004 // Write the implementations in scope into the module metadata.
4005 debug!("(resolving module) resolving module ID {}", id);
4006 visit::walk_mod(self, module, ());
4009 fn resolve_local(&mut self, local: &Local) {
4010 // Resolve the type.
4011 self.resolve_type(local.ty);
4013 // Resolve the initializer, if necessary.
4018 Some(initializer) => {
4019 self.resolve_expr(initializer);
4023 // Resolve the pattern.
4024 self.resolve_pattern(local.pat, LocalIrrefutableMode, None);
4027 // build a map from pattern identifiers to binding-info's.
4028 // this is done hygienically. This could arise for a macro
4029 // that expands into an or-pattern where one 'x' was from the
4030 // user and one 'x' came from the macro.
4031 fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
4032 let mut result = HashMap::new();
4033 pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path| {
4034 let name = mtwt::resolve(path_to_ident(path));
4036 binding_info {span: sp,
4037 binding_mode: binding_mode});
4042 // check that all of the arms in an or-pattern have exactly the
4043 // same set of bindings, with the same binding modes for each.
4044 fn check_consistent_bindings(&mut self, arm: &Arm) {
4045 if arm.pats.len() == 0 {
4048 let map_0 = self.binding_mode_map(*arm.pats.get(0));
4049 for (i, p) in arm.pats.iter().enumerate() {
4050 let map_i = self.binding_mode_map(*p);
4052 for (&key, &binding_0) in map_0.iter() {
4053 match map_i.find(&key) {
4057 format!("variable `{}` from pattern \\#1 is \
4058 not bound in pattern \\#{}",
4059 token::get_name(key),
4062 Some(binding_i) => {
4063 if binding_0.binding_mode != binding_i.binding_mode {
4066 format!("variable `{}` is bound with different \
4067 mode in pattern \\#{} than in pattern \\#1",
4068 token::get_name(key),
4075 for (&key, &binding) in map_i.iter() {
4076 if !map_0.contains_key(&key) {
4079 format!("variable `{}` from pattern \\#{} is \
4080 not bound in pattern \\#1",
4081 token::get_name(key),
4088 fn resolve_arm(&mut self, arm: &Arm) {
4089 self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4091 let mut bindings_list = HashMap::new();
4092 for pattern in arm.pats.iter() {
4093 self.resolve_pattern(*pattern,
4095 Some(&mut bindings_list));
4098 // This has to happen *after* we determine which
4099 // pat_idents are variants
4100 self.check_consistent_bindings(arm);
4102 visit::walk_expr_opt(self, arm.guard, ());
4103 self.resolve_expr(arm.body);
4105 self.value_ribs.borrow_mut().pop();
4108 fn resolve_block(&mut self, block: &Block) {
4109 debug!("(resolving block) entering block");
4110 self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4112 // Move down in the graph, if there's an anonymous module rooted here.
4113 let orig_module = self.current_module.clone();
4114 match orig_module.anonymous_children.borrow().find(&block.id) {
4115 None => { /* Nothing to do. */ }
4116 Some(anonymous_module) => {
4117 debug!("(resolving block) found anonymous module, moving \
4119 self.current_module = anonymous_module.clone();
4123 // Descend into the block.
4124 visit::walk_block(self, block, ());
4127 self.current_module = orig_module;
4129 self.value_ribs.borrow_mut().pop();
4130 debug!("(resolving block) leaving block");
4133 fn resolve_type(&mut self, ty: &Ty) {
4135 // Like path expressions, the interpretation of path types depends
4136 // on whether the path has multiple elements in it or not.
4138 TyPath(ref path, ref bounds, path_id) => {
4139 // This is a path in the type namespace. Walk through scopes
4141 let mut result_def = None;
4143 // First, check to see whether the name is a primitive type.
4144 if path.segments.len() == 1 {
4145 let id = path.segments.last().unwrap().identifier;
4147 match self.primitive_type_table
4151 Some(&primitive_type) => {
4153 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4157 .any(|s| !s.lifetimes.is_empty()) {
4158 self.session.span_err(path.span,
4159 "lifetime parameters \
4160 are not allowed on \
4162 } else if path.segments
4164 .any(|s| s.types.len() > 0) {
4165 self.session.span_err(path.span,
4166 "type parameters are \
4167 not allowed on this \
4179 match self.resolve_path(ty.id, path, TypeNS, true) {
4181 debug!("(resolving type) resolved `{}` to \
4183 token::get_ident(path.segments
4187 result_def = Some(def);
4194 Some(_) => {} // Continue.
4199 // Write the result into the def map.
4200 debug!("(resolving type) writing resolution for `{}` \
4202 self.path_idents_to_str(path),
4204 self.record_def(path_id, def);
4207 let msg = format!("use of undeclared type name `{}`",
4208 self.path_idents_to_str(path));
4209 self.resolve_error(ty.span, msg);
4213 bounds.as_ref().map(|bound_vec| {
4214 for bound in bound_vec.iter() {
4215 self.resolve_type_parameter_bound(ty.id, bound);
4220 TyClosure(c, _) | TyProc(c) => {
4221 c.bounds.as_ref().map(|bounds| {
4222 for bound in bounds.iter() {
4223 self.resolve_type_parameter_bound(ty.id, bound);
4226 visit::walk_ty(self, ty, ());
4230 // Just resolve embedded types.
4231 visit::walk_ty(self, ty, ());
4236 fn resolve_pattern(&mut self,
4238 mode: PatternBindingMode,
4239 // Maps idents to the node ID for the (outermost)
4240 // pattern that binds them
4241 mut bindings_list: Option<&mut HashMap<Name,NodeId>>) {
4242 let pat_id = pattern.id;
4243 walk_pat(pattern, |pattern| {
4244 match pattern.node {
4245 PatIdent(binding_mode, ref path, _)
4246 if !path.global && path.segments.len() == 1 => {
4248 // The meaning of pat_ident with no type parameters
4249 // depends on whether an enum variant or unit-like struct
4250 // with that name is in scope. The probing lookup has to
4251 // be careful not to emit spurious errors. Only matching
4252 // patterns (match) can match nullary variants or
4253 // unit-like structs. For binding patterns (let), matching
4254 // such a value is simply disallowed (since it's rarely
4257 let ident = path.segments.get(0).identifier;
4258 let renamed = mtwt::resolve(ident);
4260 match self.resolve_bare_identifier_pattern(ident) {
4261 FoundStructOrEnumVariant(def, lp)
4262 if mode == RefutableMode => {
4263 debug!("(resolving pattern) resolving `{}` to \
4264 struct or enum variant",
4265 token::get_name(renamed));
4267 self.enforce_default_binding_mode(
4271 self.record_def(pattern.id, (def, lp));
4273 FoundStructOrEnumVariant(..) => {
4274 self.resolve_error(pattern.span,
4275 format!("declaration of `{}` \
4277 variant or unit-like \
4279 token::get_name(renamed)));
4281 FoundConst(def, lp) if mode == RefutableMode => {
4282 debug!("(resolving pattern) resolving `{}` to \
4284 token::get_name(renamed));
4286 self.enforce_default_binding_mode(
4290 self.record_def(pattern.id, (def, lp));
4293 self.resolve_error(pattern.span,
4294 "only irrefutable patterns \
4297 BareIdentifierPatternUnresolved => {
4298 debug!("(resolving pattern) binding `{}`",
4299 token::get_name(renamed));
4301 let def = match mode {
4303 // For pattern arms, we must use
4304 // `def_binding` definitions.
4306 DefBinding(pattern.id, binding_mode)
4308 LocalIrrefutableMode => {
4309 // But for locals, we use `def_local`.
4310 DefLocal(pattern.id, binding_mode)
4312 ArgumentIrrefutableMode => {
4313 // And for function arguments, `def_arg`.
4314 DefArg(pattern.id, binding_mode)
4318 // Record the definition so that later passes
4319 // will be able to distinguish variants from
4320 // locals in patterns.
4322 self.record_def(pattern.id, (def, LastMod(AllPublic)));
4324 // Add the binding to the local ribs, if it
4325 // doesn't already exist in the bindings list. (We
4326 // must not add it if it's in the bindings list
4327 // because that breaks the assumptions later
4328 // passes make about or-patterns.)
4330 match bindings_list {
4331 Some(ref mut bindings_list)
4332 if !bindings_list.contains_key(&renamed) => {
4333 let this = &mut *self;
4334 let value_ribs = this.value_ribs.borrow();
4335 let length = value_ribs.len();
4336 let last_rib = value_ribs.get(
4338 last_rib.bindings.borrow_mut()
4339 .insert(renamed, DlDef(def));
4340 bindings_list.insert(renamed, pat_id);
4342 Some(ref mut b) => {
4343 if b.find(&renamed) == Some(&pat_id) {
4344 // Then this is a duplicate variable
4345 // in the same disjunct, which is an
4347 self.resolve_error(pattern.span,
4348 format!("identifier `{}` is bound more \
4349 than once in the same pattern",
4350 path_to_str(path)));
4352 // Not bound in the same pattern: do nothing
4355 let this = &mut *self;
4357 let value_ribs = this.value_ribs.borrow();
4358 let length = value_ribs.len();
4359 let last_rib = value_ribs.get(
4361 last_rib.bindings.borrow_mut()
4362 .insert(renamed, DlDef(def));
4369 // Check the types in the path pattern.
4370 for &ty in path.segments
4372 .flat_map(|seg| seg.types.iter()) {
4373 self.resolve_type(ty);
4377 PatIdent(binding_mode, ref path, _) => {
4378 // This must be an enum variant, struct, or constant.
4379 match self.resolve_path(pat_id, path, ValueNS, false) {
4380 Some(def @ (DefVariant(..), _)) |
4381 Some(def @ (DefStruct(..), _)) => {
4382 self.record_def(pattern.id, def);
4384 Some(def @ (DefStatic(..), _)) => {
4385 self.enforce_default_binding_mode(
4389 self.record_def(pattern.id, def);
4394 format!("`{}` is not an enum variant or constant",
4396 path.segments.last().unwrap().identifier)))
4399 self.resolve_error(path.span,
4400 "unresolved enum variant");
4404 // Check the types in the path pattern.
4405 for &ty in path.segments
4407 .flat_map(|s| s.types.iter()) {
4408 self.resolve_type(ty);
4412 PatEnum(ref path, _) => {
4413 // This must be an enum variant, struct or const.
4414 match self.resolve_path(pat_id, path, ValueNS, false) {
4415 Some(def @ (DefFn(..), _)) |
4416 Some(def @ (DefVariant(..), _)) |
4417 Some(def @ (DefStruct(..), _)) |
4418 Some(def @ (DefStatic(..), _)) => {
4419 self.record_def(pattern.id, def);
4422 self.resolve_error(path.span,
4423 format!("`{}` is not an enum variant, struct or const",
4424 token::get_ident(path.segments
4429 self.resolve_error(path.span,
4430 format!("unresolved enum variant, struct or const `{}`",
4431 token::get_ident(path.segments
4437 // Check the types in the path pattern.
4438 for &ty in path.segments
4440 .flat_map(|s| s.types.iter()) {
4441 self.resolve_type(ty);
4446 self.resolve_expr(expr);
4449 PatRange(first_expr, last_expr) => {
4450 self.resolve_expr(first_expr);
4451 self.resolve_expr(last_expr);
4454 PatStruct(ref path, _, _) => {
4455 match self.resolve_path(pat_id, path, TypeNS, false) {
4456 Some((DefTy(class_id), lp))
4457 if self.structs.contains(&class_id) => {
4458 let class_def = DefStruct(class_id);
4459 self.record_def(pattern.id, (class_def, lp));
4461 Some(definition @ (DefStruct(class_id), _)) => {
4462 assert!(self.structs.contains(&class_id));
4463 self.record_def(pattern.id, definition);
4465 Some(definition @ (DefVariant(_, variant_id, _), _))
4466 if self.structs.contains(&variant_id) => {
4467 self.record_def(pattern.id, definition);
4470 debug!("(resolving pattern) didn't find struct \
4471 def: {:?}", result);
4472 let msg = format!("`{}` does not name a structure",
4473 self.path_idents_to_str(path));
4474 self.resolve_error(path.span, msg);
4487 fn resolve_bare_identifier_pattern(&mut self, name: Ident)
4488 -> BareIdentifierPatternResolution {
4489 let module = self.current_module.clone();
4490 match self.resolve_item_in_lexical_scope(module,
4493 SearchThroughModules) {
4494 Success((target, _)) => {
4495 debug!("(resolve bare identifier pattern) succeeded in \
4496 finding {} at {:?}",
4497 token::get_ident(name),
4498 target.bindings.value_def.borrow());
4499 match *target.bindings.value_def.borrow() {
4501 fail!("resolved name in the value namespace to a \
4502 set of name bindings with no def?!");
4505 // For the two success cases, this lookup can be
4506 // considered as not having a private component because
4507 // the lookup happened only within the current module.
4509 def @ DefVariant(..) | def @ DefStruct(..) => {
4510 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
4512 def @ DefStatic(_, false) => {
4513 return FoundConst(def, LastMod(AllPublic));
4516 return BareIdentifierPatternUnresolved;
4524 fail!("unexpected indeterminate result");
4528 debug!("(resolve bare identifier pattern) failed to find {}",
4529 token::get_ident(name));
4530 return BareIdentifierPatternUnresolved;
4535 /// If `check_ribs` is true, checks the local definitions first; i.e.
4536 /// doesn't skip straight to the containing module.
4537 fn resolve_path(&mut self,
4540 namespace: Namespace,
4541 check_ribs: bool) -> Option<(Def, LastPrivate)> {
4542 // First, resolve the types.
4543 for &ty in path.segments.iter().flat_map(|s| s.types.iter()) {
4544 self.resolve_type(ty);
4548 return self.resolve_crate_relative_path(path, namespace);
4551 let unqualified_def =
4552 self.resolve_identifier(path.segments
4559 if path.segments.len() > 1 {
4560 let def = self.resolve_module_relative_path(path, namespace);
4561 match (def, unqualified_def) {
4562 (Some((d, _)), Some((ud, _))) if d == ud => {
4563 self.session.add_lint(UnnecessaryQualification,
4566 "unnecessary qualification".to_owned());
4574 return unqualified_def;
4577 // resolve a single identifier (used as a varref)
4578 fn resolve_identifier(&mut self,
4580 namespace: Namespace,
4583 -> Option<(Def, LastPrivate)> {
4585 match self.resolve_identifier_in_local_ribs(identifier,
4589 return Some((def, LastMod(AllPublic)));
4597 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
4601 // FIXME #4952: Merge me with resolve_name_in_module?
4602 fn resolve_definition_of_name_in_module(&mut self,
4603 containing_module: Rc<Module>,
4605 namespace: Namespace)
4607 // First, search children.
4608 self.populate_module_if_necessary(&containing_module);
4610 match containing_module.children.borrow().find(&name.name) {
4611 Some(child_name_bindings) => {
4612 match child_name_bindings.def_for_namespace(namespace) {
4614 // Found it. Stop the search here.
4615 let p = child_name_bindings.defined_in_public_namespace(
4617 let lp = if p {LastMod(AllPublic)} else {
4618 LastMod(DependsOn(def_id_of_def(def)))
4620 return ChildNameDefinition(def, lp);
4628 // Next, search import resolutions.
4629 match containing_module.import_resolutions.borrow().find(&name.name) {
4630 Some(import_resolution) if import_resolution.is_public => {
4631 match (*import_resolution).target_for_namespace(namespace) {
4633 match target.bindings.def_for_namespace(namespace) {
4636 let id = import_resolution.id(namespace);
4637 self.used_imports.insert((id, namespace));
4638 return ImportNameDefinition(def, LastMod(AllPublic));
4641 // This can happen with external impls, due to
4642 // the imperfect way we read the metadata.
4649 Some(..) | None => {} // Continue.
4652 // Finally, search through external children.
4653 if namespace == TypeNS {
4654 match containing_module.external_module_children.borrow()
4655 .find_copy(&name.name) {
4658 match module.def_id.get() {
4659 None => {} // Continue.
4661 let lp = if module.is_public {LastMod(AllPublic)} else {
4662 LastMod(DependsOn(def_id))
4664 return ChildNameDefinition(DefMod(def_id), lp);
4671 return NoNameDefinition;
4674 // resolve a "module-relative" path, e.g. a::b::c
4675 fn resolve_module_relative_path(&mut self,
4677 namespace: Namespace)
4678 -> Option<(Def, LastPrivate)> {
4679 let module_path_idents = path.segments.init().iter()
4680 .map(|ps| ps.identifier)
4681 .collect::<Vec<_>>();
4683 let containing_module;
4685 let module = self.current_module.clone();
4686 match self.resolve_module_path(module,
4687 module_path_idents.as_slice(),
4692 let msg = format!("use of undeclared module `{}`",
4693 self.idents_to_str(module_path_idents.as_slice()));
4694 self.resolve_error(path.span, msg);
4699 fail!("indeterminate unexpected");
4702 Success((resulting_module, resulting_last_private)) => {
4703 containing_module = resulting_module;
4704 last_private = resulting_last_private;
4708 let ident = path.segments.last().unwrap().identifier;
4709 let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
4712 NoNameDefinition => {
4713 // We failed to resolve the name. Report an error.
4716 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4717 (def, last_private.or(lp))
4720 match containing_module.kind.get() {
4721 TraitModuleKind | ImplModuleKind => {
4722 match containing_module.def_id.get() {
4723 Some(def_id) if self.method_set.borrow().contains(&(ident.name, def_id)) => {
4724 debug!("containing module was a trait or impl \
4725 and name was a method -> not resolved");
4736 /// Invariant: This must be called only during main resolution, not during
4737 /// import resolution.
4738 fn resolve_crate_relative_path(&mut self,
4740 namespace: Namespace)
4741 -> Option<(Def, LastPrivate)> {
4742 let module_path_idents = path.segments.init().iter()
4743 .map(|ps| ps.identifier)
4744 .collect::<Vec<_>>();
4746 let root_module = self.graph_root.get_module();
4748 let containing_module;
4750 match self.resolve_module_path_from_root(root_module,
4751 module_path_idents.as_slice(),
4755 LastMod(AllPublic)) {
4757 let msg = format!("use of undeclared module `::{}`",
4758 self.idents_to_str(module_path_idents.as_slice()));
4759 self.resolve_error(path.span, msg);
4764 fail!("indeterminate unexpected");
4767 Success((resulting_module, resulting_last_private)) => {
4768 containing_module = resulting_module;
4769 last_private = resulting_last_private;
4773 let name = path.segments.last().unwrap().identifier;
4774 match self.resolve_definition_of_name_in_module(containing_module,
4777 NoNameDefinition => {
4778 // We failed to resolve the name. Report an error.
4781 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4782 return Some((def, last_private.or(lp)));
4787 fn resolve_identifier_in_local_ribs(&mut self,
4789 namespace: Namespace,
4792 // Check the local set of ribs.
4793 let search_result = match namespace {
4795 let renamed = mtwt::resolve(ident);
4796 self.search_ribs(self.value_ribs.borrow().as_slice(),
4800 let name = ident.name;
4801 self.search_ribs(self.type_ribs.borrow().as_slice(), name, span)
4805 match search_result {
4806 Some(DlDef(def)) => {
4807 debug!("(resolving path in local ribs) resolved `{}` to \
4809 token::get_ident(ident),
4813 Some(DlField) | Some(DlImpl(_)) | None => {
4819 fn resolve_item_by_identifier_in_lexical_scope(&mut self,
4821 namespace: Namespace)
4822 -> Option<(Def, LastPrivate)> {
4824 let module = self.current_module.clone();
4825 match self.resolve_item_in_lexical_scope(module,
4828 DontSearchThroughModules) {
4829 Success((target, _)) => {
4830 match (*target.bindings).def_for_namespace(namespace) {
4832 // This can happen if we were looking for a type and
4833 // found a module instead. Modules don't have defs.
4834 debug!("(resolving item path by identifier in lexical \
4835 scope) failed to resolve {} after success...",
4836 token::get_ident(ident));
4840 debug!("(resolving item path in lexical scope) \
4841 resolved `{}` to item",
4842 token::get_ident(ident));
4843 // This lookup is "all public" because it only searched
4844 // for one identifier in the current module (couldn't
4845 // have passed through reexports or anything like that.
4846 return Some((def, LastMod(AllPublic)));
4851 fail!("unexpected indeterminate result");
4854 debug!("(resolving item path by identifier in lexical scope) \
4855 failed to resolve {}", token::get_ident(ident));
4861 fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
4862 self.emit_errors = false;
4864 self.emit_errors = true;
4868 fn resolve_error(&self, span: Span, s: &str) {
4869 if self.emit_errors {
4870 self.session.span_err(span, s);
4874 fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
4876 let this = &mut *self;
4878 let mut maybes: Vec<token::InternedString> = Vec::new();
4879 let mut values: Vec<uint> = Vec::new();
4881 let mut j = this.value_ribs.borrow().len();
4884 let value_ribs = this.value_ribs.borrow();
4885 let bindings = value_ribs.get(j).bindings.borrow();
4886 for (&k, _) in bindings.iter() {
4887 maybes.push(token::get_name(k));
4888 values.push(uint::MAX);
4892 let mut smallest = 0;
4893 for (i, other) in maybes.iter().enumerate() {
4894 *values.get_mut(i) = name.lev_distance(other.get());
4896 if *values.get(i) <= *values.get(smallest) {
4901 if values.len() > 0 &&
4902 *values.get(smallest) != uint::MAX &&
4903 *values.get(smallest) < name.len() + 2 &&
4904 *values.get(smallest) <= max_distance &&
4905 name != maybes.get(smallest).get() {
4907 Some(maybes.get(smallest).get().to_str())
4914 fn resolve_expr(&mut self, expr: &Expr) {
4915 // First, record candidate traits for this expression if it could
4916 // result in the invocation of a method call.
4918 self.record_candidate_traits_for_expr_if_necessary(expr);
4920 // Next, resolve the node.
4922 // The interpretation of paths depends on whether the path has
4923 // multiple elements in it or not.
4925 ExprPath(ref path) => {
4926 // This is a local path in the value namespace. Walk through
4927 // scopes looking for it.
4929 match self.resolve_path(expr.id, path, ValueNS, true) {
4931 // Write the result into the def map.
4932 debug!("(resolving expr) resolved `{}`",
4933 self.path_idents_to_str(path));
4935 // First-class methods are not supported yet; error
4938 (DefMethod(..), _) => {
4939 self.resolve_error(expr.span,
4940 "first-class methods \
4941 are not supported");
4942 self.session.span_note(expr.span,
4950 self.record_def(expr.id, def);
4953 let wrong_name = self.path_idents_to_str(path);
4954 // Be helpful if the name refers to a struct
4955 // (The pattern matching def_tys where the id is in self.structs
4956 // matches on regular structs while excluding tuple- and enum-like
4957 // structs, which wouldn't result in this error.)
4958 match self.with_no_errors(|this|
4959 this.resolve_path(expr.id, path, TypeNS, false)) {
4960 Some((DefTy(struct_id), _))
4961 if self.structs.contains(&struct_id) => {
4962 self.resolve_error(expr.span,
4963 format!("`{}` is a structure name, but \
4965 uses it like a function name",
4968 self.session.span_note(expr.span,
4969 format!("Did you mean to write: \
4970 `{} \\{ /* fields */ \\}`?",
4975 // limit search to 5 to reduce the number
4976 // of stupid suggestions
4977 match self.find_best_match_for_name(wrong_name, 5) {
4979 self.resolve_error(expr.span,
4980 format!("unresolved name `{}`. \
4981 Did you mean `{}`?",
4985 self.resolve_error(expr.span,
4986 format!("unresolved name `{}`.",
4994 visit::walk_expr(self, expr, ());
4997 ExprFnBlock(fn_decl, block) |
4998 ExprProc(fn_decl, block) => {
4999 self.resolve_function(FunctionRibKind(expr.id, block.id),
5000 Some(fn_decl), NoTypeParameters,
5004 ExprStruct(ref path, _, _) => {
5005 // Resolve the path to the structure it goes to.
5006 match self.resolve_path(expr.id, path, TypeNS, false) {
5007 Some((DefTy(class_id), lp)) | Some((DefStruct(class_id), lp))
5008 if self.structs.contains(&class_id) => {
5009 let class_def = DefStruct(class_id);
5010 self.record_def(expr.id, (class_def, lp));
5012 Some(definition @ (DefVariant(_, class_id, _), _))
5013 if self.structs.contains(&class_id) => {
5014 self.record_def(expr.id, definition);
5017 debug!("(resolving expression) didn't find struct \
5018 def: {:?}", result);
5019 let msg = format!("`{}` does not name a structure",
5020 self.path_idents_to_str(path));
5021 self.resolve_error(path.span, msg);
5025 visit::walk_expr(self, expr, ());
5028 ExprLoop(_, Some(label)) => {
5029 self.with_label_rib(|this| {
5030 let def_like = DlDef(DefLabel(expr.id));
5033 let label_ribs = this.label_ribs.borrow();
5034 let length = label_ribs.len();
5035 let rib = label_ribs.get(length - 1);
5036 let renamed = mtwt::resolve(label);
5037 rib.bindings.borrow_mut().insert(renamed, def_like);
5040 visit::walk_expr(this, expr, ());
5044 ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
5046 ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5047 let renamed = mtwt::resolve(label);
5048 match self.search_ribs(self.label_ribs.borrow().as_slice(),
5049 renamed, expr.span) {
5051 self.resolve_error(expr.span,
5052 format!("use of undeclared label `{}`",
5053 token::get_ident(label))),
5054 Some(DlDef(def @ DefLabel(_))) => {
5055 // Since this def is a label, it is never read.
5056 self.record_def(expr.id, (def, LastMod(AllPublic)))
5059 self.session.span_bug(expr.span,
5060 "label wasn't mapped to a \
5067 visit::walk_expr(self, expr, ());
5072 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5074 ExprField(_, ident, _) => {
5075 // FIXME(#6890): Even though you can't treat a method like a
5076 // field, we need to add any trait methods we find that match
5077 // the field name so that we can do some nice error reporting
5078 // later on in typeck.
5079 let traits = self.search_for_traits_containing_method(ident.name);
5080 self.trait_map.insert(expr.id, traits);
5082 ExprMethodCall(ident, _, _) => {
5083 debug!("(recording candidate traits for expr) recording \
5086 let traits = self.search_for_traits_containing_method(ident.node.name);
5087 self.trait_map.insert(expr.id, traits);
5095 fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
5096 debug!("(searching for traits containing method) looking for '{}'",
5097 token::get_name(name));
5099 fn add_trait_info(found_traits: &mut Vec<DefId>,
5100 trait_def_id: DefId,
5102 debug!("(adding trait info) found trait {}:{} for method '{}'",
5105 token::get_name(name));
5106 found_traits.push(trait_def_id);
5109 let mut found_traits = Vec::new();
5110 let mut search_module = self.current_module.clone();
5112 // Look for the current trait.
5113 match self.current_trait_refs {
5114 Some(ref trait_def_ids) => {
5115 let method_set = self.method_set.borrow();
5116 for &trait_def_id in trait_def_ids.iter() {
5117 if method_set.contains(&(name, trait_def_id)) {
5118 add_trait_info(&mut found_traits, trait_def_id, name);
5127 // Look for trait children.
5128 self.populate_module_if_necessary(&search_module);
5131 let method_set = self.method_set.borrow();
5132 for (_, child_names) in search_module.children.borrow().iter() {
5133 let def = match child_names.def_for_namespace(TypeNS) {
5137 let trait_def_id = match def {
5138 DefTrait(trait_def_id) => trait_def_id,
5141 if method_set.contains(&(name, trait_def_id)) {
5142 add_trait_info(&mut found_traits, trait_def_id, name);
5147 // Look for imports.
5148 for (_, import) in search_module.import_resolutions.borrow().iter() {
5149 let target = match import.target_for_namespace(TypeNS) {
5151 Some(target) => target,
5153 let did = match target.bindings.def_for_namespace(TypeNS) {
5154 Some(DefTrait(trait_def_id)) => trait_def_id,
5155 Some(..) | None => continue,
5157 if self.method_set.borrow().contains(&(name, did)) {
5158 add_trait_info(&mut found_traits, did, name);
5159 self.used_imports.insert((import.type_id, TypeNS));
5163 match search_module.parent_link.clone() {
5164 NoParentLink | ModuleParentLink(..) => break,
5165 BlockParentLink(parent_module, _) => {
5166 search_module = parent_module.upgrade().unwrap();
5174 fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
5175 debug!("(recording def) recording {:?} for {:?}, last private {:?}",
5177 assert!(match lp {LastImport{..} => false, _ => true},
5178 "Import should only be used for `use` directives");
5179 self.last_private.insert(node_id, lp);
5180 self.def_map.borrow_mut().insert_or_update_with(node_id, def, |_, old_value| {
5181 // Resolve appears to "resolve" the same ID multiple
5182 // times, so here is a sanity check it at least comes to
5183 // the same conclusion! - nmatsakis
5184 if def != *old_value {
5185 self.session.bug(format!("node_id {:?} resolved first to {:?} \
5186 and then {:?}", node_id, *old_value, def));
5191 fn enforce_default_binding_mode(&mut self,
5193 pat_binding_mode: BindingMode,
5195 match pat_binding_mode {
5196 BindByValue(_) => {}
5200 format!("cannot use `ref` binding mode with {}",
5207 // Unused import checking
5209 // Although this is mostly a lint pass, it lives in here because it depends on
5210 // resolve data structures and because it finalises the privacy information for
5211 // `use` directives.
5214 fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
5215 let mut visitor = UnusedImportCheckVisitor{ resolver: self };
5216 visit::walk_crate(&mut visitor, krate, ());
5219 fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
5220 // Ignore is_public import statements because there's no way to be sure
5221 // whether they're used or not. Also ignore imports with a dummy span
5222 // because this means that they were generated in some fashion by the
5223 // compiler and we don't need to consider them.
5224 if vi.vis == Public { return }
5225 if vi.span == DUMMY_SP { return }
5228 ViewItemExternCrate(..) => {} // ignore
5229 ViewItemUse(ref path) => {
5230 for p in path.iter() {
5232 ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
5233 ViewPathList(_, ref list, _) => {
5234 for i in list.iter() {
5235 self.finalize_import(i.node.id, i.span);
5238 ViewPathGlob(_, id) => {
5239 if !self.used_imports.contains(&(id, TypeNS)) &&
5240 !self.used_imports.contains(&(id, ValueNS)) {
5241 self.session.add_lint(UnusedImports, id, p.span,
5242 "unused import".to_owned());
5251 // We have information about whether `use` (import) directives are actually used now.
5252 // If an import is not used at all, we signal a lint error. If an import is only used
5253 // for a single namespace, we remove the other namespace from the recorded privacy
5254 // information. That means in privacy.rs, we will only check imports and namespaces
5255 // which are used. In particular, this means that if an import could name either a
5256 // public or private item, we will check the correct thing, dependent on how the import
5258 fn finalize_import(&mut self, id: NodeId, span: Span) {
5259 debug!("finalizing import uses for {}", self.session.codemap().span_to_snippet(span));
5261 if !self.used_imports.contains(&(id, TypeNS)) &&
5262 !self.used_imports.contains(&(id, ValueNS)) {
5263 self.session.add_lint(UnusedImports, id, span, "unused import".to_owned());
5266 let (v_priv, t_priv) = match self.last_private.find(&id) {
5267 Some(&LastImport{value_priv: v,
5270 type_used: _}) => (v, t),
5271 Some(_) => fail!("We should only have LastImport for `use` directives"),
5275 let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
5280 let t_used = if self.used_imports.contains(&(id, TypeNS)) {
5286 match (v_priv, t_priv) {
5287 // Since some items may be both in the value _and_ type namespaces (e.g., structs)
5288 // we might have two LastPrivates pointing at the same thing. There is no point
5289 // checking both, so lets not check the value one.
5290 (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
5294 self.last_private.insert(id, LastImport{value_priv: v_priv,
5297 type_used: t_used});
5303 // Diagnostics are not particularly efficient, because they're rarely
5307 /// A somewhat inefficient routine to obtain the name of a module.
5308 fn module_to_str(&mut self, module: &Module) -> ~str {
5309 let mut idents = Vec::new();
5311 fn collect_mod(idents: &mut Vec<ast::Ident>, module: &Module) {
5312 match module.parent_link {
5314 ModuleParentLink(ref module, name) => {
5316 collect_mod(idents, &*module.upgrade().unwrap());
5318 BlockParentLink(ref module, _) => {
5319 idents.push(special_idents::opaque);
5320 collect_mod(idents, &*module.upgrade().unwrap());
5324 collect_mod(&mut idents, module);
5326 if idents.len() == 0 {
5327 return "???".to_owned();
5329 self.idents_to_str(idents.move_iter().rev()
5330 .collect::<Vec<ast::Ident>>()
5334 #[allow(dead_code)] // useful for debugging
5335 fn dump_module(&mut self, module_: Rc<Module>) {
5336 debug!("Dump of module `{}`:", self.module_to_str(&*module_));
5338 debug!("Children:");
5339 self.populate_module_if_necessary(&module_);
5340 for (&name, _) in module_.children.borrow().iter() {
5341 debug!("* {}", token::get_name(name));
5344 debug!("Import resolutions:");
5345 let import_resolutions = module_.import_resolutions.borrow();
5346 for (&name, import_resolution) in import_resolutions.iter() {
5348 match import_resolution.target_for_namespace(ValueNS) {
5349 None => { value_repr = "".to_owned(); }
5351 value_repr = " value:?".to_owned();
5357 match import_resolution.target_for_namespace(TypeNS) {
5358 None => { type_repr = "".to_owned(); }
5360 type_repr = " type:?".to_owned();
5365 debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
5370 pub struct CrateMap {
5371 pub def_map: DefMap,
5372 pub exp_map2: ExportMap2,
5373 pub trait_map: TraitMap,
5374 pub external_exports: ExternalExports,
5375 pub last_private_map: LastPrivateMap,
5378 /// Entry point to crate resolution.
5379 pub fn resolve_crate(session: &Session,
5380 lang_items: &LanguageItems,
5383 let mut resolver = Resolver(session, lang_items, krate.span);
5384 resolver.resolve(krate);
5385 let Resolver { def_map, export_map2, trait_map, last_private,
5386 external_exports, .. } = resolver;
5389 exp_map2: export_map2,
5390 trait_map: trait_map,
5391 external_exports: external_exports,
5392 last_private_map: last_private,