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};
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::strbuf::StrBuf;
41 pub type DefMap = @RefCell<NodeMap<Def>>;
45 binding_mode: BindingMode,
48 // Map from the name in a pattern to its binding mode.
49 type BindingMap = HashMap<Name,binding_info>;
51 // Trait method resolution
52 pub type TraitMap = NodeMap<Vec<DefId> >;
54 // This is the replacement export map. It maps a module to all of the exports
56 pub type ExportMap2 = @RefCell<NodeMap<Vec<Export2> >>;
59 pub name: ~str, // The name of the target.
60 pub def_id: DefId, // The definition of the target.
63 // This set contains all exported definitions from external crates. The set does
64 // not contain any entries from local crates.
65 pub type ExternalExports = DefIdSet;
68 pub type LastPrivateMap = NodeMap<LastPrivate>;
70 pub enum LastPrivate {
72 // `use` directives (imports) can refer to two separate definitions in the
73 // type and value namespaces. We record here the last private node for each
74 // and whether the import is in fact used for each.
75 // If the Option<PrivateDep> fields are None, it means there is no defintion
77 LastImport{pub value_priv: Option<PrivateDep>,
78 pub value_used: ImportUse,
79 pub type_priv: Option<PrivateDep>,
80 pub type_used: ImportUse},
88 // How an import is used.
91 Unused, // The import is not used.
92 Used, // The import is used.
96 fn or(self, other: LastPrivate) -> LastPrivate {
98 (me, LastMod(AllPublic)) => me,
105 enum PatternBindingMode {
107 LocalIrrefutableMode,
108 ArgumentIrrefutableMode,
111 #[deriving(Eq, TotalEq, Hash)]
118 enum NamespaceError {
125 /// A NamespaceResult represents the result of resolving an import in
126 /// a particular namespace. The result is either definitely-resolved,
127 /// definitely- unresolved, or unknown.
128 enum NamespaceResult {
129 /// Means that resolve hasn't gathered enough information yet to determine
130 /// whether the name is bound in this namespace. (That is, it hasn't
131 /// resolved all `use` directives yet.)
133 /// Means that resolve has determined that the name is definitely
134 /// not bound in the namespace.
136 /// Means that resolve has determined that the name is bound in the Module
137 /// argument, and specified by the NameBindings argument.
138 BoundResult(@Module, @NameBindings)
141 impl NamespaceResult {
142 fn is_unknown(&self) -> bool {
144 UnknownResult => true,
148 fn is_unbound(&self) -> bool {
150 UnboundResult => true,
156 enum NameDefinition {
157 NoNameDefinition, //< The name was unbound.
158 ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
159 ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
162 impl<'a> Visitor<()> for Resolver<'a> {
163 fn visit_item(&mut self, item: &Item, _: ()) {
164 self.resolve_item(item);
166 fn visit_arm(&mut self, arm: &Arm, _: ()) {
167 self.resolve_arm(arm);
169 fn visit_block(&mut self, block: &Block, _: ()) {
170 self.resolve_block(block);
172 fn visit_expr(&mut self, expr: &Expr, _: ()) {
173 self.resolve_expr(expr);
175 fn visit_local(&mut self, local: &Local, _: ()) {
176 self.resolve_local(local);
178 fn visit_ty(&mut self, ty: &Ty, _: ()) {
179 self.resolve_type(ty);
183 /// Contains data for specific types of import directives.
184 enum ImportDirectiveSubclass {
185 SingleImport(Ident /* target */, Ident /* source */),
189 /// The context that we thread through while building the reduced graph.
191 enum ReducedGraphParent {
192 ModuleReducedGraphParent(@Module)
195 impl ReducedGraphParent {
196 fn module(&self) -> @Module {
198 ModuleReducedGraphParent(m) => {
205 enum ResolveResult<T> {
206 Failed, // Failed to resolve the name.
207 Indeterminate, // Couldn't determine due to unresolved globs.
208 Success(T) // Successfully resolved the import.
211 impl<T> ResolveResult<T> {
212 fn indeterminate(&self) -> bool {
213 match *self { Indeterminate => true, _ => false }
217 enum TypeParameters<'a> {
218 NoTypeParameters, //< No type parameters.
219 HasTypeParameters(&'a Generics, //< Type parameters.
220 NodeId, //< ID of the enclosing item
222 // The index to start numbering the type parameters at.
223 // This is zero if this is the outermost set of type
224 // parameters, or equal to the number of outer type
225 // parameters. For example, if we have:
228 // fn method<U>() { ... }
231 // The index at the method site will be 1, because the
232 // outer T had index 0.
235 // The kind of the rib used for type parameters.
239 // The rib kind controls the translation of argument or local definitions
240 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
243 // No translation needs to be applied.
246 // We passed through a function scope at the given node ID. Translate
247 // upvars as appropriate.
248 FunctionRibKind(NodeId /* func id */, NodeId /* body id */),
250 // We passed through an impl or trait and are now in one of its
251 // methods. Allow references to ty params that impl or trait
252 // binds. Disallow any other upvars (including other ty params that are
254 // parent; method itself
255 MethodRibKind(NodeId, MethodSort),
257 // We passed through a function *item* scope. Disallow upvars.
258 OpaqueFunctionRibKind,
260 // We're in a constant item. Can't refer to dynamic stuff.
264 // Methods can be required or provided. Required methods only occur in traits.
270 enum UseLexicalScopeFlag {
275 enum SearchThroughModulesFlag {
276 DontSearchThroughModules,
280 enum ModulePrefixResult {
282 PrefixFound(@Module, uint)
286 enum NameSearchType {
287 /// We're doing a name search in order to resolve a `use` directive.
290 /// We're doing a name search in order to resolve a path type, a path
291 /// expression, or a path pattern.
295 enum BareIdentifierPatternResolution {
296 FoundStructOrEnumVariant(Def, LastPrivate),
297 FoundConst(Def, LastPrivate),
298 BareIdentifierPatternUnresolved
301 // Specifies how duplicates should be handled when adding a child item if
302 // another item exists with the same name in some namespace.
304 enum DuplicateCheckingMode {
305 ForbidDuplicateModules,
306 ForbidDuplicateTypes,
307 ForbidDuplicateValues,
308 ForbidDuplicateTypesAndValues,
314 bindings: RefCell<HashMap<Name, DefLike>>,
319 fn new(kind: RibKind) -> Rib {
321 bindings: RefCell::new(HashMap::new()),
327 /// One import directive.
328 struct ImportDirective {
329 module_path: Vec<Ident> ,
330 subclass: @ImportDirectiveSubclass,
333 is_public: bool, // see note in ImportResolution about how to use this
336 impl ImportDirective {
337 fn new(module_path: Vec<Ident> ,
338 subclass: @ImportDirectiveSubclass,
344 module_path: module_path,
348 is_public: is_public,
353 /// The item that an import resolves to.
356 target_module: @Module,
357 bindings: @NameBindings,
361 fn new(target_module: @Module, bindings: @NameBindings) -> Target {
363 target_module: target_module,
369 /// An ImportResolution represents a particular `use` directive.
370 struct ImportResolution {
371 /// Whether this resolution came from a `use` or a `pub use`. Note that this
372 /// should *not* be used whenever resolution is being performed, this is
373 /// only looked at for glob imports statements currently. Privacy testing
374 /// occurs during a later phase of compilation.
375 is_public: Cell<bool>,
377 // The number of outstanding references to this name. When this reaches
378 // zero, outside modules can count on the targets being correct. Before
379 // then, all bets are off; future imports could override this name.
380 outstanding_references: Cell<uint>,
382 /// The value that this `use` directive names, if there is one.
383 value_target: RefCell<Option<Target>>,
384 /// The source node of the `use` directive leading to the value target
386 value_id: Cell<NodeId>,
388 /// The type that this `use` directive names, if there is one.
389 type_target: RefCell<Option<Target>>,
390 /// The source node of the `use` directive leading to the type target
392 type_id: Cell<NodeId>,
395 fn get<T: Clone>(cell: &RefCell<T>) -> T {
396 cell.borrow().clone()
399 impl ImportResolution {
400 fn new(id: NodeId, is_public: bool) -> ImportResolution {
402 type_id: Cell::new(id),
403 value_id: Cell::new(id),
404 outstanding_references: Cell::new(0),
405 value_target: RefCell::new(None),
406 type_target: RefCell::new(None),
407 is_public: Cell::new(is_public),
411 fn target_for_namespace(&self, namespace: Namespace)
414 TypeNS => return self.type_target.borrow().clone(),
415 ValueNS => return self.value_target.borrow().clone(),
419 fn id(&self, namespace: Namespace) -> NodeId {
421 TypeNS => self.type_id.get(),
422 ValueNS => self.value_id.get(),
427 /// The link from a module up to its nearest parent node.
430 ModuleParentLink(@Module, Ident),
431 BlockParentLink(@Module, NodeId)
434 /// The type of module this is.
444 /// One node in the tree of modules.
446 parent_link: ParentLink,
447 def_id: Cell<Option<DefId>>,
448 kind: Cell<ModuleKind>,
451 children: RefCell<HashMap<Name, @NameBindings>>,
452 imports: RefCell<Vec<@ImportDirective> >,
454 // The external module children of this node that were declared with
456 external_module_children: RefCell<HashMap<Name, @Module>>,
458 // The anonymous children of this node. Anonymous children are pseudo-
459 // modules that are implicitly created around items contained within
462 // For example, if we have this:
470 // There will be an anonymous module created around `g` with the ID of the
471 // entry block for `f`.
472 anonymous_children: RefCell<NodeMap<@Module>>,
474 // The status of resolving each import in this module.
475 import_resolutions: RefCell<HashMap<Name, @ImportResolution>>,
477 // The number of unresolved globs that this module exports.
478 glob_count: Cell<uint>,
480 // The index of the import we're resolving.
481 resolved_import_count: Cell<uint>,
483 // Whether this module is populated. If not populated, any attempt to
484 // access the children must be preceded with a
485 // `populate_module_if_necessary` call.
486 populated: Cell<bool>,
490 fn new(parent_link: ParentLink,
491 def_id: Option<DefId>,
497 parent_link: parent_link,
498 def_id: Cell::new(def_id),
499 kind: Cell::new(kind),
500 is_public: is_public,
501 children: RefCell::new(HashMap::new()),
502 imports: RefCell::new(Vec::new()),
503 external_module_children: RefCell::new(HashMap::new()),
504 anonymous_children: RefCell::new(NodeMap::new()),
505 import_resolutions: RefCell::new(HashMap::new()),
506 glob_count: Cell::new(0),
507 resolved_import_count: Cell::new(0),
508 populated: Cell::new(!external),
512 fn all_imports_resolved(&self) -> bool {
513 self.imports.borrow().len() == self.resolved_import_count.get()
517 // Records a possibly-private type definition.
520 is_public: bool, // see note in ImportResolution about how to use this
521 module_def: Option<@Module>,
522 type_def: Option<Def>,
523 type_span: Option<Span>
526 // Records a possibly-private value definition.
529 is_public: bool, // see note in ImportResolution about how to use this
531 value_span: Option<Span>,
534 // Records the definitions (at most one for each namespace) that a name is
536 struct NameBindings {
537 type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
538 value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
541 /// Ways in which a trait can be referenced
542 enum TraitReferenceType {
543 TraitImplementation, // impl SomeTrait for T { ... }
544 TraitDerivation, // trait T : SomeTrait { ... }
545 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
549 /// Creates a new module in this set of name bindings.
550 fn define_module(&self,
551 parent_link: ParentLink,
552 def_id: Option<DefId>,
557 // Merges the module with the existing type def or creates a new one.
558 let module_ = @Module::new(parent_link, def_id, kind, external,
560 let type_def = self.type_def.borrow().clone();
563 *self.type_def.borrow_mut() = Some(TypeNsDef {
564 is_public: is_public,
565 module_def: Some(module_),
571 *self.type_def.borrow_mut() = Some(TypeNsDef {
572 is_public: is_public,
573 module_def: Some(module_),
575 type_def: type_def.type_def
581 /// Sets the kind of the module, creating a new one if necessary.
582 fn set_module_kind(&self,
583 parent_link: ParentLink,
584 def_id: Option<DefId>,
589 let type_def = self.type_def.borrow().clone();
592 let module = @Module::new(parent_link, def_id, kind,
593 external, is_public);
594 *self.type_def.borrow_mut() = Some(TypeNsDef {
595 is_public: is_public,
596 module_def: Some(module),
602 match type_def.module_def {
604 let module = @Module::new(parent_link,
609 *self.type_def.borrow_mut() = Some(TypeNsDef {
610 is_public: is_public,
611 module_def: Some(module),
612 type_def: type_def.type_def,
616 Some(module_def) => module_def.kind.set(kind),
622 /// Records a type definition.
623 fn define_type(&self, def: Def, sp: Span, is_public: bool) {
624 // Merges the type with the existing type def or creates a new one.
625 let type_def = self.type_def.borrow().clone();
628 *self.type_def.borrow_mut() = Some(TypeNsDef {
632 is_public: is_public,
636 *self.type_def.borrow_mut() = Some(TypeNsDef {
639 module_def: type_def.module_def,
640 is_public: is_public,
646 /// Records a value definition.
647 fn define_value(&self, def: Def, sp: Span, is_public: bool) {
648 *self.value_def.borrow_mut() = Some(ValueNsDef {
650 value_span: Some(sp),
651 is_public: is_public,
655 /// Returns the module node if applicable.
656 fn get_module_if_available(&self) -> Option<@Module> {
657 match *self.type_def.borrow() {
658 Some(ref type_def) => (*type_def).module_def,
664 * Returns the module node. Fails if this node does not have a module
667 fn get_module(&self) -> @Module {
668 match self.get_module_if_available() {
670 fail!("get_module called on a node with no module \
673 Some(module_def) => module_def
677 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
679 TypeNS => return self.type_def.borrow().is_some(),
680 ValueNS => return self.value_def.borrow().is_some()
684 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
686 TypeNS => match *self.type_def.borrow() {
687 Some(def) => def.is_public, None => false
689 ValueNS => match *self.value_def.borrow() {
690 Some(def) => def.is_public, None => false
695 fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
698 match *self.type_def.borrow() {
701 match type_def.type_def {
702 Some(type_def) => Some(type_def),
704 match type_def.module_def {
706 match module.def_id.get() {
707 Some(did) => Some(DefMod(did)),
719 match *self.value_def.borrow() {
721 Some(value_def) => Some(value_def.def)
727 fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
728 if self.defined_in_namespace(namespace) {
731 match *self.type_def.borrow() {
733 Some(type_def) => type_def.type_span
737 match *self.value_def.borrow() {
739 Some(value_def) => value_def.value_span
749 fn NameBindings() -> NameBindings {
751 type_def: RefCell::new(None),
752 value_def: RefCell::new(None),
756 /// Interns the names of the primitive types.
757 struct PrimitiveTypeTable {
758 primitive_types: HashMap<Name, PrimTy>,
761 impl PrimitiveTypeTable {
762 fn intern(&mut self, string: &str, primitive_type: PrimTy) {
763 self.primitive_types.insert(token::intern(string), primitive_type);
767 fn PrimitiveTypeTable() -> PrimitiveTypeTable {
768 let mut table = PrimitiveTypeTable {
769 primitive_types: HashMap::new()
772 table.intern("bool", TyBool);
773 table.intern("char", TyChar);
774 table.intern("f32", TyFloat(TyF32));
775 table.intern("f64", TyFloat(TyF64));
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: @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_map: @RefCell::new(HashMap::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: @LanguageItems,
861 graph_root: @NameBindings,
863 method_map: @RefCell<HashMap<Name, HashSet<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: @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, c);
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);
985 /// Returns the current module tracked by the reduced graph parent.
986 fn get_module_from_parent(&mut self,
987 reduced_graph_parent: ReducedGraphParent)
989 match reduced_graph_parent {
990 ModuleReducedGraphParent(module_) => {
997 * Adds a new child item to the module definition of the parent node and
998 * returns its corresponding name bindings as well as the current parent.
999 * Or, if we're inside a block, creates (or reuses) an anonymous module
1000 * corresponding to the innermost block ID and returns the name bindings
1001 * as well as the newly-created parent.
1003 * If this node does not have a module definition and we are not inside
1006 fn add_child(&mut self,
1008 reduced_graph_parent: ReducedGraphParent,
1009 duplicate_checking_mode: DuplicateCheckingMode,
1010 // For printing errors
1012 -> (@NameBindings, ReducedGraphParent) {
1013 // If this is the immediate descendant of a module, then we add the
1014 // child name directly. Otherwise, we create or reuse an anonymous
1015 // module and add the child to that.
1018 match reduced_graph_parent {
1019 ModuleReducedGraphParent(parent_module) => {
1020 module_ = parent_module;
1024 // Add or reuse the child.
1025 let new_parent = ModuleReducedGraphParent(module_);
1026 let child_opt = module_.children.borrow().find_copy(&name.name);
1029 let child = @NameBindings();
1030 module_.children.borrow_mut().insert(name.name, child);
1031 return (child, new_parent);
1034 // Enforce the duplicate checking mode:
1036 // * If we're requesting duplicate module checking, check that
1037 // there isn't a module in the module with the same name.
1039 // * If we're requesting duplicate type checking, check that
1040 // there isn't a type in the module with the same name.
1042 // * If we're requesting duplicate value checking, check that
1043 // there isn't a value in the module with the same name.
1045 // * If we're requesting duplicate type checking and duplicate
1046 // value checking, check that there isn't a duplicate type
1047 // and a duplicate value with the same name.
1049 // * If no duplicate checking was requested at all, do
1052 let mut duplicate_type = NoError;
1053 let ns = match duplicate_checking_mode {
1054 ForbidDuplicateModules => {
1055 if child.get_module_if_available().is_some() {
1056 duplicate_type = ModuleError;
1060 ForbidDuplicateTypes => {
1061 match child.def_for_namespace(TypeNS) {
1062 Some(DefMod(_)) | None => {}
1063 Some(_) => duplicate_type = TypeError
1067 ForbidDuplicateValues => {
1068 if child.defined_in_namespace(ValueNS) {
1069 duplicate_type = ValueError;
1073 ForbidDuplicateTypesAndValues => {
1075 match child.def_for_namespace(TypeNS) {
1076 Some(DefMod(_)) | None => {}
1079 duplicate_type = TypeError;
1082 if child.defined_in_namespace(ValueNS) {
1083 duplicate_type = ValueError;
1088 OverwriteDuplicates => None
1090 if duplicate_type != NoError {
1091 // Return an error here by looking up the namespace that
1092 // had the duplicate.
1093 let ns = ns.unwrap();
1094 self.resolve_error(sp,
1095 format!("duplicate definition of {} `{}`",
1096 namespace_error_to_str(duplicate_type),
1097 token::get_ident(name)));
1099 let r = child.span_for_namespace(ns);
1100 for sp in r.iter() {
1101 self.session.span_note(*sp,
1102 format!("first definition of {} `{}` here",
1103 namespace_error_to_str(duplicate_type),
1104 token::get_ident(name)));
1108 return (child, new_parent);
1113 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1114 // If the block has view items, we need an anonymous module.
1115 if block.view_items.len() > 0 {
1119 // Check each statement.
1120 for statement in block.stmts.iter() {
1121 match statement.node {
1122 StmtDecl(declaration, _) => {
1123 match declaration.node {
1138 // If we found neither view items nor items, we don't need to create
1139 // an anonymous module.
1144 fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Ident)
1147 ModuleReducedGraphParent(module_) => {
1148 return ModuleParentLink(module_, name);
1153 /// Constructs the reduced graph for one item.
1154 fn build_reduced_graph_for_item(&mut self,
1156 parent: ReducedGraphParent)
1157 -> ReducedGraphParent
1159 let ident = item.ident;
1161 let is_public = item.vis == ast::Public;
1165 let (name_bindings, new_parent) =
1166 self.add_child(ident, parent, ForbidDuplicateModules, sp);
1168 let parent_link = self.get_parent_link(new_parent, ident);
1169 let def_id = DefId { krate: 0, node: item.id };
1170 name_bindings.define_module(parent_link,
1174 item.vis == ast::Public,
1177 ModuleReducedGraphParent(name_bindings.get_module())
1180 ItemForeignMod(..) => parent,
1182 // These items live in the value namespace.
1183 ItemStatic(_, m, _) => {
1184 let (name_bindings, _) =
1185 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1186 let mutbl = m == ast::MutMutable;
1188 name_bindings.define_value
1189 (DefStatic(local_def(item.id), mutbl), sp, is_public);
1192 ItemFn(_, fn_style, _, _, _) => {
1193 let (name_bindings, new_parent) =
1194 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1196 let def = DefFn(local_def(item.id), fn_style);
1197 name_bindings.define_value(def, sp, is_public);
1201 // These items live in the type namespace.
1203 let (name_bindings, _) =
1204 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1206 name_bindings.define_type
1207 (DefTy(local_def(item.id)), sp, is_public);
1211 ItemEnum(ref enum_definition, _) => {
1212 let (name_bindings, new_parent) =
1213 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1215 name_bindings.define_type
1216 (DefTy(local_def(item.id)), sp, is_public);
1218 for &variant in (*enum_definition).variants.iter() {
1219 self.build_reduced_graph_for_variant(
1228 // These items live in both the type and value namespaces.
1229 ItemStruct(struct_def, _) => {
1230 // Adding to both Type and Value namespaces or just Type?
1231 let (forbid, ctor_id) = match struct_def.ctor_id {
1232 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1233 None => (ForbidDuplicateTypes, None)
1236 let (name_bindings, new_parent) = self.add_child(ident, parent, forbid, sp);
1238 // Define a name in the type namespace.
1239 name_bindings.define_type(DefTy(local_def(item.id)), sp, is_public);
1241 // If this is a newtype or unit-like struct, define a name
1242 // in the value namespace as well
1243 ctor_id.while_some(|cid| {
1244 name_bindings.define_value(DefStruct(local_def(cid)), sp,
1249 // Record the def ID of this struct.
1250 self.structs.insert(local_def(item.id));
1255 ItemImpl(_, None, ty, ref methods) => {
1256 // If this implements an anonymous trait, then add all the
1257 // methods within to a new module, if the type was defined
1258 // within this module.
1260 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1261 // should modify anonymous traits to only be implementable in
1262 // the same module that declared the type.
1264 // Create the module and add all methods.
1266 TyPath(ref path, _, _) if path.segments.len() == 1 => {
1267 let name = path_to_ident(path);
1269 let parent_opt = parent.module().children.borrow()
1270 .find_copy(&name.name);
1271 let new_parent = match parent_opt {
1272 // It already exists
1273 Some(child) if child.get_module_if_available()
1275 child.get_module().kind.get() ==
1277 ModuleReducedGraphParent(child.get_module())
1279 // Create the module
1281 let (name_bindings, new_parent) =
1282 self.add_child(name,
1284 ForbidDuplicateModules,
1288 self.get_parent_link(new_parent, ident);
1289 let def_id = local_def(item.id);
1292 !name_bindings.defined_in_namespace(ns) ||
1293 name_bindings.defined_in_public_namespace(ns);
1295 name_bindings.define_module(parent_link,
1302 ModuleReducedGraphParent(
1303 name_bindings.get_module())
1307 // For each method...
1308 for method in methods.iter() {
1309 // Add the method to the module.
1310 let ident = method.ident;
1311 let (method_name_bindings, _) =
1312 self.add_child(ident,
1314 ForbidDuplicateValues,
1316 let def = match method.explicit_self.node {
1318 // Static methods become
1319 // `def_static_method`s.
1320 DefStaticMethod(local_def(method.id),
1326 // Non-static methods become
1328 DefMethod(local_def(method.id), None)
1332 let is_public = method.vis == ast::Public;
1333 method_name_bindings.define_value(def,
1344 ItemImpl(_, Some(_), _, _) => parent,
1346 ItemTrait(_, _, ref methods) => {
1347 let (name_bindings, new_parent) =
1348 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1350 // Add all the methods within to a new module.
1351 let parent_link = self.get_parent_link(parent, ident);
1352 name_bindings.define_module(parent_link,
1353 Some(local_def(item.id)),
1356 item.vis == ast::Public,
1358 let module_parent = ModuleReducedGraphParent(name_bindings.
1361 // Add the names of all the methods to the trait info.
1362 let mut method_names = HashMap::new();
1363 for method in methods.iter() {
1364 let ty_m = trait_method_to_ty_method(method);
1366 let ident = ty_m.ident;
1368 // Add it as a name in the trait module.
1369 let def = match ty_m.explicit_self.node {
1371 // Static methods become `def_static_method`s.
1372 DefStaticMethod(local_def(ty_m.id),
1373 FromTrait(local_def(item.id)),
1377 // Non-static methods become `def_method`s.
1378 DefMethod(local_def(ty_m.id),
1379 Some(local_def(item.id)))
1383 let (method_name_bindings, _) =
1384 self.add_child(ident,
1386 ForbidDuplicateValues,
1388 method_name_bindings.define_value(def, ty_m.span, true);
1390 // Add it to the trait info if not static.
1391 match ty_m.explicit_self.node {
1394 method_names.insert(ident.name, ());
1399 let def_id = local_def(item.id);
1400 for (name, _) in method_names.iter() {
1401 let mut method_map = self.method_map.borrow_mut();
1402 if !method_map.contains_key(name) {
1403 method_map.insert(*name, HashSet::new());
1405 match method_map.find_mut(name) {
1406 Some(s) => { s.insert(def_id); },
1407 _ => fail!("can't happen"),
1411 name_bindings.define_type(DefTrait(def_id), sp, is_public);
1414 ItemMac(..) => parent
1418 // Constructs the reduced graph for one variant. Variants exist in the
1419 // type and/or value namespaces.
1420 fn build_reduced_graph_for_variant(&mut self,
1423 parent: ReducedGraphParent,
1424 parent_public: bool) {
1425 let ident = variant.node.name;
1426 // FIXME: this is unfortunate to have to do this privacy calculation
1427 // here. This should be living in middle::privacy, but it's
1428 // necessary to keep around in some form becaues of glob imports...
1429 let is_public = parent_public && variant.node.vis != ast::Private;
1431 match variant.node.kind {
1432 TupleVariantKind(_) => {
1433 let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues,
1435 child.define_value(DefVariant(item_id,
1436 local_def(variant.node.id), false),
1437 variant.span, is_public);
1439 StructVariantKind(_) => {
1440 let (child, _) = self.add_child(ident, parent, ForbidDuplicateTypesAndValues,
1442 child.define_type(DefVariant(item_id,
1443 local_def(variant.node.id), true),
1444 variant.span, is_public);
1445 self.structs.insert(local_def(variant.node.id));
1450 /// Constructs the reduced graph for one 'view item'. View items consist
1451 /// of imports and use directives.
1452 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1453 parent: ReducedGraphParent) {
1454 match view_item.node {
1455 ViewItemUse(ref view_paths) => {
1456 for view_path in view_paths.iter() {
1457 // Extract and intern the module part of the path. For
1458 // globs and lists, the path is found directly in the AST;
1459 // for simple paths we have to munge the path a little.
1461 let mut module_path = Vec::new();
1462 match view_path.node {
1463 ViewPathSimple(_, ref full_path, _) => {
1464 let path_len = full_path.segments.len();
1465 assert!(path_len != 0);
1467 for (i, segment) in full_path.segments
1470 if i != path_len - 1 {
1471 module_path.push(segment.identifier)
1476 ViewPathGlob(ref module_ident_path, _) |
1477 ViewPathList(ref module_ident_path, _, _) => {
1478 for segment in module_ident_path.segments.iter() {
1479 module_path.push(segment.identifier)
1484 // Build up the import directives.
1485 let module_ = self.get_module_from_parent(parent);
1486 let is_public = view_item.vis == ast::Public;
1487 match view_path.node {
1488 ViewPathSimple(binding, ref full_path, id) => {
1490 full_path.segments.last().unwrap().identifier;
1491 let subclass = @SingleImport(binding,
1493 self.build_import_directive(module_,
1500 ViewPathList(_, ref source_idents, _) => {
1501 for source_ident in source_idents.iter() {
1502 let name = source_ident.node.name;
1503 let subclass = @SingleImport(name, name);
1504 self.build_import_directive(
1506 module_path.clone(),
1509 source_ident.node.id,
1513 ViewPathGlob(_, id) => {
1514 self.build_import_directive(module_,
1525 ViewItemExternCrate(name, _, node_id) => {
1526 // n.b. we don't need to look at the path option here, because cstore already did
1527 match self.session.cstore.find_extern_mod_stmt_cnum(node_id) {
1529 let def_id = DefId { krate: crate_id, node: 0 };
1530 self.external_exports.insert(def_id);
1531 let parent_link = ModuleParentLink
1532 (self.get_module_from_parent(parent), name);
1533 let external_module = @Module::new(parent_link,
1539 parent.module().external_module_children
1540 .borrow_mut().insert(name.name,
1543 self.build_reduced_graph_for_external_crate(
1546 None => {} // Ignore.
1552 /// Constructs the reduced graph for one foreign item.
1553 fn build_reduced_graph_for_foreign_item(&mut self,
1554 foreign_item: &ForeignItem,
1555 parent: ReducedGraphParent,
1557 ReducedGraphParent|) {
1558 let name = foreign_item.ident;
1559 let is_public = foreign_item.vis == ast::Public;
1560 let (name_bindings, new_parent) =
1561 self.add_child(name, parent, ForbidDuplicateValues,
1564 match foreign_item.node {
1565 ForeignItemFn(_, ref generics) => {
1566 let def = DefFn(local_def(foreign_item.id), UnsafeFn);
1567 name_bindings.define_value(def, foreign_item.span, is_public);
1569 self.with_type_parameter_rib(
1570 HasTypeParameters(generics,
1574 |this| f(this, new_parent));
1576 ForeignItemStatic(_, m) => {
1577 let def = DefStatic(local_def(foreign_item.id), m);
1578 name_bindings.define_value(def, foreign_item.span, is_public);
1585 fn build_reduced_graph_for_block(&mut self,
1587 parent: ReducedGraphParent)
1588 -> ReducedGraphParent
1590 if self.block_needs_anonymous_module(block) {
1591 let block_id = block.id;
1593 debug!("(building reduced graph for block) creating a new \
1594 anonymous module for block {}",
1597 let parent_module = self.get_module_from_parent(parent);
1598 let new_module = @Module::new(
1599 BlockParentLink(parent_module, block_id),
1601 AnonymousModuleKind,
1604 parent_module.anonymous_children.borrow_mut()
1605 .insert(block_id, new_module);
1606 ModuleReducedGraphParent(new_module)
1612 fn handle_external_def(&mut self,
1615 child_name_bindings: @NameBindings,
1618 new_parent: ReducedGraphParent) {
1619 debug!("(building reduced graph for \
1620 external crate) building external def, priv {:?}",
1622 let is_public = vis == ast::Public;
1623 let is_exported = is_public && match new_parent {
1624 ModuleReducedGraphParent(module) => {
1625 match module.def_id.get() {
1627 Some(did) => self.external_exports.contains(&did)
1632 self.external_exports.insert(def_id_of_def(def));
1635 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1637 let type_def = child_name_bindings.type_def.borrow().clone();
1639 Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1640 debug!("(building reduced graph for external crate) \
1641 already created module");
1642 module_def.def_id.set(Some(def_id));
1645 debug!("(building reduced graph for \
1646 external crate) building module \
1648 let parent_link = self.get_parent_link(new_parent, ident);
1650 child_name_bindings.define_module(parent_link,
1663 DefMod(_) | DefForeignMod(_) => {}
1664 DefVariant(_, variant_id, is_struct) => {
1665 debug!("(building reduced graph for external crate) building \
1668 // We assume the parent is visible, or else we wouldn't have seen
1669 // it. Also variants are public-by-default if the parent was also
1671 let is_public = vis != ast::Private;
1673 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1674 self.structs.insert(variant_id);
1676 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1679 DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
1680 debug!("(building reduced graph for external \
1681 crate) building value (fn/static) {}", final_ident);
1682 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1684 DefTrait(def_id) => {
1685 debug!("(building reduced graph for external \
1686 crate) building type {}", final_ident);
1688 // If this is a trait, add all the method names
1689 // to the trait info.
1691 let method_def_ids =
1692 csearch::get_trait_method_def_ids(&self.session.cstore, def_id);
1693 let mut interned_method_names = HashSet::new();
1694 for &method_def_id in method_def_ids.iter() {
1695 let (method_name, explicit_self) =
1696 csearch::get_method_name_and_explicit_self(&self.session.cstore,
1699 debug!("(building reduced graph for \
1700 external crate) ... adding \
1702 token::get_ident(method_name));
1704 // Add it to the trait info if not static.
1705 if explicit_self != SelfStatic {
1706 interned_method_names.insert(method_name.name);
1709 self.external_exports.insert(method_def_id);
1712 for name in interned_method_names.iter() {
1713 let mut method_map = self.method_map.borrow_mut();
1714 if !method_map.contains_key(name) {
1715 method_map.insert(*name, HashSet::new());
1717 match method_map.find_mut(name) {
1718 Some(s) => { s.insert(def_id); },
1719 _ => fail!("can't happen"),
1723 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1725 // Define a module if necessary.
1726 let parent_link = self.get_parent_link(new_parent, ident);
1727 child_name_bindings.set_module_kind(parent_link,
1735 debug!("(building reduced graph for external \
1736 crate) building type {}", final_ident);
1738 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1740 DefStruct(def_id) => {
1741 debug!("(building reduced graph for external \
1742 crate) building type and value for {}",
1744 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1745 if csearch::get_struct_fields(&self.session.cstore, def_id).len() == 0 {
1746 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1748 self.structs.insert(def_id);
1751 debug!("(building reduced graph for external crate) \
1752 ignoring {:?}", def);
1753 // Ignored; handled elsewhere.
1755 DefArg(..) | DefLocal(..) | DefPrimTy(..) |
1756 DefTyParam(..) | DefBinding(..) |
1757 DefUse(..) | DefUpvar(..) | DefRegion(..) |
1758 DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
1759 fail!("didn't expect `{:?}`", def);
1764 /// Builds the reduced graph for a single item in an external crate.
1765 fn build_reduced_graph_for_external_crate_def(&mut self,
1769 visibility: Visibility) {
1772 // Add the new child item, if necessary.
1774 DefForeignMod(def_id) => {
1775 // Foreign modules have no names. Recur and populate
1777 csearch::each_child_of_item(&self.session.cstore,
1782 self.build_reduced_graph_for_external_crate_def(
1790 let (child_name_bindings, new_parent) =
1791 self.add_child(ident,
1792 ModuleReducedGraphParent(root),
1793 OverwriteDuplicates,
1796 self.handle_external_def(def,
1798 child_name_bindings,
1799 token::get_ident(ident).get(),
1806 // We only process static methods of impls here.
1807 match csearch::get_type_name_if_impl(&self.session.cstore, def) {
1809 Some(final_ident) => {
1810 let static_methods_opt =
1811 csearch::get_static_methods_if_impl(&self.session.cstore, def);
1812 match static_methods_opt {
1813 Some(ref static_methods) if
1814 static_methods.len() >= 1 => {
1815 debug!("(building reduced graph for \
1816 external crate) processing \
1817 static methods for type name {}",
1818 token::get_ident(final_ident));
1820 let (child_name_bindings, new_parent) =
1823 ModuleReducedGraphParent(root),
1824 OverwriteDuplicates,
1827 // Process the static methods. First,
1828 // create the module.
1830 let type_def = child_name_bindings.type_def.borrow().clone();
1833 module_def: Some(module_def),
1836 // We already have a module. This
1838 type_module = module_def;
1840 // Mark it as an impl module if
1842 type_module.kind.set(ImplModuleKind);
1846 self.get_parent_link(new_parent,
1848 child_name_bindings.define_module(
1856 child_name_bindings.
1861 // Add each static method to the module.
1863 ModuleReducedGraphParent(type_module);
1864 for static_method_info in
1865 static_methods.iter() {
1866 let ident = static_method_info.ident;
1867 debug!("(building reduced graph for \
1868 external crate) creating \
1869 static method '{}'",
1870 token::get_ident(ident));
1872 let (method_name_bindings, _) =
1873 self.add_child(ident,
1875 OverwriteDuplicates,
1878 static_method_info.def_id,
1879 static_method_info.fn_style);
1881 method_name_bindings.define_value(
1883 visibility == ast::Public);
1887 // Otherwise, do nothing.
1888 Some(_) | None => {}
1894 debug!("(building reduced graph for external crate) \
1900 /// Builds the reduced graph rooted at the given external module.
1901 fn populate_external_module(&mut self, module: @Module) {
1902 debug!("(populating external module) attempting to populate {}",
1903 self.module_to_str(module));
1905 let def_id = match module.def_id.get() {
1907 debug!("(populating external module) ... no def ID!");
1910 Some(def_id) => def_id,
1913 csearch::each_child_of_item(&self.session.cstore,
1915 |def_like, child_ident, visibility| {
1916 debug!("(populating external module) ... found ident: {}",
1917 token::get_ident(child_ident));
1918 self.build_reduced_graph_for_external_crate_def(module,
1923 module.populated.set(true)
1926 /// Ensures that the reduced graph rooted at the given external module
1927 /// is built, building it if it is not.
1928 fn populate_module_if_necessary(&mut self, module: @Module) {
1929 if !module.populated.get() {
1930 self.populate_external_module(module)
1932 assert!(module.populated.get())
1935 /// Builds the reduced graph rooted at the 'use' directive for an external
1937 fn build_reduced_graph_for_external_crate(&mut self,
1939 csearch::each_top_level_item_of_crate(&self.session.cstore,
1944 |def_like, ident, visibility| {
1945 self.build_reduced_graph_for_external_crate_def(root,
1952 /// Creates and adds an import directive to the given module.
1953 fn build_import_directive(&mut self,
1955 module_path: Vec<Ident> ,
1956 subclass: @ImportDirectiveSubclass,
1960 let directive = @ImportDirective::new(module_path,
1963 module_.imports.borrow_mut().push(directive);
1964 // Bump the reference count on the name. Or, if this is a glob, set
1965 // the appropriate flag.
1968 SingleImport(target, _) => {
1969 debug!("(building import directive) building import \
1971 self.idents_to_str(directive.module_path.as_slice()),
1972 token::get_ident(target));
1974 let mut import_resolutions = module_.import_resolutions
1976 match import_resolutions.find(&target.name) {
1977 Some(&resolution) => {
1978 debug!("(building import directive) bumping \
1980 resolution.outstanding_references.set(
1981 resolution.outstanding_references.get() + 1);
1983 // the source of this name is different now
1984 resolution.type_id.set(id);
1985 resolution.value_id.set(id);
1986 resolution.is_public.set(is_public);
1989 debug!("(building import directive) creating new");
1990 let resolution = @ImportResolution::new(id, is_public);
1991 resolution.outstanding_references.set(1);
1992 import_resolutions.insert(target.name, resolution);
1997 // Set the glob flag. This tells us that we don't know the
1998 // module's exports ahead of time.
2000 module_.glob_count.set(module_.glob_count.get() + 1);
2004 self.unresolved_imports += 1;
2007 // Import resolution
2009 // This is a fixed-point algorithm. We resolve imports until our efforts
2010 // are stymied by an unresolved import; then we bail out of the current
2011 // module and continue. We terminate successfully once no more imports
2012 // remain or unsuccessfully when no forward progress in resolving imports
2015 /// Resolves all imports for the crate. This method performs the fixed-
2016 /// point iteration.
2017 fn resolve_imports(&mut self) {
2019 let mut prev_unresolved_imports = 0;
2021 debug!("(resolving imports) iteration {}, {} imports left",
2022 i, self.unresolved_imports);
2024 let module_root = self.graph_root.get_module();
2025 self.resolve_imports_for_module_subtree(module_root);
2027 if self.unresolved_imports == 0 {
2028 debug!("(resolving imports) success");
2032 if self.unresolved_imports == prev_unresolved_imports {
2033 self.report_unresolved_imports(module_root);
2038 prev_unresolved_imports = self.unresolved_imports;
2042 /// Attempts to resolve imports for the given module and all of its
2044 fn resolve_imports_for_module_subtree(&mut self,
2046 debug!("(resolving imports for module subtree) resolving {}",
2047 self.module_to_str(module_));
2048 self.resolve_imports_for_module(module_);
2050 self.populate_module_if_necessary(module_);
2051 for (_, &child_node) in module_.children.borrow().iter() {
2052 match child_node.get_module_if_available() {
2056 Some(child_module) => {
2057 self.resolve_imports_for_module_subtree(child_module);
2062 for (_, &child_module) in module_.anonymous_children.borrow().iter() {
2063 self.resolve_imports_for_module_subtree(child_module);
2067 /// Attempts to resolve imports for the given module only.
2068 fn resolve_imports_for_module(&mut self, module: @Module) {
2069 if module.all_imports_resolved() {
2070 debug!("(resolving imports for module) all imports resolved for \
2072 self.module_to_str(module));
2076 let mut imports = module.imports.borrow_mut();
2077 let import_count = imports.len();
2078 while module.resolved_import_count.get() < import_count {
2079 let import_index = module.resolved_import_count.get();
2080 let import_directive = *imports.get(import_index);
2081 match self.resolve_import_for_module(module, import_directive) {
2083 // We presumably emitted an error. Continue.
2084 let msg = format!("failed to resolve import `{}`",
2085 self.import_path_to_str(
2086 import_directive.module_path
2088 *import_directive.subclass));
2089 self.resolve_error(import_directive.span, msg);
2092 // Bail out. We'll come around next time.
2100 module.resolved_import_count
2101 .set(module.resolved_import_count.get() + 1);
2105 fn idents_to_str(&mut self, idents: &[Ident]) -> ~str {
2106 let mut first = true;
2107 let mut result = StrBuf::new();
2108 for ident in idents.iter() {
2112 result.push_str("::")
2114 result.push_str(token::get_ident(*ident).get());
2119 fn path_idents_to_str(&mut self, path: &Path) -> ~str {
2120 let identifiers: Vec<ast::Ident> = path.segments
2122 .map(|seg| seg.identifier)
2124 self.idents_to_str(identifiers.as_slice())
2127 fn import_directive_subclass_to_str(&mut self,
2128 subclass: ImportDirectiveSubclass)
2131 SingleImport(_, source) => {
2132 token::get_ident(source).get().to_str()
2138 fn import_path_to_str(&mut self,
2140 subclass: ImportDirectiveSubclass)
2142 if idents.is_empty() {
2143 self.import_directive_subclass_to_str(subclass)
2146 self.idents_to_str(idents),
2147 self.import_directive_subclass_to_str(subclass)))
2151 /// Attempts to resolve the given import. The return value indicates
2152 /// failure if we're certain the name does not exist, indeterminate if we
2153 /// don't know whether the name exists at the moment due to other
2154 /// currently-unresolved imports, or success if we know the name exists.
2155 /// If successful, the resolved bindings are written into the module.
2156 fn resolve_import_for_module(&mut self,
2158 import_directive: @ImportDirective)
2159 -> ResolveResult<()> {
2160 let mut resolution_result = Failed;
2161 let module_path = &import_directive.module_path;
2163 debug!("(resolving import for module) resolving import `{}::...` in \
2165 self.idents_to_str(module_path.as_slice()),
2166 self.module_to_str(module_));
2168 // First, resolve the module path for the directive, if necessary.
2169 let container = if module_path.len() == 0 {
2170 // Use the crate root.
2171 Some((self.graph_root.get_module(), LastMod(AllPublic)))
2173 match self.resolve_module_path(module_,
2174 module_path.as_slice(),
2175 DontUseLexicalScope,
2176 import_directive.span,
2181 resolution_result = Indeterminate;
2184 Success(container) => Some(container),
2190 Some((containing_module, lp)) => {
2191 // We found the module that the target is contained
2192 // within. Attempt to resolve the import within it.
2194 match *import_directive.subclass {
2195 SingleImport(target, source) => {
2197 self.resolve_single_import(module_,
2206 self.resolve_glob_import(module_,
2208 import_directive.id,
2209 import_directive.is_public,
2216 // Decrement the count of unresolved imports.
2217 match resolution_result {
2219 assert!(self.unresolved_imports >= 1);
2220 self.unresolved_imports -= 1;
2223 // Nothing to do here; just return the error.
2227 // Decrement the count of unresolved globs if necessary. But only if
2228 // the resolution result is indeterminate -- otherwise we'll stop
2229 // processing imports here. (See the loop in
2230 // resolve_imports_for_module.)
2232 if !resolution_result.indeterminate() {
2233 match *import_directive.subclass {
2235 assert!(module_.glob_count.get() >= 1);
2236 module_.glob_count.set(module_.glob_count.get() - 1);
2238 SingleImport(..) => {
2244 return resolution_result;
2247 fn create_name_bindings_from_module(module: @Module) -> NameBindings {
2249 type_def: RefCell::new(Some(TypeNsDef {
2251 module_def: Some(module),
2255 value_def: RefCell::new(None),
2259 fn resolve_single_import(&mut self,
2261 containing_module: @Module,
2264 directive: &ImportDirective,
2266 -> ResolveResult<()> {
2267 debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2268 `{}` id {}, last private {:?}",
2269 token::get_ident(target),
2270 self.module_to_str(containing_module),
2271 token::get_ident(source),
2272 self.module_to_str(module_),
2278 LastImport{..} => self.session.span_bug(directive.span,
2279 "Not expecting Import here, must be LastMod"),
2282 // We need to resolve both namespaces for this to succeed.
2285 let mut value_result = UnknownResult;
2286 let mut type_result = UnknownResult;
2288 // Search for direct children of the containing module.
2289 self.populate_module_if_necessary(containing_module);
2291 match containing_module.children.borrow().find(&source.name) {
2295 Some(child_name_bindings) => {
2296 if child_name_bindings.defined_in_namespace(ValueNS) {
2297 debug!("(resolving single import) found value binding");
2298 value_result = BoundResult(containing_module,
2299 *child_name_bindings);
2301 if child_name_bindings.defined_in_namespace(TypeNS) {
2302 debug!("(resolving single import) found type binding");
2303 type_result = BoundResult(containing_module,
2304 *child_name_bindings);
2309 // Unless we managed to find a result in both namespaces (unlikely),
2310 // search imports as well.
2311 let mut value_used_reexport = false;
2312 let mut type_used_reexport = false;
2313 match (value_result, type_result) {
2314 (BoundResult(..), BoundResult(..)) => {} // Continue.
2316 // If there is an unresolved glob at this point in the
2317 // containing module, bail out. We don't know enough to be
2318 // able to resolve this import.
2320 if containing_module.glob_count.get() > 0 {
2321 debug!("(resolving single import) unresolved glob; \
2323 return Indeterminate;
2326 // Now search the exported imports within the containing
2329 let import_resolutions = containing_module.import_resolutions
2331 match import_resolutions.find(&source.name) {
2333 debug!("(resolving single import) no import");
2334 // The containing module definitely doesn't have an
2335 // exported import with the name in question. We can
2336 // therefore accurately report that the names are
2339 if value_result.is_unknown() {
2340 value_result = UnboundResult;
2342 if type_result.is_unknown() {
2343 type_result = UnboundResult;
2346 Some(import_resolution)
2347 if import_resolution.outstanding_references.get()
2350 fn get_binding(this: &mut Resolver,
2351 import_resolution: @ImportResolution,
2352 namespace: Namespace)
2353 -> NamespaceResult {
2355 // Import resolutions must be declared with "pub"
2356 // in order to be exported.
2357 if !import_resolution.is_public.get() {
2358 return UnboundResult;
2361 match (*import_resolution).
2362 target_for_namespace(namespace) {
2364 return UnboundResult;
2367 debug!("(resolving single import) found \
2368 import in ns {:?}", namespace);
2369 let id = import_resolution.id(namespace);
2370 this.used_imports.insert((id, namespace));
2371 return BoundResult(target.target_module,
2377 // The name is an import which has been fully
2378 // resolved. We can, therefore, just follow it.
2379 if value_result.is_unknown() {
2380 value_result = get_binding(self, *import_resolution,
2382 value_used_reexport = import_resolution.is_public.get();
2384 if type_result.is_unknown() {
2385 type_result = get_binding(self, *import_resolution,
2387 type_used_reexport = import_resolution.is_public.get();
2392 // The import is unresolved. Bail out.
2393 debug!("(resolving single import) unresolved import; \
2395 return Indeterminate;
2401 // If we didn't find a result in the type namespace, search the
2402 // external modules.
2403 let mut value_used_public = false;
2404 let mut type_used_public = false;
2406 BoundResult(..) => {}
2408 match containing_module.external_module_children.borrow_mut()
2409 .find_copy(&source.name) {
2410 None => {} // Continue.
2412 debug!("(resolving single import) found external \
2415 @Resolver::create_name_bindings_from_module(
2417 type_result = BoundResult(containing_module,
2419 type_used_public = true;
2425 // We've successfully resolved the import. Write the results in.
2426 let import_resolution = {
2427 let import_resolutions = module_.import_resolutions.borrow();
2428 assert!(import_resolutions.contains_key(&target.name));
2429 import_resolutions.get_copy(&target.name)
2432 match value_result {
2433 BoundResult(target_module, name_bindings) => {
2434 debug!("(resolving single import) found value target");
2435 *import_resolution.value_target.borrow_mut() =
2436 Some(Target::new(target_module, name_bindings));
2437 import_resolution.value_id.set(directive.id);
2438 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2440 UnboundResult => { /* Continue. */ }
2442 fail!("value result should be known at this point");
2446 BoundResult(target_module, name_bindings) => {
2447 debug!("(resolving single import) found type target: {:?}",
2448 { name_bindings.type_def.borrow().clone().unwrap().type_def });
2449 *import_resolution.type_target.borrow_mut() =
2450 Some(Target::new(target_module, name_bindings));
2451 import_resolution.type_id.set(directive.id);
2452 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2454 UnboundResult => { /* Continue. */ }
2456 fail!("type result should be known at this point");
2460 if value_result.is_unbound() && type_result.is_unbound() {
2461 let msg = format!("unresolved import: there is no \
2463 token::get_ident(source),
2464 self.module_to_str(containing_module));
2465 self.resolve_error(directive.span, msg);
2468 let value_used_public = value_used_reexport || value_used_public;
2469 let type_used_public = type_used_reexport || type_used_public;
2471 assert!(import_resolution.outstanding_references.get() >= 1);
2472 import_resolution.outstanding_references.set(
2473 import_resolution.outstanding_references.get() - 1);
2475 // record what this import resolves to for later uses in documentation,
2476 // this may resolve to either a value or a type, but for documentation
2477 // purposes it's good enough to just favor one over the other.
2478 let value_private = match *import_resolution.value_target.borrow() {
2480 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2481 self.def_map.borrow_mut().insert(directive.id, def);
2482 let did = def_id_of_def(def);
2483 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2485 // AllPublic here and below is a dummy value, it should never be used because
2486 // _exists is false.
2489 let type_private = match *import_resolution.type_target.borrow() {
2491 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2492 self.def_map.borrow_mut().insert(directive.id, def);
2493 let did = def_id_of_def(def);
2494 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2499 self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2501 type_priv: type_private,
2504 debug!("(resolving single import) successfully resolved import");
2508 // Resolves a glob import. Note that this function cannot fail; it either
2509 // succeeds or bails out (as importing * from an empty module or a module
2510 // that exports nothing is valid).
2511 fn resolve_glob_import(&mut self,
2513 containing_module: @Module,
2517 -> ResolveResult<()> {
2518 // This function works in a highly imperative manner; it eagerly adds
2519 // everything it can to the list of import resolutions of the module
2521 debug!("(resolving glob import) resolving glob import {}", id);
2523 // We must bail out if the node has unresolved imports of any kind
2524 // (including globs).
2525 if !(*containing_module).all_imports_resolved() {
2526 debug!("(resolving glob import) target module has unresolved \
2527 imports; bailing out");
2528 return Indeterminate;
2531 assert_eq!(containing_module.glob_count.get(), 0);
2533 // Add all resolved imports from the containing module.
2534 let import_resolutions = containing_module.import_resolutions
2536 for (ident, target_import_resolution) in import_resolutions.iter() {
2537 debug!("(resolving glob import) writing module resolution \
2539 target_import_resolution.type_target.borrow().is_none(),
2540 self.module_to_str(module_));
2542 if !target_import_resolution.is_public.get() {
2543 debug!("(resolving glob import) nevermind, just kidding");
2547 // Here we merge two import resolutions.
2548 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2549 match import_resolutions.find(ident) {
2551 // Simple: just copy the old import resolution.
2552 let new_import_resolution =
2553 @ImportResolution::new(id, is_public);
2554 *new_import_resolution.value_target.borrow_mut() =
2555 get(&target_import_resolution.value_target);
2556 *new_import_resolution.type_target.borrow_mut() =
2557 get(&target_import_resolution.type_target);
2559 import_resolutions.insert
2560 (*ident, new_import_resolution);
2562 Some(&dest_import_resolution) => {
2563 // Merge the two import resolutions at a finer-grained
2566 match *target_import_resolution.value_target.borrow() {
2570 Some(value_target) => {
2571 *dest_import_resolution.value_target.borrow_mut() = Some(value_target);
2574 match *target_import_resolution.type_target.borrow() {
2578 Some(type_target) => {
2579 *dest_import_resolution.type_target.borrow_mut() = Some(type_target);
2582 dest_import_resolution.is_public.set(is_public);
2587 // Add all children from the containing module.
2588 self.populate_module_if_necessary(containing_module);
2590 for (&name, name_bindings) in containing_module.children
2592 self.merge_import_resolution(module_, containing_module,
2594 name, *name_bindings);
2597 // Add external module children from the containing module.
2598 for (&name, module) in containing_module.external_module_children
2601 @Resolver::create_name_bindings_from_module(*module);
2602 self.merge_import_resolution(module_, containing_module,
2604 name, name_bindings);
2607 // Record the destination of this import
2608 match containing_module.def_id.get() {
2610 self.def_map.borrow_mut().insert(id, DefMod(did));
2611 self.last_private.insert(id, lp);
2616 debug!("(resolving glob import) successfully resolved import");
2620 fn merge_import_resolution(&mut self,
2622 containing_module: @Module,
2626 name_bindings: @NameBindings) {
2627 let dest_import_resolution;
2628 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2629 match import_resolutions.find(&name) {
2631 // Create a new import resolution from this child.
2632 dest_import_resolution =
2633 @ImportResolution::new(id, is_public);
2634 import_resolutions.insert(name,
2635 dest_import_resolution);
2637 Some(&existing_import_resolution) => {
2638 dest_import_resolution = existing_import_resolution;
2642 debug!("(resolving glob import) writing resolution `{}` in `{}` \
2644 token::get_name(name).get().to_str(),
2645 self.module_to_str(containing_module),
2646 self.module_to_str(module_));
2648 // Merge the child item into the import resolution.
2649 if name_bindings.defined_in_public_namespace(ValueNS) {
2650 debug!("(resolving glob import) ... for value target");
2651 *dest_import_resolution.value_target.borrow_mut() =
2652 Some(Target::new(containing_module, name_bindings));
2653 dest_import_resolution.value_id.set(id);
2655 if name_bindings.defined_in_public_namespace(TypeNS) {
2656 debug!("(resolving glob import) ... for type target");
2657 *dest_import_resolution.type_target.borrow_mut() =
2658 Some(Target::new(containing_module, name_bindings));
2659 dest_import_resolution.type_id.set(id);
2661 dest_import_resolution.is_public.set(is_public);
2664 /// Resolves the given module path from the given root `module_`.
2665 fn resolve_module_path_from_root(&mut self,
2667 module_path: &[Ident],
2670 name_search_type: NameSearchType,
2672 -> ResolveResult<(@Module, LastPrivate)> {
2673 let mut search_module = module_;
2674 let mut index = index;
2675 let module_path_len = module_path.len();
2676 let mut closest_private = lp;
2678 // Resolve the module part of the path. This does not involve looking
2679 // upward though scope chains; we simply resolve names directly in
2680 // modules as we go.
2681 while index < module_path_len {
2682 let name = module_path[index];
2683 match self.resolve_name_in_module(search_module,
2689 let segment_name = token::get_ident(name);
2690 let module_name = self.module_to_str(search_module);
2691 if "???" == module_name {
2694 hi: span.lo + Pos::from_uint(segment_name.get().len()),
2695 expn_info: span.expn_info,
2697 self.resolve_error(span,
2698 format!("unresolved import. maybe \
2699 a missing `extern crate \
2704 self.resolve_error(span, format!("unresolved import: could not find `{}` in \
2705 `{}`.", segment_name, module_name));
2709 debug!("(resolving module path for import) module \
2710 resolution is indeterminate: {}",
2711 token::get_ident(name));
2712 return Indeterminate;
2714 Success((target, used_proxy)) => {
2715 // Check to see whether there are type bindings, and, if
2716 // so, whether there is a module within.
2717 match *target.bindings.type_def.borrow() {
2719 match type_def.module_def {
2722 self.resolve_error(span, format!("not a module `{}`",
2723 token::get_ident(name)));
2726 Some(module_def) => {
2727 // If we're doing the search for an
2728 // import, do not allow traits and impls
2730 match (name_search_type,
2731 module_def.kind.get()) {
2732 (ImportSearch, TraitModuleKind) |
2733 (ImportSearch, ImplModuleKind) => {
2736 "cannot import from a trait \
2737 or type implementation");
2741 search_module = module_def;
2743 // Keep track of the closest
2744 // private module used when
2745 // resolving this import chain.
2747 !search_module.is_public {
2748 match search_module.def_id
2752 LastMod(DependsOn(did));
2763 // There are no type bindings at all.
2764 self.resolve_error(span,
2765 format!("not a module `{}`",
2766 token::get_ident(name)));
2776 return Success((search_module, closest_private));
2779 /// Attempts to resolve the module part of an import directive or path
2780 /// rooted at the given module.
2782 /// On success, returns the resolved module, and the closest *private*
2783 /// module found to the destination when resolving this path.
2784 fn resolve_module_path(&mut self,
2786 module_path: &[Ident],
2787 use_lexical_scope: UseLexicalScopeFlag,
2789 name_search_type: NameSearchType)
2790 -> ResolveResult<(@Module, LastPrivate)> {
2791 let module_path_len = module_path.len();
2792 assert!(module_path_len > 0);
2794 debug!("(resolving module path for import) processing `{}` rooted at \
2796 self.idents_to_str(module_path),
2797 self.module_to_str(module_));
2799 // Resolve the module prefix, if any.
2800 let module_prefix_result = self.resolve_module_prefix(module_,
2806 match module_prefix_result {
2808 let mpath = self.idents_to_str(module_path);
2809 match mpath.rfind(':') {
2811 self.resolve_error(span, format!("unresolved import: could not find `{}` \
2813 // idx +- 1 to account for the colons
2815 mpath.slice_from(idx + 1),
2816 mpath.slice_to(idx - 1)));
2823 debug!("(resolving module path for import) indeterminate; \
2825 return Indeterminate;
2827 Success(NoPrefixFound) => {
2828 // There was no prefix, so we're considering the first element
2829 // of the path. How we handle this depends on whether we were
2830 // instructed to use lexical scope or not.
2831 match use_lexical_scope {
2832 DontUseLexicalScope => {
2833 // This is a crate-relative path. We will start the
2834 // resolution process at index zero.
2835 search_module = self.graph_root.get_module();
2837 last_private = LastMod(AllPublic);
2839 UseLexicalScope => {
2840 // This is not a crate-relative path. We resolve the
2841 // first component of the path in the current lexical
2842 // scope and then proceed to resolve below that.
2843 let result = self.resolve_module_in_lexical_scope(
2848 self.resolve_error(span, "unresolved name");
2852 debug!("(resolving module path for import) \
2853 indeterminate; bailing");
2854 return Indeterminate;
2856 Success(containing_module) => {
2857 search_module = containing_module;
2859 last_private = LastMod(AllPublic);
2865 Success(PrefixFound(containing_module, index)) => {
2866 search_module = containing_module;
2867 start_index = index;
2868 last_private = LastMod(DependsOn(containing_module.def_id
2874 self.resolve_module_path_from_root(search_module,
2882 /// Invariant: This must only be called during main resolution, not during
2883 /// import resolution.
2884 fn resolve_item_in_lexical_scope(&mut self,
2887 namespace: Namespace,
2888 search_through_modules:
2889 SearchThroughModulesFlag)
2890 -> ResolveResult<(Target, bool)> {
2891 debug!("(resolving item in lexical scope) resolving `{}` in \
2892 namespace {:?} in `{}`",
2893 token::get_ident(name),
2895 self.module_to_str(module_));
2897 // The current module node is handled specially. First, check for
2898 // its immediate children.
2899 self.populate_module_if_necessary(module_);
2901 match module_.children.borrow().find(&name.name) {
2903 if name_bindings.defined_in_namespace(namespace) => {
2904 debug!("top name bindings succeeded");
2905 return Success((Target::new(module_, *name_bindings),
2908 Some(_) | None => { /* Not found; continue. */ }
2911 // Now check for its import directives. We don't have to have resolved
2912 // all its imports in the usual way; this is because chains of
2913 // adjacent import statements are processed as though they mutated the
2915 match module_.import_resolutions.borrow().find(&name.name) {
2917 // Not found; continue.
2919 Some(import_resolution) => {
2920 match (*import_resolution).target_for_namespace(namespace) {
2922 // Not found; continue.
2923 debug!("(resolving item in lexical scope) found \
2924 import resolution, but not in namespace {:?}",
2928 debug!("(resolving item in lexical scope) using \
2929 import resolution");
2930 self.used_imports.insert((import_resolution.id(namespace), namespace));
2931 return Success((target, false));
2937 // Search for external modules.
2938 if namespace == TypeNS {
2939 match module_.external_module_children.borrow().find_copy(&name.name) {
2943 @Resolver::create_name_bindings_from_module(module);
2944 debug!("lower name bindings succeeded");
2945 return Success((Target::new(module_, name_bindings), false));
2950 // Finally, proceed up the scope chain looking for parent modules.
2951 let mut search_module = module_;
2953 // Go to the next parent.
2954 match search_module.parent_link {
2956 // No more parents. This module was unresolved.
2957 debug!("(resolving item in lexical scope) unresolved \
2961 ModuleParentLink(parent_module_node, _) => {
2962 match search_through_modules {
2963 DontSearchThroughModules => {
2964 match search_module.kind.get() {
2965 NormalModuleKind => {
2966 // We stop the search here.
2967 debug!("(resolving item in lexical \
2968 scope) unresolved module: not \
2969 searching through module \
2976 AnonymousModuleKind => {
2977 search_module = parent_module_node;
2981 SearchThroughModules => {
2982 search_module = parent_module_node;
2986 BlockParentLink(parent_module_node, _) => {
2987 search_module = parent_module_node;
2991 // Resolve the name in the parent module.
2992 match self.resolve_name_in_module(search_module,
2998 // Continue up the search chain.
3001 // We couldn't see through the higher scope because of an
3002 // unresolved import higher up. Bail.
3004 debug!("(resolving item in lexical scope) indeterminate \
3005 higher scope; bailing");
3006 return Indeterminate;
3008 Success((target, used_reexport)) => {
3009 // We found the module.
3010 debug!("(resolving item in lexical scope) found name \
3012 return Success((target, used_reexport));
3018 /// Resolves a module name in the current lexical scope.
3019 fn resolve_module_in_lexical_scope(&mut self,
3022 -> ResolveResult<@Module> {
3023 // If this module is an anonymous module, resolve the item in the
3024 // lexical scope. Otherwise, resolve the item from the crate root.
3025 let resolve_result = self.resolve_item_in_lexical_scope(
3026 module_, name, TypeNS, DontSearchThroughModules);
3027 match resolve_result {
3028 Success((target, _)) => {
3029 let bindings = &*target.bindings;
3030 match *bindings.type_def.borrow() {
3032 match type_def.module_def {
3034 error!("!!! (resolving module in lexical \
3035 scope) module wasn't actually a \
3039 Some(module_def) => {
3040 return Success(module_def);
3045 error!("!!! (resolving module in lexical scope) module
3046 wasn't actually a module!");
3052 debug!("(resolving module in lexical scope) indeterminate; \
3054 return Indeterminate;
3057 debug!("(resolving module in lexical scope) failed to \
3064 /// Returns the nearest normal module parent of the given module.
3065 fn get_nearest_normal_module_parent(&mut self, module_: @Module)
3066 -> Option<@Module> {
3067 let mut module_ = module_;
3069 match module_.parent_link {
3070 NoParentLink => return None,
3071 ModuleParentLink(new_module, _) |
3072 BlockParentLink(new_module, _) => {
3073 match new_module.kind.get() {
3074 NormalModuleKind => return Some(new_module),
3078 AnonymousModuleKind => module_ = new_module,
3085 /// Returns the nearest normal module parent of the given module, or the
3086 /// module itself if it is a normal module.
3087 fn get_nearest_normal_module_parent_or_self(&mut self, module_: @Module)
3089 match module_.kind.get() {
3090 NormalModuleKind => return module_,
3094 AnonymousModuleKind => {
3095 match self.get_nearest_normal_module_parent(module_) {
3097 Some(new_module) => new_module
3103 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3104 /// (b) some chain of `super::`.
3105 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3106 fn resolve_module_prefix(&mut self,
3108 module_path: &[Ident])
3109 -> ResolveResult<ModulePrefixResult> {
3110 // Start at the current module if we see `self` or `super`, or at the
3111 // top of the crate otherwise.
3112 let mut containing_module;
3114 let first_module_path_string = token::get_ident(module_path[0]);
3115 if "self" == first_module_path_string.get() {
3117 self.get_nearest_normal_module_parent_or_self(module_);
3119 } else if "super" == first_module_path_string.get() {
3121 self.get_nearest_normal_module_parent_or_self(module_);
3122 i = 0; // We'll handle `super` below.
3124 return Success(NoPrefixFound);
3127 // Now loop through all the `super`s we find.
3128 while i < module_path.len() {
3129 let string = token::get_ident(module_path[i]);
3130 if "super" != string.get() {
3133 debug!("(resolving module prefix) resolving `super` at {}",
3134 self.module_to_str(containing_module));
3135 match self.get_nearest_normal_module_parent(containing_module) {
3136 None => return Failed,
3137 Some(new_module) => {
3138 containing_module = new_module;
3144 debug!("(resolving module prefix) finished resolving prefix at {}",
3145 self.module_to_str(containing_module));
3147 return Success(PrefixFound(containing_module, i));
3150 /// Attempts to resolve the supplied name in the given module for the
3151 /// given namespace. If successful, returns the target corresponding to
3154 /// The boolean returned on success is an indicator of whether this lookup
3155 /// passed through a public re-export proxy.
3156 fn resolve_name_in_module(&mut self,
3159 namespace: Namespace,
3160 name_search_type: NameSearchType,
3161 allow_private_imports: bool)
3162 -> ResolveResult<(Target, bool)> {
3163 debug!("(resolving name in module) resolving `{}` in `{}`",
3164 token::get_ident(name),
3165 self.module_to_str(module_));
3167 // First, check the direct children of the module.
3168 self.populate_module_if_necessary(module_);
3170 match module_.children.borrow().find(&name.name) {
3172 if name_bindings.defined_in_namespace(namespace) => {
3173 debug!("(resolving name in module) found node as child");
3174 return Success((Target::new(module_, *name_bindings),
3182 // Next, check the module's imports if necessary.
3184 // If this is a search of all imports, we should be done with glob
3185 // resolution at this point.
3186 if name_search_type == PathSearch {
3187 assert_eq!(module_.glob_count.get(), 0);
3190 // Check the list of resolved imports.
3191 match module_.import_resolutions.borrow().find(&name.name) {
3192 Some(import_resolution) if allow_private_imports ||
3193 import_resolution.is_public.get() => {
3195 if import_resolution.is_public.get() &&
3196 import_resolution.outstanding_references.get() != 0 {
3197 debug!("(resolving name in module) import \
3198 unresolved; bailing out");
3199 return Indeterminate;
3201 match import_resolution.target_for_namespace(namespace) {
3203 debug!("(resolving name in module) name found, \
3204 but not in namespace {:?}",
3208 debug!("(resolving name in module) resolved to \
3210 self.used_imports.insert((import_resolution.id(namespace), namespace));
3211 return Success((target, true));
3215 Some(..) | None => {} // Continue.
3218 // Finally, search through external children.
3219 if namespace == TypeNS {
3220 match module_.external_module_children.borrow().find_copy(&name.name) {
3224 @Resolver::create_name_bindings_from_module(module);
3225 return Success((Target::new(module_, name_bindings), false));
3230 // We're out of luck.
3231 debug!("(resolving name in module) failed to resolve `{}`",
3232 token::get_ident(name));
3236 fn report_unresolved_imports(&mut self, module_: @Module) {
3237 let index = module_.resolved_import_count.get();
3238 let imports = module_.imports.borrow();
3239 let import_count = imports.len();
3240 if index != import_count {
3241 let sn = self.session
3243 .span_to_snippet(imports.get(index).span)
3245 if sn.contains("::") {
3246 self.resolve_error(imports.get(index).span,
3247 "unresolved import");
3249 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3250 sn.slice(0, sn.len()));
3251 self.resolve_error(imports.get(index).span, err);
3255 // Descend into children and anonymous children.
3256 self.populate_module_if_necessary(module_);
3258 for (_, &child_node) in module_.children.borrow().iter() {
3259 match child_node.get_module_if_available() {
3263 Some(child_module) => {
3264 self.report_unresolved_imports(child_module);
3269 for (_, &module_) in module_.anonymous_children.borrow().iter() {
3270 self.report_unresolved_imports(module_);
3276 // This pass simply determines what all "export" keywords refer to and
3277 // writes the results into the export map.
3279 // FIXME #4953 This pass will be removed once exports change to per-item.
3280 // Then this operation can simply be performed as part of item (or import)
3283 fn record_exports(&mut self) {
3284 let root_module = self.graph_root.get_module();
3285 self.record_exports_for_module_subtree(root_module);
3288 fn record_exports_for_module_subtree(&mut self,
3290 // If this isn't a local krate, then bail out. We don't need to record
3291 // exports for nonlocal crates.
3293 match module_.def_id.get() {
3294 Some(def_id) if def_id.krate == LOCAL_CRATE => {
3296 debug!("(recording exports for module subtree) recording \
3297 exports for local module `{}`",
3298 self.module_to_str(module_));
3301 // Record exports for the root module.
3302 debug!("(recording exports for module subtree) recording \
3303 exports for root module `{}`",
3304 self.module_to_str(module_));
3308 debug!("(recording exports for module subtree) not recording \
3310 self.module_to_str(module_));
3315 self.record_exports_for_module(module_);
3316 self.populate_module_if_necessary(module_);
3318 for (_, &child_name_bindings) in module_.children.borrow().iter() {
3319 match child_name_bindings.get_module_if_available() {
3323 Some(child_module) => {
3324 self.record_exports_for_module_subtree(child_module);
3329 for (_, &child_module) in module_.anonymous_children.borrow().iter() {
3330 self.record_exports_for_module_subtree(child_module);
3334 fn record_exports_for_module(&mut self, module_: @Module) {
3335 let mut exports2 = Vec::new();
3337 self.add_exports_for_module(&mut exports2, module_);
3338 match module_.def_id.get() {
3340 self.export_map2.borrow_mut().insert(def_id.node, exports2);
3341 debug!("(computing exports) writing exports for {} (some)",
3348 fn add_exports_of_namebindings(&mut self,
3349 exports2: &mut Vec<Export2> ,
3351 namebindings: @NameBindings,
3353 match namebindings.def_for_namespace(ns) {
3355 let name = token::get_name(name);
3356 debug!("(computing exports) YES: export '{}' => {:?}",
3357 name, def_id_of_def(d));
3358 exports2.push(Export2 {
3359 name: name.get().to_str(),
3360 def_id: def_id_of_def(d)
3364 debug!("(computing exports) NO: {:?}", d_opt);
3369 fn add_exports_for_module(&mut self,
3370 exports2: &mut Vec<Export2> ,
3372 for (name, importresolution) in module_.import_resolutions.borrow().iter() {
3373 if !importresolution.is_public.get() {
3376 let xs = [TypeNS, ValueNS];
3377 for &ns in xs.iter() {
3378 match importresolution.target_for_namespace(ns) {
3380 debug!("(computing exports) maybe export '{}'",
3381 token::get_name(*name));
3382 self.add_exports_of_namebindings(exports2,
3395 // We maintain a list of value ribs and type ribs.
3397 // Simultaneously, we keep track of the current position in the module
3398 // graph in the `current_module` pointer. When we go to resolve a name in
3399 // the value or type namespaces, we first look through all the ribs and
3400 // then query the module graph. When we resolve a name in the module
3401 // namespace, we can skip all the ribs (since nested modules are not
3402 // allowed within blocks in Rust) and jump straight to the current module
3405 // Named implementations are handled separately. When we find a method
3406 // call, we consult the module node to find all of the implementations in
3407 // scope. This information is lazily cached in the module node. We then
3408 // generate a fake "implementation scope" containing all the
3409 // implementations thus found, for compatibility with old resolve pass.
3411 fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
3412 let orig_module = self.current_module;
3414 // Move down in the graph.
3420 self.populate_module_if_necessary(orig_module);
3422 match orig_module.children.borrow().find(&name.name) {
3424 debug!("!!! (with scope) didn't find `{}` in `{}`",
3425 token::get_ident(name),
3426 self.module_to_str(orig_module));
3428 Some(name_bindings) => {
3429 match (*name_bindings).get_module_if_available() {
3431 debug!("!!! (with scope) didn't find module \
3433 token::get_ident(name),
3434 self.module_to_str(orig_module));
3437 self.current_module = module_;
3447 self.current_module = orig_module;
3450 /// Wraps the given definition in the appropriate number of `def_upvar`
3452 fn upvarify(&mut self,
3453 ribs: &mut Vec<@Rib> ,
3457 -> Option<DefLike> {
3462 DlDef(d @ DefLocal(..)) | DlDef(d @ DefUpvar(..)) |
3463 DlDef(d @ DefArg(..)) | DlDef(d @ DefBinding(..)) => {
3465 is_ty_param = false;
3467 DlDef(d @ DefTyParam(..)) => {
3472 return Some(def_like);
3476 let mut rib_index = rib_index + 1;
3477 while rib_index < ribs.len() {
3478 match ribs.get(rib_index).kind {
3480 // Nothing to do. Continue.
3482 FunctionRibKind(function_id, body_id) => {
3484 def = DefUpvar(def_id_of_def(def).node,
3490 MethodRibKind(item_id, _) => {
3491 // If the def is a ty param, and came from the parent
3494 DefTyParam(did, _) if {
3495 self.def_map.borrow().find(&did.node).map(|x| *x)
3496 == Some(DefTyParamBinder(item_id))
3502 // This was an attempt to access an upvar inside a
3503 // named function item. This is not allowed, so we
3508 "can't capture dynamic environment in a fn item; \
3509 use the || { ... } closure form instead");
3511 // This was an attempt to use a type parameter outside
3514 self.resolve_error(span,
3515 "attempt to use a type \
3516 argument out of scope");
3523 OpaqueFunctionRibKind => {
3525 // This was an attempt to access an upvar inside a
3526 // named function item. This is not allowed, so we
3531 "can't capture dynamic environment in a fn item; \
3532 use the || { ... } closure form instead");
3534 // This was an attempt to use a type parameter outside
3537 self.resolve_error(span,
3538 "attempt to use a type \
3539 argument out of scope");
3544 ConstantItemRibKind => {
3547 self.resolve_error(span,
3548 "cannot use an outer type \
3549 parameter in this context");
3551 // Still doesn't deal with upvars
3552 self.resolve_error(span,
3553 "attempt to use a non-constant \
3554 value in a constant");
3563 return Some(DlDef(def));
3566 fn search_ribs(&mut self,
3567 ribs: &mut Vec<@Rib> ,
3570 -> Option<DefLike> {
3571 // FIXME #4950: This should not use a while loop.
3572 // FIXME #4950: Try caching?
3574 let mut i = ribs.len();
3577 let binding_opt = ribs.get(i).bindings.borrow().find_copy(&name);
3580 return self.upvarify(ribs, i, def_like, span);
3591 fn resolve_crate(&mut self, krate: &ast::Crate) {
3592 debug!("(resolving crate) starting");
3594 visit::walk_crate(self, krate, ());
3597 fn resolve_item(&mut self, item: &Item) {
3598 debug!("(resolving item) resolving {}",
3599 token::get_ident(item.ident));
3603 // enum item: resolve all the variants' discrs,
3604 // then resolve the ty params
3605 ItemEnum(ref enum_def, ref generics) => {
3606 for variant in (*enum_def).variants.iter() {
3607 for dis_expr in variant.node.disr_expr.iter() {
3608 // resolve the discriminator expr
3610 self.with_constant_rib(|this| {
3611 this.resolve_expr(*dis_expr);
3616 // n.b. the discr expr gets visted twice.
3617 // but maybe it's okay since the first time will signal an
3618 // error if there is one? -- tjc
3619 self.with_type_parameter_rib(HasTypeParameters(generics,
3624 visit::walk_item(this, item, ());
3628 ItemTy(_, ref generics) => {
3629 self.with_type_parameter_rib(HasTypeParameters(generics,
3634 visit::walk_item(this, item, ());
3638 ItemImpl(ref generics,
3639 ref implemented_traits,
3642 self.resolve_implementation(item.id,
3646 methods.as_slice());
3649 ItemTrait(ref generics, ref traits, ref methods) => {
3650 // Create a new rib for the self type.
3651 let self_type_rib = @Rib::new(NormalRibKind);
3652 self.type_ribs.borrow_mut().push(self_type_rib);
3653 // plain insert (no renaming)
3654 let name = self.type_self_ident.name;
3655 self_type_rib.bindings.borrow_mut()
3656 .insert(name, DlDef(DefSelfTy(item.id)));
3658 // Create a new rib for the trait-wide type parameters.
3659 self.with_type_parameter_rib(HasTypeParameters(generics,
3664 this.resolve_type_parameters(&generics.ty_params);
3666 // Resolve derived traits.
3667 for trt in traits.iter() {
3668 this.resolve_trait_reference(item.id, trt, TraitDerivation);
3671 for method in (*methods).iter() {
3672 // Create a new rib for the method-specific type
3675 // FIXME #4951: Do we need a node ID here?
3678 ast::Required(ref ty_m) => {
3679 this.with_type_parameter_rib
3680 (HasTypeParameters(&ty_m.generics,
3682 generics.ty_params.len(),
3683 MethodRibKind(item.id, Required)),
3686 // Resolve the method-specific type
3688 this.resolve_type_parameters(
3689 &ty_m.generics.ty_params);
3691 for argument in ty_m.decl.inputs.iter() {
3692 this.resolve_type(argument.ty);
3695 this.resolve_type(ty_m.decl.output);
3698 ast::Provided(m) => {
3699 this.resolve_method(MethodRibKind(item.id,
3702 generics.ty_params.len())
3708 self.type_ribs.borrow_mut().pop();
3711 ItemStruct(ref struct_def, ref generics) => {
3712 self.resolve_struct(item.id,
3714 struct_def.fields.as_slice());
3717 ItemMod(ref module_) => {
3718 self.with_scope(Some(item.ident), |this| {
3719 this.resolve_module(module_, item.span, item.ident,
3724 ItemForeignMod(ref foreign_module) => {
3725 self.with_scope(Some(item.ident), |this| {
3726 for foreign_item in foreign_module.items.iter() {
3727 match foreign_item.node {
3728 ForeignItemFn(_, ref generics) => {
3729 this.with_type_parameter_rib(
3731 generics, foreign_item.id, 0,
3733 |this| visit::walk_foreign_item(this,
3737 ForeignItemStatic(..) => {
3738 visit::walk_foreign_item(this,
3747 ItemFn(fn_decl, _, _, ref generics, block) => {
3748 self.resolve_function(OpaqueFunctionRibKind,
3754 OpaqueFunctionRibKind),
3759 self.with_constant_rib(|this| {
3760 visit::walk_item(this, item, ());
3765 // do nothing, these are just around to be encoded
3770 fn with_type_parameter_rib(&mut self,
3771 type_parameters: TypeParameters,
3772 f: |&mut Resolver|) {
3773 match type_parameters {
3774 HasTypeParameters(generics, node_id, initial_index,
3777 let function_type_rib = @Rib::new(rib_kind);
3778 self.type_ribs.borrow_mut().push(function_type_rib);
3780 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
3781 let ident = type_parameter.ident;
3782 debug!("with_type_parameter_rib: {} {}", node_id,
3784 let def_like = DlDef(DefTyParam
3785 (local_def(type_parameter.id),
3786 index + initial_index));
3787 // Associate this type parameter with
3788 // the item that bound it
3789 self.record_def(type_parameter.id,
3790 (DefTyParamBinder(node_id), LastMod(AllPublic)));
3791 // plain insert (no renaming)
3792 function_type_rib.bindings.borrow_mut()
3793 .insert(ident.name, def_like);
3797 NoTypeParameters => {
3804 match type_parameters {
3805 HasTypeParameters(..) => { self.type_ribs.borrow_mut().pop(); }
3806 NoTypeParameters => { }
3810 fn with_label_rib(&mut self, f: |&mut Resolver|) {
3811 self.label_ribs.borrow_mut().push(@Rib::new(NormalRibKind));
3813 self.label_ribs.borrow_mut().pop();
3816 fn with_constant_rib(&mut self, f: |&mut Resolver|) {
3817 self.value_ribs.borrow_mut().push(@Rib::new(ConstantItemRibKind));
3818 self.type_ribs.borrow_mut().push(@Rib::new(ConstantItemRibKind));
3820 self.type_ribs.borrow_mut().pop();
3821 self.value_ribs.borrow_mut().pop();
3824 fn resolve_function(&mut self,
3826 optional_declaration: Option<P<FnDecl>>,
3827 type_parameters: TypeParameters,
3829 // Create a value rib for the function.
3830 let function_value_rib = @Rib::new(rib_kind);
3831 self.value_ribs.borrow_mut().push(function_value_rib);
3833 // Create a label rib for the function.
3834 let function_label_rib = @Rib::new(rib_kind);
3835 self.label_ribs.borrow_mut().push(function_label_rib);
3837 // If this function has type parameters, add them now.
3838 self.with_type_parameter_rib(type_parameters, |this| {
3839 // Resolve the type parameters.
3840 match type_parameters {
3841 NoTypeParameters => {
3844 HasTypeParameters(ref generics, _, _, _) => {
3845 this.resolve_type_parameters(&generics.ty_params);
3849 // Add each argument to the rib.
3850 match optional_declaration {
3854 Some(declaration) => {
3855 for argument in declaration.inputs.iter() {
3856 let binding_mode = ArgumentIrrefutableMode;
3857 this.resolve_pattern(argument.pat,
3861 this.resolve_type(argument.ty);
3863 debug!("(resolving function) recorded argument");
3866 this.resolve_type(declaration.output);
3870 // Resolve the function body.
3871 this.resolve_block(block);
3873 debug!("(resolving function) leaving function");
3876 self.label_ribs.borrow_mut().pop();
3877 self.value_ribs.borrow_mut().pop();
3880 fn resolve_type_parameters(&mut self,
3881 type_parameters: &OwnedSlice<TyParam>) {
3882 for type_parameter in type_parameters.iter() {
3883 for bound in type_parameter.bounds.iter() {
3884 self.resolve_type_parameter_bound(type_parameter.id, bound);
3886 match type_parameter.default {
3887 Some(ty) => self.resolve_type(ty),
3893 fn resolve_type_parameter_bound(&mut self,
3895 type_parameter_bound: &TyParamBound) {
3896 match *type_parameter_bound {
3897 TraitTyParamBound(ref tref) => {
3898 self.resolve_trait_reference(id, tref, TraitBoundingTypeParameter)
3900 RegionTyParamBound => {}
3904 fn resolve_trait_reference(&mut self,
3906 trait_reference: &TraitRef,
3907 reference_type: TraitReferenceType) {
3908 match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
3910 let path_str = self.path_idents_to_str(&trait_reference.path);
3911 let usage_str = match reference_type {
3912 TraitBoundingTypeParameter => "bound type parameter with",
3913 TraitImplementation => "implement",
3914 TraitDerivation => "derive"
3917 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
3918 self.resolve_error(trait_reference.path.span, msg);
3921 debug!("(resolving trait) found trait def: {:?}", def);
3922 self.record_def(trait_reference.ref_id, def);
3927 fn resolve_struct(&mut self,
3929 generics: &Generics,
3930 fields: &[StructField]) {
3931 let mut ident_map: HashMap<ast::Ident, &StructField> = HashMap::new();
3932 for field in fields.iter() {
3933 match field.node.kind {
3934 NamedField(ident, _) => {
3935 match ident_map.find(&ident) {
3936 Some(&prev_field) => {
3937 let ident_str = token::get_ident(ident);
3938 self.resolve_error(field.span,
3939 format!("field `{}` is already declared", ident_str));
3940 self.session.span_note(prev_field.span,
3941 "previously declared here");
3944 ident_map.insert(ident, field);
3952 // If applicable, create a rib for the type parameters.
3953 self.with_type_parameter_rib(HasTypeParameters(generics,
3956 OpaqueFunctionRibKind),
3958 // Resolve the type parameters.
3959 this.resolve_type_parameters(&generics.ty_params);
3962 for field in fields.iter() {
3963 this.resolve_type(field.node.ty);
3968 // Does this really need to take a RibKind or is it always going
3969 // to be NormalRibKind?
3970 fn resolve_method(&mut self,
3973 outer_type_parameter_count: uint) {
3974 let method_generics = &method.generics;
3975 let type_parameters =
3976 HasTypeParameters(method_generics,
3978 outer_type_parameter_count,
3981 self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
3984 fn resolve_implementation(&mut self,
3986 generics: &Generics,
3987 opt_trait_reference: &Option<TraitRef>,
3989 methods: &[@Method]) {
3990 // If applicable, create a rib for the type parameters.
3991 let outer_type_parameter_count = generics.ty_params.len();
3992 self.with_type_parameter_rib(HasTypeParameters(generics,
3997 // Resolve the type parameters.
3998 this.resolve_type_parameters(&generics.ty_params);
4000 // Resolve the trait reference, if necessary.
4001 let original_trait_refs;
4002 match opt_trait_reference {
4003 &Some(ref trait_reference) => {
4004 this.resolve_trait_reference(id, trait_reference,
4005 TraitImplementation);
4007 // Record the current set of trait references.
4008 let mut new_trait_refs = Vec::new();
4009 for &def in this.def_map.borrow()
4010 .find(&trait_reference.ref_id).iter() {
4011 new_trait_refs.push(def_id_of_def(*def));
4013 original_trait_refs = Some(replace(
4014 &mut this.current_trait_refs,
4015 Some(new_trait_refs)));
4018 original_trait_refs = None;
4022 // Resolve the self type.
4023 this.resolve_type(self_type);
4025 for method in methods.iter() {
4026 // We also need a new scope for the method-specific
4028 this.resolve_method(MethodRibKind(
4030 Provided(method.id)),
4032 outer_type_parameter_count);
4034 let borrowed_type_parameters = &method.tps;
4035 self.resolve_function(MethodRibKind(
4037 Provided(method.id)),
4040 (borrowed_type_parameters,
4042 outer_type_parameter_count,
4048 // Restore the original trait references.
4049 match original_trait_refs {
4050 Some(r) => { this.current_trait_refs = r; }
4056 fn resolve_module(&mut self, module: &Mod, _span: Span,
4057 _name: Ident, id: NodeId) {
4058 // Write the implementations in scope into the module metadata.
4059 debug!("(resolving module) resolving module ID {}", id);
4060 visit::walk_mod(self, module, ());
4063 fn resolve_local(&mut self, local: &Local) {
4064 // Resolve the type.
4065 self.resolve_type(local.ty);
4067 // Resolve the initializer, if necessary.
4072 Some(initializer) => {
4073 self.resolve_expr(initializer);
4077 // Resolve the pattern.
4078 self.resolve_pattern(local.pat, LocalIrrefutableMode, None);
4081 // build a map from pattern identifiers to binding-info's.
4082 // this is done hygienically. This could arise for a macro
4083 // that expands into an or-pattern where one 'x' was from the
4084 // user and one 'x' came from the macro.
4085 fn binding_mode_map(&mut self, pat: @Pat) -> BindingMap {
4086 let mut result = HashMap::new();
4087 pat_bindings(self.def_map, pat, |binding_mode, _id, sp, path| {
4088 let name = mtwt::resolve(path_to_ident(path));
4090 binding_info {span: sp,
4091 binding_mode: binding_mode});
4096 // check that all of the arms in an or-pattern have exactly the
4097 // same set of bindings, with the same binding modes for each.
4098 fn check_consistent_bindings(&mut self, arm: &Arm) {
4099 if arm.pats.len() == 0 {
4102 let map_0 = self.binding_mode_map(*arm.pats.get(0));
4103 for (i, p) in arm.pats.iter().enumerate() {
4104 let map_i = self.binding_mode_map(*p);
4106 for (&key, &binding_0) in map_0.iter() {
4107 match map_i.find(&key) {
4111 format!("variable `{}` from pattern \\#1 is \
4112 not bound in pattern \\#{}",
4113 token::get_name(key),
4116 Some(binding_i) => {
4117 if binding_0.binding_mode != binding_i.binding_mode {
4120 format!("variable `{}` is bound with different \
4121 mode in pattern \\#{} than in pattern \\#1",
4122 token::get_name(key),
4129 for (&key, &binding) in map_i.iter() {
4130 if !map_0.contains_key(&key) {
4133 format!("variable `{}` from pattern \\#{} is \
4134 not bound in pattern \\#1",
4135 token::get_name(key),
4142 fn resolve_arm(&mut self, arm: &Arm) {
4143 self.value_ribs.borrow_mut().push(@Rib::new(NormalRibKind));
4145 let mut bindings_list = HashMap::new();
4146 for pattern in arm.pats.iter() {
4147 self.resolve_pattern(*pattern,
4149 Some(&mut bindings_list));
4152 // This has to happen *after* we determine which
4153 // pat_idents are variants
4154 self.check_consistent_bindings(arm);
4156 visit::walk_expr_opt(self, arm.guard, ());
4157 self.resolve_expr(arm.body);
4159 self.value_ribs.borrow_mut().pop();
4162 fn resolve_block(&mut self, block: &Block) {
4163 debug!("(resolving block) entering block");
4164 self.value_ribs.borrow_mut().push(@Rib::new(NormalRibKind));
4166 // Move down in the graph, if there's an anonymous module rooted here.
4167 let orig_module = self.current_module;
4168 let anonymous_children = self.current_module
4171 match anonymous_children.find(&block.id) {
4172 None => { /* Nothing to do. */ }
4173 Some(&anonymous_module) => {
4174 debug!("(resolving block) found anonymous module, moving \
4176 self.current_module = anonymous_module;
4180 // Descend into the block.
4181 visit::walk_block(self, block, ());
4184 self.current_module = orig_module;
4186 self.value_ribs.borrow_mut().pop();
4187 debug!("(resolving block) leaving block");
4190 fn resolve_type(&mut self, ty: &Ty) {
4192 // Like path expressions, the interpretation of path types depends
4193 // on whether the path has multiple elements in it or not.
4195 TyPath(ref path, ref bounds, path_id) => {
4196 // This is a path in the type namespace. Walk through scopes
4198 let mut result_def = None;
4200 // First, check to see whether the name is a primitive type.
4201 if path.segments.len() == 1 {
4202 let id = path.segments.last().unwrap().identifier;
4204 match self.primitive_type_table
4208 Some(&primitive_type) => {
4210 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4214 .any(|s| !s.lifetimes.is_empty()) {
4215 self.session.span_err(path.span,
4216 "lifetime parameters \
4217 are not allowed on \
4219 } else if path.segments
4221 .any(|s| s.types.len() > 0) {
4222 self.session.span_err(path.span,
4223 "type parameters are \
4224 not allowed on this \
4236 match self.resolve_path(ty.id, path, TypeNS, true) {
4238 debug!("(resolving type) resolved `{}` to \
4240 token::get_ident(path.segments
4244 result_def = Some(def);
4251 Some(_) => {} // Continue.
4256 // Write the result into the def map.
4257 debug!("(resolving type) writing resolution for `{}` \
4259 self.path_idents_to_str(path),
4261 self.record_def(path_id, def);
4264 let msg = format!("use of undeclared type name `{}`",
4265 self.path_idents_to_str(path));
4266 self.resolve_error(ty.span, msg);
4270 bounds.as_ref().map(|bound_vec| {
4271 for bound in bound_vec.iter() {
4272 self.resolve_type_parameter_bound(ty.id, bound);
4278 c.bounds.as_ref().map(|bounds| {
4279 for bound in bounds.iter() {
4280 self.resolve_type_parameter_bound(ty.id, bound);
4283 visit::walk_ty(self, ty, ());
4287 // Just resolve embedded types.
4288 visit::walk_ty(self, ty, ());
4293 fn resolve_pattern(&mut self,
4295 mode: PatternBindingMode,
4296 // Maps idents to the node ID for the (outermost)
4297 // pattern that binds them
4298 mut bindings_list: Option<&mut HashMap<Name,NodeId>>) {
4299 let pat_id = pattern.id;
4300 walk_pat(pattern, |pattern| {
4301 match pattern.node {
4302 PatIdent(binding_mode, ref path, _)
4303 if !path.global && path.segments.len() == 1 => {
4305 // The meaning of pat_ident with no type parameters
4306 // depends on whether an enum variant or unit-like struct
4307 // with that name is in scope. The probing lookup has to
4308 // be careful not to emit spurious errors. Only matching
4309 // patterns (match) can match nullary variants or
4310 // unit-like structs. For binding patterns (let), matching
4311 // such a value is simply disallowed (since it's rarely
4314 let ident = path.segments.get(0).identifier;
4315 let renamed = mtwt::resolve(ident);
4317 match self.resolve_bare_identifier_pattern(ident) {
4318 FoundStructOrEnumVariant(def, lp)
4319 if mode == RefutableMode => {
4320 debug!("(resolving pattern) resolving `{}` to \
4321 struct or enum variant",
4322 token::get_name(renamed));
4324 self.enforce_default_binding_mode(
4328 self.record_def(pattern.id, (def, lp));
4330 FoundStructOrEnumVariant(..) => {
4331 self.resolve_error(pattern.span,
4332 format!("declaration of `{}` \
4334 variant or unit-like \
4336 token::get_name(renamed)));
4338 FoundConst(def, lp) if mode == RefutableMode => {
4339 debug!("(resolving pattern) resolving `{}` to \
4341 token::get_name(renamed));
4343 self.enforce_default_binding_mode(
4347 self.record_def(pattern.id, (def, lp));
4350 self.resolve_error(pattern.span,
4351 "only irrefutable patterns \
4354 BareIdentifierPatternUnresolved => {
4355 debug!("(resolving pattern) binding `{}`",
4356 token::get_name(renamed));
4358 let def = match mode {
4360 // For pattern arms, we must use
4361 // `def_binding` definitions.
4363 DefBinding(pattern.id, binding_mode)
4365 LocalIrrefutableMode => {
4366 // But for locals, we use `def_local`.
4367 DefLocal(pattern.id, binding_mode)
4369 ArgumentIrrefutableMode => {
4370 // And for function arguments, `def_arg`.
4371 DefArg(pattern.id, binding_mode)
4375 // Record the definition so that later passes
4376 // will be able to distinguish variants from
4377 // locals in patterns.
4379 self.record_def(pattern.id, (def, LastMod(AllPublic)));
4381 // Add the binding to the local ribs, if it
4382 // doesn't already exist in the bindings list. (We
4383 // must not add it if it's in the bindings list
4384 // because that breaks the assumptions later
4385 // passes make about or-patterns.)
4387 match bindings_list {
4388 Some(ref mut bindings_list)
4389 if !bindings_list.contains_key(&renamed) => {
4390 let this = &mut *self;
4391 let value_ribs = this.value_ribs.borrow();
4392 let length = value_ribs.len();
4393 let last_rib = value_ribs.get(
4395 last_rib.bindings.borrow_mut()
4396 .insert(renamed, DlDef(def));
4397 bindings_list.insert(renamed, pat_id);
4399 Some(ref mut b) => {
4400 if b.find(&renamed) == Some(&pat_id) {
4401 // Then this is a duplicate variable
4402 // in the same disjunct, which is an
4404 self.resolve_error(pattern.span,
4405 format!("identifier `{}` is bound more \
4406 than once in the same pattern",
4407 path_to_str(path)));
4409 // Not bound in the same pattern: do nothing
4412 let this = &mut *self;
4414 let value_ribs = this.value_ribs.borrow();
4415 let length = value_ribs.len();
4416 let last_rib = value_ribs.get(
4418 last_rib.bindings.borrow_mut()
4419 .insert(renamed, DlDef(def));
4426 // Check the types in the path pattern.
4427 for &ty in path.segments
4429 .flat_map(|seg| seg.types.iter()) {
4430 self.resolve_type(ty);
4434 PatIdent(binding_mode, ref path, _) => {
4435 // This must be an enum variant, struct, or constant.
4436 match self.resolve_path(pat_id, path, ValueNS, false) {
4437 Some(def @ (DefVariant(..), _)) |
4438 Some(def @ (DefStruct(..), _)) => {
4439 self.record_def(pattern.id, def);
4441 Some(def @ (DefStatic(..), _)) => {
4442 self.enforce_default_binding_mode(
4446 self.record_def(pattern.id, def);
4451 format!("`{}` is not an enum variant or constant",
4453 path.segments.last().unwrap().identifier)))
4456 self.resolve_error(path.span,
4457 "unresolved enum variant");
4461 // Check the types in the path pattern.
4462 for &ty in path.segments
4464 .flat_map(|s| s.types.iter()) {
4465 self.resolve_type(ty);
4469 PatEnum(ref path, _) => {
4470 // This must be an enum variant, struct or const.
4471 match self.resolve_path(pat_id, path, ValueNS, false) {
4472 Some(def @ (DefFn(..), _)) |
4473 Some(def @ (DefVariant(..), _)) |
4474 Some(def @ (DefStruct(..), _)) |
4475 Some(def @ (DefStatic(..), _)) => {
4476 self.record_def(pattern.id, def);
4479 self.resolve_error(path.span,
4480 format!("`{}` is not an enum variant, struct or const",
4481 token::get_ident(path.segments
4486 self.resolve_error(path.span,
4487 format!("unresolved enum variant, struct or const `{}`",
4488 token::get_ident(path.segments
4494 // Check the types in the path pattern.
4495 for &ty in path.segments
4497 .flat_map(|s| s.types.iter()) {
4498 self.resolve_type(ty);
4503 self.resolve_expr(expr);
4506 PatRange(first_expr, last_expr) => {
4507 self.resolve_expr(first_expr);
4508 self.resolve_expr(last_expr);
4511 PatStruct(ref path, _, _) => {
4512 match self.resolve_path(pat_id, path, TypeNS, false) {
4513 Some((DefTy(class_id), lp))
4514 if self.structs.contains(&class_id) => {
4515 let class_def = DefStruct(class_id);
4516 self.record_def(pattern.id, (class_def, lp));
4518 Some(definition @ (DefStruct(class_id), _)) => {
4519 assert!(self.structs.contains(&class_id));
4520 self.record_def(pattern.id, definition);
4522 Some(definition @ (DefVariant(_, variant_id, _), _))
4523 if self.structs.contains(&variant_id) => {
4524 self.record_def(pattern.id, definition);
4527 debug!("(resolving pattern) didn't find struct \
4528 def: {:?}", result);
4529 let msg = format!("`{}` does not name a structure",
4530 self.path_idents_to_str(path));
4531 self.resolve_error(path.span, msg);
4544 fn resolve_bare_identifier_pattern(&mut self, name: Ident)
4546 BareIdentifierPatternResolution {
4547 match self.resolve_item_in_lexical_scope(self.current_module,
4550 SearchThroughModules) {
4551 Success((target, _)) => {
4552 debug!("(resolve bare identifier pattern) succeeded in \
4553 finding {} at {:?}",
4554 token::get_ident(name),
4555 target.bindings.value_def.borrow());
4556 match *target.bindings.value_def.borrow() {
4558 fail!("resolved name in the value namespace to a \
4559 set of name bindings with no def?!");
4562 // For the two success cases, this lookup can be
4563 // considered as not having a private component because
4564 // the lookup happened only within the current module.
4566 def @ DefVariant(..) | def @ DefStruct(..) => {
4567 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
4569 def @ DefStatic(_, false) => {
4570 return FoundConst(def, LastMod(AllPublic));
4573 return BareIdentifierPatternUnresolved;
4581 fail!("unexpected indeterminate result");
4585 debug!("(resolve bare identifier pattern) failed to find {}",
4586 token::get_ident(name));
4587 return BareIdentifierPatternUnresolved;
4592 /// If `check_ribs` is true, checks the local definitions first; i.e.
4593 /// doesn't skip straight to the containing module.
4594 fn resolve_path(&mut self,
4597 namespace: Namespace,
4598 check_ribs: bool) -> Option<(Def, LastPrivate)> {
4599 // First, resolve the types.
4600 for &ty in path.segments.iter().flat_map(|s| s.types.iter()) {
4601 self.resolve_type(ty);
4605 return self.resolve_crate_relative_path(path, namespace);
4608 let unqualified_def =
4609 self.resolve_identifier(path.segments
4616 if path.segments.len() > 1 {
4617 let def = self.resolve_module_relative_path(path, namespace);
4618 match (def, unqualified_def) {
4619 (Some((d, _)), Some((ud, _))) if d == ud => {
4620 self.session.add_lint(UnnecessaryQualification,
4623 ~"unnecessary qualification");
4631 return unqualified_def;
4634 // resolve a single identifier (used as a varref)
4635 fn resolve_identifier(&mut self,
4637 namespace: Namespace,
4640 -> Option<(Def, LastPrivate)> {
4642 match self.resolve_identifier_in_local_ribs(identifier,
4646 return Some((def, LastMod(AllPublic)));
4654 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
4658 // FIXME #4952: Merge me with resolve_name_in_module?
4659 fn resolve_definition_of_name_in_module(&mut self,
4660 containing_module: @Module,
4662 namespace: Namespace)
4664 // First, search children.
4665 self.populate_module_if_necessary(containing_module);
4667 match containing_module.children.borrow().find(&name.name) {
4668 Some(child_name_bindings) => {
4669 match child_name_bindings.def_for_namespace(namespace) {
4671 // Found it. Stop the search here.
4672 let p = child_name_bindings.defined_in_public_namespace(
4674 let lp = if p {LastMod(AllPublic)} else {
4675 LastMod(DependsOn(def_id_of_def(def)))
4677 return ChildNameDefinition(def, lp);
4685 // Next, search import resolutions.
4686 match containing_module.import_resolutions.borrow().find(&name.name) {
4687 Some(import_resolution) if import_resolution.is_public.get() => {
4688 match (*import_resolution).target_for_namespace(namespace) {
4690 match target.bindings.def_for_namespace(namespace) {
4693 let id = import_resolution.id(namespace);
4694 self.used_imports.insert((id, namespace));
4695 return ImportNameDefinition(def, LastMod(AllPublic));
4698 // This can happen with external impls, due to
4699 // the imperfect way we read the metadata.
4706 Some(..) | None => {} // Continue.
4709 // Finally, search through external children.
4710 if namespace == TypeNS {
4711 match containing_module.external_module_children.borrow()
4712 .find_copy(&name.name) {
4715 match module.def_id.get() {
4716 None => {} // Continue.
4718 let lp = if module.is_public {LastMod(AllPublic)} else {
4719 LastMod(DependsOn(def_id))
4721 return ChildNameDefinition(DefMod(def_id), lp);
4728 return NoNameDefinition;
4731 // resolve a "module-relative" path, e.g. a::b::c
4732 fn resolve_module_relative_path(&mut self,
4734 namespace: Namespace)
4735 -> Option<(Def, LastPrivate)> {
4736 let module_path_idents = path.segments.init().iter()
4737 .map(|ps| ps.identifier)
4738 .collect::<Vec<_>>();
4740 let containing_module;
4742 match self.resolve_module_path(self.current_module,
4743 module_path_idents.as_slice(),
4748 let msg = format!("use of undeclared module `{}`",
4749 self.idents_to_str(module_path_idents.as_slice()));
4750 self.resolve_error(path.span, msg);
4755 fail!("indeterminate unexpected");
4758 Success((resulting_module, resulting_last_private)) => {
4759 containing_module = resulting_module;
4760 last_private = resulting_last_private;
4764 let ident = path.segments.last().unwrap().identifier;
4765 let def = match self.resolve_definition_of_name_in_module(containing_module,
4768 NoNameDefinition => {
4769 // We failed to resolve the name. Report an error.
4772 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4773 (def, last_private.or(lp))
4776 match containing_module.kind.get() {
4777 TraitModuleKind | ImplModuleKind => {
4778 match self.method_map.borrow().find(&ident.name) {
4780 match containing_module.def_id.get() {
4781 Some(def_id) if s.contains(&def_id) => {
4782 debug!("containing module was a trait or impl \
4783 and name was a method -> not resolved");
4797 /// Invariant: This must be called only during main resolution, not during
4798 /// import resolution.
4799 fn resolve_crate_relative_path(&mut self,
4801 namespace: Namespace)
4802 -> Option<(Def, LastPrivate)> {
4803 let module_path_idents = path.segments.init().iter()
4804 .map(|ps| ps.identifier)
4805 .collect::<Vec<_>>();
4807 let root_module = self.graph_root.get_module();
4809 let containing_module;
4811 match self.resolve_module_path_from_root(root_module,
4812 module_path_idents.as_slice(),
4816 LastMod(AllPublic)) {
4818 let msg = format!("use of undeclared module `::{}`",
4819 self.idents_to_str(module_path_idents.as_slice()));
4820 self.resolve_error(path.span, msg);
4825 fail!("indeterminate unexpected");
4828 Success((resulting_module, resulting_last_private)) => {
4829 containing_module = resulting_module;
4830 last_private = resulting_last_private;
4834 let name = path.segments.last().unwrap().identifier;
4835 match self.resolve_definition_of_name_in_module(containing_module,
4838 NoNameDefinition => {
4839 // We failed to resolve the name. Report an error.
4842 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4843 return Some((def, last_private.or(lp)));
4848 fn resolve_identifier_in_local_ribs(&mut self,
4850 namespace: Namespace,
4853 // Check the local set of ribs.
4854 let search_result = match namespace {
4856 let renamed = mtwt::resolve(ident);
4857 self.search_ribs(&mut *self.value_ribs.borrow_mut(),
4861 let name = ident.name;
4862 self.search_ribs(&mut *self.type_ribs.borrow_mut(), name, span)
4866 match search_result {
4867 Some(DlDef(def)) => {
4868 debug!("(resolving path in local ribs) resolved `{}` to \
4870 token::get_ident(ident),
4874 Some(DlField) | Some(DlImpl(_)) | None => {
4880 fn resolve_item_by_identifier_in_lexical_scope(&mut self,
4882 namespace: Namespace)
4883 -> Option<(Def, LastPrivate)> {
4885 match self.resolve_item_in_lexical_scope(self.current_module,
4888 DontSearchThroughModules) {
4889 Success((target, _)) => {
4890 match (*target.bindings).def_for_namespace(namespace) {
4892 // This can happen if we were looking for a type and
4893 // found a module instead. Modules don't have defs.
4894 debug!("(resolving item path by identifier in lexical \
4895 scope) failed to resolve {} after success...",
4896 token::get_ident(ident));
4900 debug!("(resolving item path in lexical scope) \
4901 resolved `{}` to item",
4902 token::get_ident(ident));
4903 // This lookup is "all public" because it only searched
4904 // for one identifier in the current module (couldn't
4905 // have passed through reexports or anything like that.
4906 return Some((def, LastMod(AllPublic)));
4911 fail!("unexpected indeterminate result");
4914 debug!("(resolving item path by identifier in lexical scope) \
4915 failed to resolve {}", token::get_ident(ident));
4921 fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
4922 self.emit_errors = false;
4924 self.emit_errors = true;
4928 fn resolve_error(&mut self, span: Span, s: &str) {
4929 if self.emit_errors {
4930 self.session.span_err(span, s);
4934 fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
4936 let this = &mut *self;
4938 let mut maybes: Vec<token::InternedString> = Vec::new();
4939 let mut values: Vec<uint> = Vec::new();
4941 let mut j = this.value_ribs.borrow().len();
4944 let value_ribs = this.value_ribs.borrow();
4945 let bindings = value_ribs.get(j).bindings.borrow();
4946 for (&k, _) in bindings.iter() {
4947 maybes.push(token::get_name(k));
4948 values.push(uint::MAX);
4952 let mut smallest = 0;
4953 for (i, other) in maybes.iter().enumerate() {
4954 *values.get_mut(i) = name.lev_distance(other.get());
4956 if *values.get(i) <= *values.get(smallest) {
4961 if values.len() > 0 &&
4962 *values.get(smallest) != uint::MAX &&
4963 *values.get(smallest) < name.len() + 2 &&
4964 *values.get(smallest) <= max_distance &&
4965 name != maybes.get(smallest).get() {
4967 Some(maybes.get(smallest).get().to_str())
4974 fn resolve_expr(&mut self, expr: &Expr) {
4975 // First, record candidate traits for this expression if it could
4976 // result in the invocation of a method call.
4978 self.record_candidate_traits_for_expr_if_necessary(expr);
4980 // Next, resolve the node.
4982 // The interpretation of paths depends on whether the path has
4983 // multiple elements in it or not.
4985 ExprPath(ref path) => {
4986 // This is a local path in the value namespace. Walk through
4987 // scopes looking for it.
4989 match self.resolve_path(expr.id, path, ValueNS, true) {
4991 // Write the result into the def map.
4992 debug!("(resolving expr) resolved `{}`",
4993 self.path_idents_to_str(path));
4995 // First-class methods are not supported yet; error
4998 (DefMethod(..), _) => {
4999 self.resolve_error(expr.span,
5000 "first-class methods \
5001 are not supported");
5002 self.session.span_note(expr.span,
5010 self.record_def(expr.id, def);
5013 let wrong_name = self.path_idents_to_str(path);
5014 // Be helpful if the name refers to a struct
5015 // (The pattern matching def_tys where the id is in self.structs
5016 // matches on regular structs while excluding tuple- and enum-like
5017 // structs, which wouldn't result in this error.)
5018 match self.with_no_errors(|this|
5019 this.resolve_path(expr.id, path, TypeNS, false)) {
5020 Some((DefTy(struct_id), _))
5021 if self.structs.contains(&struct_id) => {
5022 self.resolve_error(expr.span,
5023 format!("`{}` is a structure name, but \
5025 uses it like a function name",
5028 self.session.span_note(expr.span,
5029 format!("Did you mean to write: \
5030 `{} \\{ /* fields */ \\}`?",
5035 // limit search to 5 to reduce the number
5036 // of stupid suggestions
5037 match self.find_best_match_for_name(wrong_name, 5) {
5039 self.resolve_error(expr.span,
5040 format!("unresolved name `{}`. \
5041 Did you mean `{}`?",
5045 self.resolve_error(expr.span,
5046 format!("unresolved name `{}`.",
5054 visit::walk_expr(self, expr, ());
5057 ExprFnBlock(fn_decl, block) |
5058 ExprProc(fn_decl, block) => {
5059 self.resolve_function(FunctionRibKind(expr.id, block.id),
5060 Some(fn_decl), NoTypeParameters,
5064 ExprStruct(ref path, _, _) => {
5065 // Resolve the path to the structure it goes to.
5066 match self.resolve_path(expr.id, path, TypeNS, false) {
5067 Some((DefTy(class_id), lp)) | Some((DefStruct(class_id), lp))
5068 if self.structs.contains(&class_id) => {
5069 let class_def = DefStruct(class_id);
5070 self.record_def(expr.id, (class_def, lp));
5072 Some(definition @ (DefVariant(_, class_id, _), _))
5073 if self.structs.contains(&class_id) => {
5074 self.record_def(expr.id, definition);
5077 debug!("(resolving expression) didn't find struct \
5078 def: {:?}", result);
5079 let msg = format!("`{}` does not name a structure",
5080 self.path_idents_to_str(path));
5081 self.resolve_error(path.span, msg);
5085 visit::walk_expr(self, expr, ());
5088 ExprLoop(_, Some(label)) => {
5089 self.with_label_rib(|this| {
5090 let def_like = DlDef(DefLabel(expr.id));
5093 let label_ribs = this.label_ribs.borrow();
5094 let length = label_ribs.len();
5095 let rib = label_ribs.get(length - 1);
5096 let renamed = mtwt::resolve(label);
5097 rib.bindings.borrow_mut().insert(renamed, def_like);
5100 visit::walk_expr(this, expr, ());
5104 ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
5106 ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5107 let mut label_ribs = self.label_ribs.borrow_mut();
5108 let renamed = mtwt::resolve(label);
5109 match self.search_ribs(&mut *label_ribs, renamed, expr.span) {
5111 self.resolve_error(expr.span,
5112 format!("use of undeclared label `{}`",
5113 token::get_ident(label))),
5114 Some(DlDef(def @ DefLabel(_))) => {
5115 // Since this def is a label, it is never read.
5116 self.record_def(expr.id, (def, LastMod(AllPublic)))
5119 self.session.span_bug(expr.span,
5120 "label wasn't mapped to a \
5127 visit::walk_expr(self, expr, ());
5132 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5134 ExprField(_, ident, _) => {
5135 // FIXME(#6890): Even though you can't treat a method like a
5136 // field, we need to add any trait methods we find that match
5137 // the field name so that we can do some nice error reporting
5138 // later on in typeck.
5139 let traits = self.search_for_traits_containing_method(ident);
5140 self.trait_map.insert(expr.id, traits);
5142 ExprMethodCall(ident, _, _) => {
5143 debug!("(recording candidate traits for expr) recording \
5146 let traits = self.search_for_traits_containing_method(ident);
5147 self.trait_map.insert(expr.id, traits);
5155 fn search_for_traits_containing_method(&mut self, name: Ident) -> Vec<DefId> {
5156 debug!("(searching for traits containing method) looking for '{}'",
5157 token::get_ident(name));
5159 let mut found_traits = Vec::new();
5160 let mut search_module = self.current_module;
5161 match self.method_map.borrow().find(&name.name) {
5162 Some(candidate_traits) => loop {
5163 // Look for the current trait.
5164 match self.current_trait_refs {
5165 Some(ref trait_def_ids) => {
5166 for trait_def_id in trait_def_ids.iter() {
5167 if candidate_traits.contains(trait_def_id) {
5168 self.add_trait_info(&mut found_traits,
5179 // Look for trait children.
5180 self.populate_module_if_necessary(search_module);
5182 for (_, &child_names) in search_module.children.borrow().iter() {
5183 let def = match child_names.def_for_namespace(TypeNS) {
5187 let trait_def_id = match def {
5188 DefTrait(trait_def_id) => trait_def_id,
5191 if candidate_traits.contains(&trait_def_id) {
5192 self.add_trait_info(&mut found_traits, trait_def_id,
5197 // Look for imports.
5198 let import_resolutions = search_module.import_resolutions
5200 for (_, &import) in import_resolutions.iter() {
5201 let target = match import.target_for_namespace(TypeNS) {
5203 Some(target) => target,
5205 let did = match target.bindings.def_for_namespace(TypeNS) {
5206 Some(DefTrait(trait_def_id)) => trait_def_id,
5207 Some(..) | None => continue,
5209 if candidate_traits.contains(&did) {
5210 self.add_trait_info(&mut found_traits, did, name);
5211 self.used_imports.insert((import.type_id.get(), TypeNS));
5215 match search_module.parent_link {
5216 NoParentLink | ModuleParentLink(..) => break,
5217 BlockParentLink(parent_module, _) => {
5218 search_module = parent_module;
5225 return found_traits;
5228 fn add_trait_info(&self,
5229 found_traits: &mut Vec<DefId> ,
5230 trait_def_id: DefId,
5232 debug!("(adding trait info) found trait {}:{} for method '{}'",
5235 token::get_ident(name));
5236 found_traits.push(trait_def_id);
5239 fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
5240 debug!("(recording def) recording {:?} for {:?}, last private {:?}",
5242 assert!(match lp {LastImport{..} => false, _ => true},
5243 "Import should only be used for `use` directives");
5244 self.last_private.insert(node_id, lp);
5245 self.def_map.borrow_mut().insert_or_update_with(node_id, def, |_, old_value| {
5246 // Resolve appears to "resolve" the same ID multiple
5247 // times, so here is a sanity check it at least comes to
5248 // the same conclusion! - nmatsakis
5249 if def != *old_value {
5250 self.session.bug(format!("node_id {:?} resolved first to {:?} \
5251 and then {:?}", node_id, *old_value, def));
5256 fn enforce_default_binding_mode(&mut self,
5258 pat_binding_mode: BindingMode,
5260 match pat_binding_mode {
5261 BindByValue(_) => {}
5265 format!("cannot use `ref` binding mode with {}",
5272 // Unused import checking
5274 // Although this is mostly a lint pass, it lives in here because it depends on
5275 // resolve data structures and because it finalises the privacy information for
5276 // `use` directives.
5279 fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
5280 let mut visitor = UnusedImportCheckVisitor{ resolver: self };
5281 visit::walk_crate(&mut visitor, krate, ());
5284 fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
5285 // Ignore is_public import statements because there's no way to be sure
5286 // whether they're used or not. Also ignore imports with a dummy span
5287 // because this means that they were generated in some fashion by the
5288 // compiler and we don't need to consider them.
5289 if vi.vis == Public { return }
5290 if vi.span == DUMMY_SP { return }
5293 ViewItemExternCrate(..) => {} // ignore
5294 ViewItemUse(ref path) => {
5295 for p in path.iter() {
5297 ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
5298 ViewPathList(_, ref list, _) => {
5299 for i in list.iter() {
5300 self.finalize_import(i.node.id, i.span);
5303 ViewPathGlob(_, id) => {
5304 if !self.used_imports.contains(&(id, TypeNS)) &&
5305 !self.used_imports.contains(&(id, ValueNS)) {
5306 self.session.add_lint(UnusedImports, id, p.span, ~"unused import");
5315 // We have information about whether `use` (import) directives are actually used now.
5316 // If an import is not used at all, we signal a lint error. If an import is only used
5317 // for a single namespace, we remove the other namespace from the recorded privacy
5318 // information. That means in privacy.rs, we will only check imports and namespaces
5319 // which are used. In particular, this means that if an import could name either a
5320 // public or private item, we will check the correct thing, dependent on how the import
5322 fn finalize_import(&mut self, id: NodeId, span: Span) {
5323 debug!("finalizing import uses for {}", self.session.codemap().span_to_snippet(span));
5325 if !self.used_imports.contains(&(id, TypeNS)) &&
5326 !self.used_imports.contains(&(id, ValueNS)) {
5327 self.session.add_lint(UnusedImports, id, span, ~"unused import");
5330 let (v_priv, t_priv) = match self.last_private.find(&id) {
5331 Some(&LastImport{value_priv: v,
5334 type_used: _}) => (v, t),
5335 Some(_) => fail!("We should only have LastImport for `use` directives"),
5339 let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
5344 let t_used = if self.used_imports.contains(&(id, TypeNS)) {
5350 match (v_priv, t_priv) {
5351 // Since some items may be both in the value _and_ type namespaces (e.g., structs)
5352 // we might have two LastPrivates pointing at the same thing. There is no point
5353 // checking both, so lets not check the value one.
5354 (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
5358 self.last_private.insert(id, LastImport{value_priv: v_priv,
5361 type_used: t_used});
5367 // Diagnostics are not particularly efficient, because they're rarely
5371 /// A somewhat inefficient routine to obtain the name of a module.
5372 fn module_to_str(&mut self, module_: @Module) -> ~str {
5373 let mut idents = Vec::new();
5374 let mut current_module = module_;
5376 match current_module.parent_link {
5380 ModuleParentLink(module_, name) => {
5382 current_module = module_;
5384 BlockParentLink(module_, _) => {
5385 idents.push(special_idents::opaque);
5386 current_module = module_;
5391 if idents.len() == 0 {
5394 return self.idents_to_str(idents.move_iter()
5396 .collect::<Vec<ast::Ident>>()
5400 #[allow(dead_code)] // useful for debugging
5401 fn dump_module(&mut self, module_: @Module) {
5402 debug!("Dump of module `{}`:", self.module_to_str(module_));
5404 debug!("Children:");
5405 self.populate_module_if_necessary(module_);
5406 for (&name, _) in module_.children.borrow().iter() {
5407 debug!("* {}", token::get_name(name));
5410 debug!("Import resolutions:");
5411 let import_resolutions = module_.import_resolutions.borrow();
5412 for (&name, import_resolution) in import_resolutions.iter() {
5414 match import_resolution.target_for_namespace(ValueNS) {
5415 None => { value_repr = ~""; }
5417 value_repr = ~" value:?";
5423 match import_resolution.target_for_namespace(TypeNS) {
5424 None => { type_repr = ~""; }
5426 type_repr = ~" type:?";
5431 debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
5436 pub struct CrateMap {
5437 pub def_map: DefMap,
5438 pub exp_map2: ExportMap2,
5439 pub trait_map: TraitMap,
5440 pub external_exports: ExternalExports,
5441 pub last_private_map: LastPrivateMap,
5444 /// Entry point to crate resolution.
5445 pub fn resolve_crate(session: &Session,
5446 lang_items: @LanguageItems,
5449 let mut resolver = Resolver(session, lang_items, krate.span);
5450 resolver.resolve(krate);
5451 let Resolver { def_map, export_map2, trait_map, last_private,
5452 external_exports, .. } = resolver;
5455 exp_map2: export_map2,
5456 trait_map: trait_map,
5457 external_exports: external_exports,
5458 last_private_map: last_private,