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::opt_vec::OptVec;
32 use syntax::visit::Visitor;
34 use std::cell::{Cell, RefCell};
36 use std::mem::replace;
37 use collections::{HashMap, HashSet};
40 pub type DefMap = @RefCell<NodeMap<Def>>;
44 binding_mode: BindingMode,
47 // Map from the name in a pattern to its binding mode.
48 type BindingMap = HashMap<Name,binding_info>;
50 // Trait method resolution
51 pub type TraitMap = NodeMap<Vec<DefId> >;
53 // This is the replacement export map. It maps a module to all of the exports
55 pub type ExportMap2 = @RefCell<NodeMap<Vec<Export2> >>;
58 name: ~str, // The name of the target.
59 def_id: DefId, // The definition of the target.
62 // This set contains all exported definitions from external crates. The set does
63 // not contain any entries from local crates.
64 pub type ExternalExports = DefIdSet;
67 pub type LastPrivateMap = NodeMap<LastPrivate>;
69 pub enum LastPrivate {
71 // `use` directives (imports) can refer to two separate definitions in the
72 // type and value namespaces. We record here the last private node for each
73 // and whether the import is in fact used for each.
74 // If the Option<PrivateDep> fields are None, it means there is no defintion
76 LastImport{value_priv: Option<PrivateDep>,
77 value_used: ImportUse,
78 type_priv: Option<PrivateDep>,
79 type_used: ImportUse},
87 // How an import is used.
90 Unused, // The import is not used.
91 Used, // The import is used.
95 fn or(self, other: LastPrivate) -> LastPrivate {
97 (me, LastMod(AllPublic)) => me,
104 enum PatternBindingMode {
106 LocalIrrefutableMode,
107 ArgumentIrrefutableMode,
110 #[deriving(Eq, Hash)]
117 enum NamespaceError {
124 /// A NamespaceResult represents the result of resolving an import in
125 /// a particular namespace. The result is either definitely-resolved,
126 /// definitely- unresolved, or unknown.
127 enum NamespaceResult {
128 /// Means that resolve hasn't gathered enough information yet to determine
129 /// whether the name is bound in this namespace. (That is, it hasn't
130 /// resolved all `use` directives yet.)
132 /// Means that resolve has determined that the name is definitely
133 /// not bound in the namespace.
135 /// Means that resolve has determined that the name is bound in the Module
136 /// argument, and specified by the NameBindings argument.
137 BoundResult(@Module, @NameBindings)
140 impl NamespaceResult {
141 fn is_unknown(&self) -> bool {
143 UnknownResult => true,
149 enum NameDefinition {
150 NoNameDefinition, //< The name was unbound.
151 ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
152 ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
155 impl<'a> Visitor<()> for Resolver<'a> {
156 fn visit_item(&mut self, item: &Item, _: ()) {
157 self.resolve_item(item);
159 fn visit_arm(&mut self, arm: &Arm, _: ()) {
160 self.resolve_arm(arm);
162 fn visit_block(&mut self, block: &Block, _: ()) {
163 self.resolve_block(block);
165 fn visit_expr(&mut self, expr: &Expr, _: ()) {
166 self.resolve_expr(expr);
168 fn visit_local(&mut self, local: &Local, _: ()) {
169 self.resolve_local(local);
171 fn visit_ty(&mut self, ty: &Ty, _: ()) {
172 self.resolve_type(ty);
176 /// Contains data for specific types of import directives.
177 enum ImportDirectiveSubclass {
178 SingleImport(Ident /* target */, Ident /* source */),
182 /// The context that we thread through while building the reduced graph.
184 enum ReducedGraphParent {
185 ModuleReducedGraphParent(@Module)
188 impl ReducedGraphParent {
189 fn module(&self) -> @Module {
191 ModuleReducedGraphParent(m) => {
198 enum ResolveResult<T> {
199 Failed, // Failed to resolve the name.
200 Indeterminate, // Couldn't determine due to unresolved globs.
201 Success(T) // Successfully resolved the import.
204 impl<T> ResolveResult<T> {
205 fn indeterminate(&self) -> bool {
206 match *self { Indeterminate => true, _ => false }
210 enum TypeParameters<'a> {
211 NoTypeParameters, //< No type parameters.
212 HasTypeParameters(&'a Generics, //< Type parameters.
213 NodeId, //< ID of the enclosing item
215 // The index to start numbering the type parameters at.
216 // This is zero if this is the outermost set of type
217 // parameters, or equal to the number of outer type
218 // parameters. For example, if we have:
221 // fn method<U>() { ... }
224 // The index at the method site will be 1, because the
225 // outer T had index 0.
228 // The kind of the rib used for type parameters.
232 // The rib kind controls the translation of argument or local definitions
233 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
236 // No translation needs to be applied.
239 // We passed through a function scope at the given node ID. Translate
240 // upvars as appropriate.
241 FunctionRibKind(NodeId /* func id */, NodeId /* body id */),
243 // We passed through an impl or trait and are now in one of its
244 // methods. Allow references to ty params that impl or trait
245 // binds. Disallow any other upvars (including other ty params that are
247 // parent; method itself
248 MethodRibKind(NodeId, MethodSort),
250 // We passed through a function *item* scope. Disallow upvars.
251 OpaqueFunctionRibKind,
253 // We're in a constant item. Can't refer to dynamic stuff.
257 // Methods can be required or provided. Required methods only occur in traits.
263 enum UseLexicalScopeFlag {
268 enum SearchThroughModulesFlag {
269 DontSearchThroughModules,
273 enum ModulePrefixResult {
275 PrefixFound(@Module, uint)
279 enum NameSearchType {
280 /// We're doing a name search in order to resolve a `use` directive.
283 /// We're doing a name search in order to resolve a path type, a path
284 /// expression, or a path pattern.
288 enum BareIdentifierPatternResolution {
289 FoundStructOrEnumVariant(Def, LastPrivate),
290 FoundConst(Def, LastPrivate),
291 BareIdentifierPatternUnresolved
294 // Specifies how duplicates should be handled when adding a child item if
295 // another item exists with the same name in some namespace.
297 enum DuplicateCheckingMode {
298 ForbidDuplicateModules,
299 ForbidDuplicateTypes,
300 ForbidDuplicateValues,
301 ForbidDuplicateTypesAndValues,
307 bindings: RefCell<HashMap<Name, DefLike>>,
312 fn new(kind: RibKind) -> Rib {
314 bindings: RefCell::new(HashMap::new()),
320 /// One import directive.
321 struct ImportDirective {
322 module_path: Vec<Ident> ,
323 subclass: @ImportDirectiveSubclass,
326 is_public: bool, // see note in ImportResolution about how to use this
329 impl ImportDirective {
330 fn new(module_path: Vec<Ident> ,
331 subclass: @ImportDirectiveSubclass,
337 module_path: module_path,
341 is_public: is_public,
346 /// The item that an import resolves to.
349 target_module: @Module,
350 bindings: @NameBindings,
354 fn new(target_module: @Module, bindings: @NameBindings) -> Target {
356 target_module: target_module,
362 /// An ImportResolution represents a particular `use` directive.
363 struct ImportResolution {
364 /// Whether this resolution came from a `use` or a `pub use`. Note that this
365 /// should *not* be used whenever resolution is being performed, this is
366 /// only looked at for glob imports statements currently. Privacy testing
367 /// occurs during a later phase of compilation.
368 is_public: Cell<bool>,
370 // The number of outstanding references to this name. When this reaches
371 // zero, outside modules can count on the targets being correct. Before
372 // then, all bets are off; future imports could override this name.
373 outstanding_references: Cell<uint>,
375 /// The value that this `use` directive names, if there is one.
376 value_target: RefCell<Option<Target>>,
377 /// The source node of the `use` directive leading to the value target
379 value_id: Cell<NodeId>,
381 /// The type that this `use` directive names, if there is one.
382 type_target: RefCell<Option<Target>>,
383 /// The source node of the `use` directive leading to the type target
385 type_id: Cell<NodeId>,
388 impl ImportResolution {
389 fn new(id: NodeId, is_public: bool) -> ImportResolution {
391 type_id: Cell::new(id),
392 value_id: Cell::new(id),
393 outstanding_references: Cell::new(0),
394 value_target: RefCell::new(None),
395 type_target: RefCell::new(None),
396 is_public: Cell::new(is_public),
400 fn target_for_namespace(&self, namespace: Namespace)
403 TypeNS => return self.type_target.get(),
404 ValueNS => return self.value_target.get(),
408 fn id(&self, namespace: Namespace) -> NodeId {
410 TypeNS => self.type_id.get(),
411 ValueNS => self.value_id.get(),
416 /// The link from a module up to its nearest parent node.
419 ModuleParentLink(@Module, Ident),
420 BlockParentLink(@Module, NodeId)
423 /// The type of module this is.
433 /// One node in the tree of modules.
435 parent_link: ParentLink,
436 def_id: Cell<Option<DefId>>,
437 kind: Cell<ModuleKind>,
440 children: RefCell<HashMap<Name, @NameBindings>>,
441 imports: RefCell<Vec<@ImportDirective> >,
443 // The external module children of this node that were declared with
445 external_module_children: RefCell<HashMap<Name, @Module>>,
447 // The anonymous children of this node. Anonymous children are pseudo-
448 // modules that are implicitly created around items contained within
451 // For example, if we have this:
459 // There will be an anonymous module created around `g` with the ID of the
460 // entry block for `f`.
461 anonymous_children: RefCell<NodeMap<@Module>>,
463 // The status of resolving each import in this module.
464 import_resolutions: RefCell<HashMap<Name, @ImportResolution>>,
466 // The number of unresolved globs that this module exports.
467 glob_count: Cell<uint>,
469 // The index of the import we're resolving.
470 resolved_import_count: Cell<uint>,
472 // Whether this module is populated. If not populated, any attempt to
473 // access the children must be preceded with a
474 // `populate_module_if_necessary` call.
475 populated: Cell<bool>,
479 fn new(parent_link: ParentLink,
480 def_id: Option<DefId>,
486 parent_link: parent_link,
487 def_id: Cell::new(def_id),
488 kind: Cell::new(kind),
489 is_public: is_public,
490 children: RefCell::new(HashMap::new()),
491 imports: RefCell::new(Vec::new()),
492 external_module_children: RefCell::new(HashMap::new()),
493 anonymous_children: RefCell::new(NodeMap::new()),
494 import_resolutions: RefCell::new(HashMap::new()),
495 glob_count: Cell::new(0),
496 resolved_import_count: Cell::new(0),
497 populated: Cell::new(!external),
501 fn all_imports_resolved(&self) -> bool {
502 let mut imports = self.imports.borrow_mut();
503 return imports.get().len() == self.resolved_import_count.get();
507 // Records a possibly-private type definition.
510 is_public: bool, // see note in ImportResolution about how to use this
511 module_def: Option<@Module>,
512 type_def: Option<Def>,
513 type_span: Option<Span>
516 // Records a possibly-private value definition.
519 is_public: bool, // see note in ImportResolution about how to use this
521 value_span: Option<Span>,
524 // Records the definitions (at most one for each namespace) that a name is
526 struct NameBindings {
527 type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
528 value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
531 /// Ways in which a trait can be referenced
532 enum TraitReferenceType {
533 TraitImplementation, // impl SomeTrait for T { ... }
534 TraitDerivation, // trait T : SomeTrait { ... }
535 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
539 /// Creates a new module in this set of name bindings.
540 fn define_module(&self,
541 parent_link: ParentLink,
542 def_id: Option<DefId>,
547 // Merges the module with the existing type def or creates a new one.
548 let module_ = @Module::new(parent_link, def_id, kind, external,
550 match self.type_def.get() {
552 self.type_def.set(Some(TypeNsDef {
553 is_public: is_public,
554 module_def: Some(module_),
560 self.type_def.set(Some(TypeNsDef {
561 is_public: is_public,
562 module_def: Some(module_),
564 type_def: type_def.type_def
570 /// Sets the kind of the module, creating a new one if necessary.
571 fn set_module_kind(&self,
572 parent_link: ParentLink,
573 def_id: Option<DefId>,
578 match self.type_def.get() {
580 let module = @Module::new(parent_link, def_id, kind,
581 external, is_public);
582 self.type_def.set(Some(TypeNsDef {
583 is_public: is_public,
584 module_def: Some(module),
590 match type_def.module_def {
592 let module = @Module::new(parent_link,
597 self.type_def.set(Some(TypeNsDef {
598 is_public: is_public,
599 module_def: Some(module),
600 type_def: type_def.type_def,
604 Some(module_def) => module_def.kind.set(kind),
610 /// Records a type definition.
611 fn define_type(&self, def: Def, sp: Span, is_public: bool) {
612 // Merges the type with the existing type def or creates a new one.
613 match self.type_def.get() {
615 self.type_def.set(Some(TypeNsDef {
619 is_public: is_public,
623 self.type_def.set(Some(TypeNsDef {
626 module_def: type_def.module_def,
627 is_public: is_public,
633 /// Records a value definition.
634 fn define_value(&self, def: Def, sp: Span, is_public: bool) {
635 self.value_def.set(Some(ValueNsDef {
637 value_span: Some(sp),
638 is_public: is_public,
642 /// Returns the module node if applicable.
643 fn get_module_if_available(&self) -> Option<@Module> {
644 let type_def = self.type_def.borrow();
645 match *type_def.get() {
646 Some(ref type_def) => (*type_def).module_def,
652 * Returns the module node. Fails if this node does not have a module
655 fn get_module(&self) -> @Module {
656 match self.get_module_if_available() {
658 fail!("get_module called on a node with no module \
661 Some(module_def) => module_def
665 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
667 TypeNS => return self.type_def.get().is_some(),
668 ValueNS => return self.value_def.get().is_some()
672 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
674 TypeNS => match self.type_def.get() {
675 Some(def) => def.is_public, None => false
677 ValueNS => match self.value_def.get() {
678 Some(def) => def.is_public, None => false
683 fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
686 match self.type_def.get() {
689 match type_def.type_def {
690 Some(type_def) => Some(type_def),
692 match type_def.module_def {
694 match module.def_id.get() {
695 Some(did) => Some(DefMod(did)),
707 match self.value_def.get() {
709 Some(value_def) => Some(value_def.def)
715 fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
716 if self.defined_in_namespace(namespace) {
719 match self.type_def.get() {
721 Some(type_def) => type_def.type_span
725 match self.value_def.get() {
727 Some(value_def) => value_def.value_span
737 fn NameBindings() -> NameBindings {
739 type_def: RefCell::new(None),
740 value_def: RefCell::new(None),
744 /// Interns the names of the primitive types.
745 struct PrimitiveTypeTable {
746 primitive_types: HashMap<Name, PrimTy>,
749 impl PrimitiveTypeTable {
750 fn intern(&mut self, string: &str, primitive_type: PrimTy) {
751 self.primitive_types.insert(token::intern(string), primitive_type);
755 fn PrimitiveTypeTable() -> PrimitiveTypeTable {
756 let mut table = PrimitiveTypeTable {
757 primitive_types: HashMap::new()
760 table.intern("bool", TyBool);
761 table.intern("char", TyChar);
762 table.intern("f32", TyFloat(TyF32));
763 table.intern("f64", TyFloat(TyF64));
764 table.intern("int", TyInt(TyI));
765 table.intern("i8", TyInt(TyI8));
766 table.intern("i16", TyInt(TyI16));
767 table.intern("i32", TyInt(TyI32));
768 table.intern("i64", TyInt(TyI64));
769 table.intern("str", TyStr);
770 table.intern("uint", TyUint(TyU));
771 table.intern("u8", TyUint(TyU8));
772 table.intern("u16", TyUint(TyU16));
773 table.intern("u32", TyUint(TyU32));
774 table.intern("u64", TyUint(TyU64));
780 fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
783 ModuleError => "module",
785 ValueError => "value",
789 fn Resolver<'a>(session: &'a Session,
790 lang_items: @LanguageItems,
791 crate_span: Span) -> Resolver<'a> {
792 let graph_root = @NameBindings();
794 graph_root.define_module(NoParentLink,
795 Some(DefId { krate: 0, node: 0 }),
801 let current_module = graph_root.get_module();
803 let this = Resolver {
805 lang_items: lang_items,
807 // The outermost module has def ID 0; this is not reflected in the
810 graph_root: graph_root,
812 method_map: @RefCell::new(HashMap::new()),
813 structs: HashSet::new(),
815 unresolved_imports: 0,
817 current_module: current_module,
818 value_ribs: @RefCell::new(Vec::new()),
819 type_ribs: @RefCell::new(Vec::new()),
820 label_ribs: @RefCell::new(Vec::new()),
822 current_trait_refs: None,
824 self_ident: special_idents::self_,
825 type_self_ident: special_idents::type_self,
827 primitive_type_table: @PrimitiveTypeTable(),
829 namespaces: vec!(TypeNS, ValueNS),
831 def_map: @RefCell::new(NodeMap::new()),
832 export_map2: @RefCell::new(NodeMap::new()),
833 trait_map: NodeMap::new(),
834 used_imports: HashSet::new(),
835 external_exports: DefIdSet::new(),
836 last_private: NodeMap::new(),
844 /// The main resolver class.
845 struct Resolver<'a> {
846 session: &'a Session,
847 lang_items: @LanguageItems,
849 graph_root: @NameBindings,
851 method_map: @RefCell<HashMap<Name, HashSet<DefId>>>,
852 structs: HashSet<DefId>,
854 // The number of imports that are currently unresolved.
855 unresolved_imports: uint,
857 // The module that represents the current item scope.
858 current_module: @Module,
860 // The current set of local scopes, for values.
861 // FIXME #4948: Reuse ribs to avoid allocation.
862 value_ribs: @RefCell<Vec<@Rib> >,
864 // The current set of local scopes, for types.
865 type_ribs: @RefCell<Vec<@Rib> >,
867 // The current set of local scopes, for labels.
868 label_ribs: @RefCell<Vec<@Rib> >,
870 // The trait that the current context can refer to.
871 current_trait_refs: Option<Vec<DefId> >,
873 // The ident for the keyword "self".
875 // The ident for the non-keyword "Self".
876 type_self_ident: Ident,
878 // The idents for the primitive types.
879 primitive_type_table: @PrimitiveTypeTable,
881 // The four namespaces.
882 namespaces: Vec<Namespace> ,
885 export_map2: ExportMap2,
887 external_exports: ExternalExports,
888 last_private: LastPrivateMap,
890 // Whether or not to print error messages. Can be set to true
891 // when getting additional info for error message suggestions,
892 // so as to avoid printing duplicate errors
895 used_imports: HashSet<(NodeId, Namespace)>,
898 struct BuildReducedGraphVisitor<'a, 'b> {
899 resolver: &'a mut Resolver<'b>,
902 impl<'a, 'b> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a, 'b> {
904 fn visit_item(&mut self, item: &Item, context: ReducedGraphParent) {
905 let p = self.resolver.build_reduced_graph_for_item(item, context);
906 visit::walk_item(self, item, p);
909 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem,
910 context: ReducedGraphParent) {
911 self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
914 let mut v = BuildReducedGraphVisitor{ resolver: r };
915 visit::walk_foreign_item(&mut v, foreign_item, c);
919 fn visit_view_item(&mut self, view_item: &ViewItem, context: ReducedGraphParent) {
920 self.resolver.build_reduced_graph_for_view_item(view_item, context);
923 fn visit_block(&mut self, block: &Block, context: ReducedGraphParent) {
924 let np = self.resolver.build_reduced_graph_for_block(block, context);
925 visit::walk_block(self, block, np);
930 struct UnusedImportCheckVisitor<'a, 'b> { resolver: &'a mut Resolver<'b> }
932 impl<'a, 'b> Visitor<()> for UnusedImportCheckVisitor<'a, 'b> {
933 fn visit_view_item(&mut self, vi: &ViewItem, _: ()) {
934 self.resolver.check_for_item_unused_imports(vi);
935 visit::walk_view_item(self, vi, ());
939 impl<'a> Resolver<'a> {
940 /// The main name resolution procedure.
941 fn resolve(&mut self, krate: &ast::Crate) {
942 self.build_reduced_graph(krate);
943 self.session.abort_if_errors();
945 self.resolve_imports();
946 self.session.abort_if_errors();
948 self.record_exports();
949 self.session.abort_if_errors();
951 self.resolve_crate(krate);
952 self.session.abort_if_errors();
954 self.check_for_unused_imports(krate);
958 // Reduced graph building
960 // Here we build the "reduced graph": the graph of the module tree without
961 // any imports resolved.
964 /// Constructs the reduced graph for the entire crate.
965 fn build_reduced_graph(&mut self, krate: &ast::Crate) {
967 ModuleReducedGraphParent(self.graph_root.get_module());
969 let mut visitor = BuildReducedGraphVisitor { resolver: self, };
970 visit::walk_crate(&mut visitor, krate, initial_parent);
973 /// Returns the current module tracked by the reduced graph parent.
974 fn get_module_from_parent(&mut self,
975 reduced_graph_parent: ReducedGraphParent)
977 match reduced_graph_parent {
978 ModuleReducedGraphParent(module_) => {
985 * Adds a new child item to the module definition of the parent node and
986 * returns its corresponding name bindings as well as the current parent.
987 * Or, if we're inside a block, creates (or reuses) an anonymous module
988 * corresponding to the innermost block ID and returns the name bindings
989 * as well as the newly-created parent.
991 * If this node does not have a module definition and we are not inside
994 fn add_child(&mut self,
996 reduced_graph_parent: ReducedGraphParent,
997 duplicate_checking_mode: DuplicateCheckingMode,
998 // For printing errors
1000 -> (@NameBindings, ReducedGraphParent) {
1001 // If this is the immediate descendant of a module, then we add the
1002 // child name directly. Otherwise, we create or reuse an anonymous
1003 // module and add the child to that.
1006 match reduced_graph_parent {
1007 ModuleReducedGraphParent(parent_module) => {
1008 module_ = parent_module;
1012 // Add or reuse the child.
1013 let new_parent = ModuleReducedGraphParent(module_);
1015 let children = module_.children.borrow();
1016 children.get().find_copy(&name.name)
1020 let child = @NameBindings();
1021 let mut children = module_.children.borrow_mut();
1022 children.get().insert(name.name, child);
1023 return (child, new_parent);
1026 // Enforce the duplicate checking mode:
1028 // * If we're requesting duplicate module checking, check that
1029 // there isn't a module in the module with the same name.
1031 // * If we're requesting duplicate type checking, check that
1032 // there isn't a type in the module with the same name.
1034 // * If we're requesting duplicate value checking, check that
1035 // there isn't a value in the module with the same name.
1037 // * If we're requesting duplicate type checking and duplicate
1038 // value checking, check that there isn't a duplicate type
1039 // and a duplicate value with the same name.
1041 // * If no duplicate checking was requested at all, do
1044 let mut duplicate_type = NoError;
1045 let ns = match duplicate_checking_mode {
1046 ForbidDuplicateModules => {
1047 if child.get_module_if_available().is_some() {
1048 duplicate_type = ModuleError;
1052 ForbidDuplicateTypes => {
1053 match child.def_for_namespace(TypeNS) {
1054 Some(DefMod(_)) | None => {}
1055 Some(_) => duplicate_type = TypeError
1059 ForbidDuplicateValues => {
1060 if child.defined_in_namespace(ValueNS) {
1061 duplicate_type = ValueError;
1065 ForbidDuplicateTypesAndValues => {
1067 match child.def_for_namespace(TypeNS) {
1068 Some(DefMod(_)) | None => {}
1071 duplicate_type = TypeError;
1074 if child.defined_in_namespace(ValueNS) {
1075 duplicate_type = ValueError;
1080 OverwriteDuplicates => None
1082 if duplicate_type != NoError {
1083 // Return an error here by looking up the namespace that
1084 // had the duplicate.
1085 let ns = ns.unwrap();
1086 self.resolve_error(sp,
1087 format!("duplicate definition of {} `{}`",
1088 namespace_error_to_str(duplicate_type),
1089 token::get_ident(name)));
1091 let r = child.span_for_namespace(ns);
1092 for sp in r.iter() {
1093 self.session.span_note(*sp,
1094 format!("first definition of {} `{}` here",
1095 namespace_error_to_str(duplicate_type),
1096 token::get_ident(name)));
1100 return (child, new_parent);
1105 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1106 // If the block has view items, we need an anonymous module.
1107 if block.view_items.len() > 0 {
1111 // Check each statement.
1112 for statement in block.stmts.iter() {
1113 match statement.node {
1114 StmtDecl(declaration, _) => {
1115 match declaration.node {
1130 // If we found neither view items nor items, we don't need to create
1131 // an anonymous module.
1136 fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Ident)
1139 ModuleReducedGraphParent(module_) => {
1140 return ModuleParentLink(module_, name);
1145 /// Constructs the reduced graph for one item.
1146 fn build_reduced_graph_for_item(&mut self,
1148 parent: ReducedGraphParent)
1149 -> ReducedGraphParent
1151 let ident = item.ident;
1153 let is_public = item.vis == ast::Public;
1157 let (name_bindings, new_parent) =
1158 self.add_child(ident, parent, ForbidDuplicateModules, sp);
1160 let parent_link = self.get_parent_link(new_parent, ident);
1161 let def_id = DefId { krate: 0, node: item.id };
1162 name_bindings.define_module(parent_link,
1166 item.vis == ast::Public,
1169 ModuleReducedGraphParent(name_bindings.get_module())
1172 ItemForeignMod(..) => parent,
1174 // These items live in the value namespace.
1175 ItemStatic(_, m, _) => {
1176 let (name_bindings, _) =
1177 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1178 let mutbl = m == ast::MutMutable;
1180 name_bindings.define_value
1181 (DefStatic(local_def(item.id), mutbl), sp, is_public);
1184 ItemFn(_, purity, _, _, _) => {
1185 let (name_bindings, new_parent) =
1186 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1188 let def = DefFn(local_def(item.id), purity);
1189 name_bindings.define_value(def, sp, is_public);
1193 // These items live in the type namespace.
1195 let (name_bindings, _) =
1196 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1198 name_bindings.define_type
1199 (DefTy(local_def(item.id)), sp, is_public);
1203 ItemEnum(ref enum_definition, _) => {
1204 let (name_bindings, new_parent) =
1205 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1207 name_bindings.define_type
1208 (DefTy(local_def(item.id)), sp, is_public);
1210 for &variant in (*enum_definition).variants.iter() {
1211 self.build_reduced_graph_for_variant(
1220 // These items live in both the type and value namespaces.
1221 ItemStruct(struct_def, _) => {
1222 // Adding to both Type and Value namespaces or just Type?
1223 let (forbid, ctor_id) = match struct_def.ctor_id {
1224 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1225 None => (ForbidDuplicateTypes, None)
1228 let (name_bindings, new_parent) = self.add_child(ident, parent, forbid, sp);
1230 // Define a name in the type namespace.
1231 name_bindings.define_type(DefTy(local_def(item.id)), sp, is_public);
1233 // If this is a newtype or unit-like struct, define a name
1234 // in the value namespace as well
1235 ctor_id.while_some(|cid| {
1236 name_bindings.define_value(DefStruct(local_def(cid)), sp,
1241 // Record the def ID of this struct.
1242 self.structs.insert(local_def(item.id));
1247 ItemImpl(_, None, ty, ref methods) => {
1248 // If this implements an anonymous trait, then add all the
1249 // methods within to a new module, if the type was defined
1250 // within this module.
1252 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1253 // should modify anonymous traits to only be implementable in
1254 // the same module that declared the type.
1256 // Create the module and add all methods.
1258 TyPath(ref path, _, _) if path.segments.len() == 1 => {
1259 let name = path_to_ident(path);
1261 let existing_parent_opt = {
1262 let children = parent.module().children.borrow();
1263 children.get().find_copy(&name.name)
1265 let new_parent = match existing_parent_opt {
1266 // It already exists
1267 Some(child) if child.get_module_if_available()
1269 child.get_module().kind.get() ==
1271 ModuleReducedGraphParent(child.get_module())
1273 // Create the module
1275 let (name_bindings, new_parent) =
1276 self.add_child(name,
1278 ForbidDuplicateModules,
1282 self.get_parent_link(new_parent, ident);
1283 let def_id = local_def(item.id);
1286 !name_bindings.defined_in_namespace(ns) ||
1287 name_bindings.defined_in_public_namespace(ns);
1289 name_bindings.define_module(parent_link,
1296 ModuleReducedGraphParent(
1297 name_bindings.get_module())
1301 // For each method...
1302 for method in methods.iter() {
1303 // Add the method to the module.
1304 let ident = method.ident;
1305 let (method_name_bindings, _) =
1306 self.add_child(ident,
1308 ForbidDuplicateValues,
1310 let def = match method.explicit_self.node {
1312 // Static methods become
1313 // `def_static_method`s.
1314 DefStaticMethod(local_def(method.id),
1320 // Non-static methods become
1322 DefMethod(local_def(method.id), None)
1326 let is_public = method.vis == ast::Public;
1327 method_name_bindings.define_value(def,
1338 ItemImpl(_, Some(_), _, _) => parent,
1340 ItemTrait(_, _, ref methods) => {
1341 let (name_bindings, new_parent) =
1342 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1344 // Add all the methods within to a new module.
1345 let parent_link = self.get_parent_link(parent, ident);
1346 name_bindings.define_module(parent_link,
1347 Some(local_def(item.id)),
1350 item.vis == ast::Public,
1352 let module_parent = ModuleReducedGraphParent(name_bindings.
1355 // Add the names of all the methods to the trait info.
1356 let mut method_names = HashMap::new();
1357 for method in methods.iter() {
1358 let ty_m = trait_method_to_ty_method(method);
1360 let ident = ty_m.ident;
1362 // Add it as a name in the trait module.
1363 let def = match ty_m.explicit_self.node {
1365 // Static methods become `def_static_method`s.
1366 DefStaticMethod(local_def(ty_m.id),
1367 FromTrait(local_def(item.id)),
1371 // Non-static methods become `def_method`s.
1372 DefMethod(local_def(ty_m.id),
1373 Some(local_def(item.id)))
1377 let (method_name_bindings, _) =
1378 self.add_child(ident,
1380 ForbidDuplicateValues,
1382 method_name_bindings.define_value(def, ty_m.span, true);
1384 // Add it to the trait info if not static.
1385 match ty_m.explicit_self.node {
1388 method_names.insert(ident.name, ());
1393 let def_id = local_def(item.id);
1394 for (name, _) in method_names.iter() {
1395 let mut method_map = self.method_map.borrow_mut();
1396 if !method_map.get().contains_key(name) {
1397 method_map.get().insert(*name, HashSet::new());
1399 match method_map.get().find_mut(name) {
1400 Some(s) => { s.insert(def_id); },
1401 _ => fail!("can't happen"),
1405 name_bindings.define_type(DefTrait(def_id), sp, is_public);
1408 ItemMac(..) => parent
1412 // Constructs the reduced graph for one variant. Variants exist in the
1413 // type and/or value namespaces.
1414 fn build_reduced_graph_for_variant(&mut self,
1417 parent: ReducedGraphParent,
1418 parent_public: bool) {
1419 let ident = variant.node.name;
1420 // FIXME: this is unfortunate to have to do this privacy calculation
1421 // here. This should be living in middle::privacy, but it's
1422 // necessary to keep around in some form becaues of glob imports...
1423 let is_public = parent_public && variant.node.vis != ast::Private;
1425 match variant.node.kind {
1426 TupleVariantKind(_) => {
1427 let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues,
1429 child.define_value(DefVariant(item_id,
1430 local_def(variant.node.id), false),
1431 variant.span, is_public);
1433 StructVariantKind(_) => {
1434 let (child, _) = self.add_child(ident, parent, ForbidDuplicateTypesAndValues,
1436 child.define_type(DefVariant(item_id,
1437 local_def(variant.node.id), true),
1438 variant.span, is_public);
1439 self.structs.insert(local_def(variant.node.id));
1444 /// Constructs the reduced graph for one 'view item'. View items consist
1445 /// of imports and use directives.
1446 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1447 parent: ReducedGraphParent) {
1448 match view_item.node {
1449 ViewItemUse(ref view_paths) => {
1450 for view_path in view_paths.iter() {
1451 // Extract and intern the module part of the path. For
1452 // globs and lists, the path is found directly in the AST;
1453 // for simple paths we have to munge the path a little.
1455 let mut module_path = Vec::new();
1456 match view_path.node {
1457 ViewPathSimple(_, ref full_path, _) => {
1458 let path_len = full_path.segments.len();
1459 assert!(path_len != 0);
1461 for (i, segment) in full_path.segments
1464 if i != path_len - 1 {
1465 module_path.push(segment.identifier)
1470 ViewPathGlob(ref module_ident_path, _) |
1471 ViewPathList(ref module_ident_path, _, _) => {
1472 for segment in module_ident_path.segments.iter() {
1473 module_path.push(segment.identifier)
1478 // Build up the import directives.
1479 let module_ = self.get_module_from_parent(parent);
1480 let is_public = view_item.vis == ast::Public;
1481 match view_path.node {
1482 ViewPathSimple(binding, ref full_path, id) => {
1484 full_path.segments.last().unwrap().identifier;
1485 let subclass = @SingleImport(binding,
1487 self.build_import_directive(module_,
1494 ViewPathList(_, ref source_idents, _) => {
1495 for source_ident in source_idents.iter() {
1496 let name = source_ident.node.name;
1497 let subclass = @SingleImport(name, name);
1498 self.build_import_directive(
1500 module_path.clone(),
1503 source_ident.node.id,
1507 ViewPathGlob(_, id) => {
1508 self.build_import_directive(module_,
1519 ViewItemExternCrate(name, _, node_id) => {
1520 // n.b. we don't need to look at the path option here, because cstore already did
1521 match self.session.cstore.find_extern_mod_stmt_cnum(node_id) {
1523 let def_id = DefId { krate: crate_id, node: 0 };
1524 self.external_exports.insert(def_id);
1525 let parent_link = ModuleParentLink
1526 (self.get_module_from_parent(parent), name);
1527 let external_module = @Module::new(parent_link,
1534 let mut external_module_children =
1535 parent.module().external_module_children.borrow_mut();
1536 external_module_children.get().insert(
1541 self.build_reduced_graph_for_external_crate(
1544 None => {} // Ignore.
1550 /// Constructs the reduced graph for one foreign item.
1551 fn build_reduced_graph_for_foreign_item(&mut self,
1552 foreign_item: &ForeignItem,
1553 parent: ReducedGraphParent,
1555 ReducedGraphParent|) {
1556 let name = foreign_item.ident;
1557 let is_public = foreign_item.vis == ast::Public;
1558 let (name_bindings, new_parent) =
1559 self.add_child(name, parent, ForbidDuplicateValues,
1562 match foreign_item.node {
1563 ForeignItemFn(_, ref generics) => {
1564 let def = DefFn(local_def(foreign_item.id), UnsafeFn);
1565 name_bindings.define_value(def, foreign_item.span, is_public);
1567 self.with_type_parameter_rib(
1568 HasTypeParameters(generics,
1572 |this| f(this, new_parent));
1574 ForeignItemStatic(_, m) => {
1575 let def = DefStatic(local_def(foreign_item.id), m);
1576 name_bindings.define_value(def, foreign_item.span, is_public);
1583 fn build_reduced_graph_for_block(&mut self,
1585 parent: ReducedGraphParent)
1586 -> ReducedGraphParent
1588 if self.block_needs_anonymous_module(block) {
1589 let block_id = block.id;
1591 debug!("(building reduced graph for block) creating a new \
1592 anonymous module for block {}",
1595 let parent_module = self.get_module_from_parent(parent);
1596 let new_module = @Module::new(
1597 BlockParentLink(parent_module, block_id),
1599 AnonymousModuleKind,
1603 let mut anonymous_children = parent_module.anonymous_children
1605 anonymous_children.get().insert(block_id, new_module);
1606 ModuleReducedGraphParent(new_module)
1613 fn handle_external_def(&mut self,
1616 child_name_bindings: @NameBindings,
1619 new_parent: ReducedGraphParent) {
1620 debug!("(building reduced graph for \
1621 external crate) building external def, priv {:?}",
1623 let is_public = vis == ast::Public;
1624 let is_exported = is_public && match new_parent {
1625 ModuleReducedGraphParent(module) => {
1626 match module.def_id.get() {
1628 Some(did) => self.external_exports.contains(&did)
1633 self.external_exports.insert(def_id_of_def(def));
1636 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1638 match child_name_bindings.type_def.get() {
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.get().contains_key(name) {
1715 method_map.get().insert(*name, HashSet::new());
1717 match method_map.get().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 match child_name_bindings.type_def.get() {
1832 module_def: Some(module_def),
1835 // We already have a module. This
1837 type_module = module_def;
1839 // Mark it as an impl module if
1841 type_module.kind.set(ImplModuleKind);
1845 self.get_parent_link(new_parent,
1847 child_name_bindings.define_module(
1855 child_name_bindings.
1860 // Add each static method to the module.
1862 ModuleReducedGraphParent(type_module);
1863 for static_method_info in
1864 static_methods.iter() {
1865 let ident = static_method_info.ident;
1866 debug!("(building reduced graph for \
1867 external crate) creating \
1868 static method '{}'",
1869 token::get_ident(ident));
1871 let (method_name_bindings, _) =
1872 self.add_child(ident,
1874 OverwriteDuplicates,
1877 static_method_info.def_id,
1878 static_method_info.purity);
1880 method_name_bindings.define_value(
1882 visibility == ast::Public);
1886 // Otherwise, do nothing.
1887 Some(_) | None => {}
1893 debug!("(building reduced graph for external crate) \
1899 /// Builds the reduced graph rooted at the given external module.
1900 fn populate_external_module(&mut self, module: @Module) {
1901 debug!("(populating external module) attempting to populate {}",
1902 self.module_to_str(module));
1904 let def_id = match module.def_id.get() {
1906 debug!("(populating external module) ... no def ID!");
1909 Some(def_id) => def_id,
1912 csearch::each_child_of_item(&self.session.cstore,
1914 |def_like, child_ident, visibility| {
1915 debug!("(populating external module) ... found ident: {}",
1916 token::get_ident(child_ident));
1917 self.build_reduced_graph_for_external_crate_def(module,
1922 module.populated.set(true)
1925 /// Ensures that the reduced graph rooted at the given external module
1926 /// is built, building it if it is not.
1927 fn populate_module_if_necessary(&mut self, module: @Module) {
1928 if !module.populated.get() {
1929 self.populate_external_module(module)
1931 assert!(module.populated.get())
1934 /// Builds the reduced graph rooted at the 'use' directive for an external
1936 fn build_reduced_graph_for_external_crate(&mut self,
1938 csearch::each_top_level_item_of_crate(&self.session.cstore,
1943 |def_like, ident, visibility| {
1944 self.build_reduced_graph_for_external_crate_def(root,
1951 /// Creates and adds an import directive to the given module.
1952 fn build_import_directive(&mut self,
1954 module_path: Vec<Ident> ,
1955 subclass: @ImportDirectiveSubclass,
1959 let directive = @ImportDirective::new(module_path,
1964 let mut imports = module_.imports.borrow_mut();
1965 imports.get().push(directive);
1968 // Bump the reference count on the name. Or, if this is a glob, set
1969 // the appropriate flag.
1972 SingleImport(target, _) => {
1973 debug!("(building import directive) building import \
1975 self.idents_to_str(directive.module_path.as_slice()),
1976 token::get_ident(target));
1978 let mut import_resolutions = module_.import_resolutions
1980 match import_resolutions.get().find(&target.name) {
1981 Some(&resolution) => {
1982 debug!("(building import directive) bumping \
1984 resolution.outstanding_references.set(
1985 resolution.outstanding_references.get() + 1);
1987 // the source of this name is different now
1988 resolution.type_id.set(id);
1989 resolution.value_id.set(id);
1992 debug!("(building import directive) creating new");
1993 let resolution = @ImportResolution::new(id, is_public);
1994 resolution.outstanding_references.set(1);
1995 import_resolutions.get().insert(target.name,
2001 // Set the glob flag. This tells us that we don't know the
2002 // module's exports ahead of time.
2004 module_.glob_count.set(module_.glob_count.get() + 1);
2008 self.unresolved_imports += 1;
2011 // Import resolution
2013 // This is a fixed-point algorithm. We resolve imports until our efforts
2014 // are stymied by an unresolved import; then we bail out of the current
2015 // module and continue. We terminate successfully once no more imports
2016 // remain or unsuccessfully when no forward progress in resolving imports
2019 /// Resolves all imports for the crate. This method performs the fixed-
2020 /// point iteration.
2021 fn resolve_imports(&mut self) {
2023 let mut prev_unresolved_imports = 0;
2025 debug!("(resolving imports) iteration {}, {} imports left",
2026 i, self.unresolved_imports);
2028 let module_root = self.graph_root.get_module();
2029 self.resolve_imports_for_module_subtree(module_root);
2031 if self.unresolved_imports == 0 {
2032 debug!("(resolving imports) success");
2036 if self.unresolved_imports == prev_unresolved_imports {
2037 self.report_unresolved_imports(module_root);
2042 prev_unresolved_imports = self.unresolved_imports;
2046 /// Attempts to resolve imports for the given module and all of its
2048 fn resolve_imports_for_module_subtree(&mut self,
2050 debug!("(resolving imports for module subtree) resolving {}",
2051 self.module_to_str(module_));
2052 self.resolve_imports_for_module(module_);
2054 self.populate_module_if_necessary(module_);
2056 let children = module_.children.borrow();
2057 for (_, &child_node) in children.get().iter() {
2058 match child_node.get_module_if_available() {
2062 Some(child_module) => {
2063 self.resolve_imports_for_module_subtree(child_module);
2069 let anonymous_children = module_.anonymous_children.borrow();
2070 for (_, &child_module) in anonymous_children.get().iter() {
2071 self.resolve_imports_for_module_subtree(child_module);
2075 /// Attempts to resolve imports for the given module only.
2076 fn resolve_imports_for_module(&mut self, module: @Module) {
2077 if module.all_imports_resolved() {
2078 debug!("(resolving imports for module) all imports resolved for \
2080 self.module_to_str(module));
2084 let mut imports = module.imports.borrow_mut();
2085 let import_count = imports.get().len();
2086 while module.resolved_import_count.get() < import_count {
2087 let import_index = module.resolved_import_count.get();
2088 let import_directive = *imports.get().get(import_index);
2089 match self.resolve_import_for_module(module, import_directive) {
2091 // We presumably emitted an error. Continue.
2092 let msg = format!("failed to resolve import `{}`",
2093 self.import_path_to_str(
2094 import_directive.module_path
2096 *import_directive.subclass));
2097 self.resolve_error(import_directive.span, msg);
2100 // Bail out. We'll come around next time.
2108 module.resolved_import_count
2109 .set(module.resolved_import_count.get() + 1);
2113 fn idents_to_str(&mut self, idents: &[Ident]) -> ~str {
2114 let mut first = true;
2115 let mut result = ~"";
2116 for ident in idents.iter() {
2120 result.push_str("::")
2122 result.push_str(token::get_ident(*ident).get());
2127 fn path_idents_to_str(&mut self, path: &Path) -> ~str {
2128 let identifiers: Vec<ast::Ident> = path.segments
2130 .map(|seg| seg.identifier)
2132 self.idents_to_str(identifiers.as_slice())
2135 fn import_directive_subclass_to_str(&mut self,
2136 subclass: ImportDirectiveSubclass)
2139 SingleImport(_, source) => {
2140 token::get_ident(source).get().to_str()
2146 fn import_path_to_str(&mut self,
2148 subclass: ImportDirectiveSubclass)
2150 if idents.is_empty() {
2151 self.import_directive_subclass_to_str(subclass)
2154 self.idents_to_str(idents),
2155 self.import_directive_subclass_to_str(subclass)))
2159 /// Attempts to resolve the given import. The return value indicates
2160 /// failure if we're certain the name does not exist, indeterminate if we
2161 /// don't know whether the name exists at the moment due to other
2162 /// currently-unresolved imports, or success if we know the name exists.
2163 /// If successful, the resolved bindings are written into the module.
2164 fn resolve_import_for_module(&mut self,
2166 import_directive: @ImportDirective)
2167 -> ResolveResult<()> {
2168 let mut resolution_result = Failed;
2169 let module_path = &import_directive.module_path;
2171 debug!("(resolving import for module) resolving import `{}::...` in \
2173 self.idents_to_str(module_path.as_slice()),
2174 self.module_to_str(module_));
2176 // First, resolve the module path for the directive, if necessary.
2177 let container = if module_path.len() == 0 {
2178 // Use the crate root.
2179 Some((self.graph_root.get_module(), LastMod(AllPublic)))
2181 match self.resolve_module_path(module_,
2182 module_path.as_slice(),
2183 DontUseLexicalScope,
2184 import_directive.span,
2189 resolution_result = Indeterminate;
2192 Success(container) => Some(container),
2198 Some((containing_module, lp)) => {
2199 // We found the module that the target is contained
2200 // within. Attempt to resolve the import within it.
2202 match *import_directive.subclass {
2203 SingleImport(target, source) => {
2205 self.resolve_single_import(module_,
2214 self.resolve_glob_import(module_,
2216 import_directive.id,
2217 import_directive.is_public,
2224 // Decrement the count of unresolved imports.
2225 match resolution_result {
2227 assert!(self.unresolved_imports >= 1);
2228 self.unresolved_imports -= 1;
2231 // Nothing to do here; just return the error.
2235 // Decrement the count of unresolved globs if necessary. But only if
2236 // the resolution result is indeterminate -- otherwise we'll stop
2237 // processing imports here. (See the loop in
2238 // resolve_imports_for_module.)
2240 if !resolution_result.indeterminate() {
2241 match *import_directive.subclass {
2243 assert!(module_.glob_count.get() >= 1);
2244 module_.glob_count.set(module_.glob_count.get() - 1);
2246 SingleImport(..) => {
2252 return resolution_result;
2255 fn create_name_bindings_from_module(module: @Module) -> NameBindings {
2257 type_def: RefCell::new(Some(TypeNsDef {
2259 module_def: Some(module),
2263 value_def: RefCell::new(None),
2267 fn resolve_single_import(&mut self,
2269 containing_module: @Module,
2272 directive: &ImportDirective,
2274 -> ResolveResult<()> {
2275 debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2276 `{}` id {}, last private {:?}",
2277 token::get_ident(target),
2278 self.module_to_str(containing_module),
2279 token::get_ident(source),
2280 self.module_to_str(module_),
2286 LastImport{..} => self.session.span_bug(directive.span,
2287 "Not expecting Import here, must be LastMod"),
2290 // We need to resolve both namespaces for this to succeed.
2293 let mut value_result = UnknownResult;
2294 let mut type_result = UnknownResult;
2296 // Search for direct children of the containing module.
2297 self.populate_module_if_necessary(containing_module);
2300 let children = containing_module.children.borrow();
2301 match children.get().find(&source.name) {
2305 Some(child_name_bindings) => {
2306 if child_name_bindings.defined_in_namespace(ValueNS) {
2307 value_result = BoundResult(containing_module,
2308 *child_name_bindings);
2310 if child_name_bindings.defined_in_namespace(TypeNS) {
2311 type_result = BoundResult(containing_module,
2312 *child_name_bindings);
2318 // Unless we managed to find a result in both namespaces (unlikely),
2319 // search imports as well.
2320 let mut value_used_reexport = false;
2321 let mut type_used_reexport = false;
2322 match (value_result, type_result) {
2323 (BoundResult(..), BoundResult(..)) => {} // Continue.
2325 // If there is an unresolved glob at this point in the
2326 // containing module, bail out. We don't know enough to be
2327 // able to resolve this import.
2329 if containing_module.glob_count.get() > 0 {
2330 debug!("(resolving single import) unresolved glob; \
2332 return Indeterminate;
2335 // Now search the exported imports within the containing
2338 let import_resolutions = containing_module.import_resolutions
2340 match import_resolutions.get().find(&source.name) {
2342 // The containing module definitely doesn't have an
2343 // exported import with the name in question. We can
2344 // therefore accurately report that the names are
2347 if value_result.is_unknown() {
2348 value_result = UnboundResult;
2350 if type_result.is_unknown() {
2351 type_result = UnboundResult;
2354 Some(import_resolution)
2355 if import_resolution.outstanding_references.get()
2358 fn get_binding(this: &mut Resolver,
2359 import_resolution: @ImportResolution,
2360 namespace: Namespace)
2361 -> NamespaceResult {
2363 // Import resolutions must be declared with "pub"
2364 // in order to be exported.
2365 if !import_resolution.is_public.get() {
2366 return UnboundResult;
2369 match (*import_resolution).
2370 target_for_namespace(namespace) {
2372 return UnboundResult;
2375 let id = import_resolution.id(namespace);
2376 this.used_imports.insert((id, namespace));
2377 return BoundResult(target.target_module,
2383 // The name is an import which has been fully
2384 // resolved. We can, therefore, just follow it.
2385 if value_result.is_unknown() {
2386 value_result = get_binding(self, *import_resolution,
2388 value_used_reexport = import_resolution.is_public.get();
2390 if type_result.is_unknown() {
2391 type_result = get_binding(self, *import_resolution,
2393 type_used_reexport = import_resolution.is_public.get();
2398 // The import is unresolved. Bail out.
2399 debug!("(resolving single import) unresolved import; \
2401 return Indeterminate;
2407 // If we didn't find a result in the type namespace, search the
2408 // external modules.
2409 let mut value_used_public = false;
2410 let mut type_used_public = false;
2412 BoundResult(..) => {}
2415 let mut external_module_children =
2416 containing_module.external_module_children
2418 external_module_children.get().find_copy(&source.name)
2421 None => {} // Continue.
2424 @Resolver::create_name_bindings_from_module(
2426 type_result = BoundResult(containing_module,
2428 type_used_public = true;
2434 // We've successfully resolved the import. Write the results in.
2435 let import_resolution = {
2436 let import_resolutions = module_.import_resolutions.borrow();
2437 assert!(import_resolutions.get().contains_key(&target.name));
2438 import_resolutions.get().get_copy(&target.name)
2441 match value_result {
2442 BoundResult(target_module, name_bindings) => {
2443 debug!("(resolving single import) found value target");
2444 import_resolution.value_target.set(
2445 Some(Target::new(target_module, name_bindings)));
2446 import_resolution.value_id.set(directive.id);
2447 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2449 UnboundResult => { /* Continue. */ }
2451 fail!("value result should be known at this point");
2455 BoundResult(target_module, name_bindings) => {
2456 debug!("(resolving single import) found type target: {:?}",
2457 {name_bindings.type_def.get().unwrap().type_def});
2458 import_resolution.type_target.set(
2459 Some(Target::new(target_module, name_bindings)));
2460 import_resolution.type_id.set(directive.id);
2461 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2463 UnboundResult => { /* Continue. */ }
2465 fail!("type result should be known at this point");
2469 if import_resolution.value_target.get().is_none() &&
2470 import_resolution.type_target.get().is_none() {
2471 let msg = format!("unresolved import: there is no \
2473 token::get_ident(source),
2474 self.module_to_str(containing_module));
2475 self.resolve_error(directive.span, msg);
2478 let value_used_public = value_used_reexport || value_used_public;
2479 let type_used_public = type_used_reexport || type_used_public;
2481 assert!(import_resolution.outstanding_references.get() >= 1);
2482 import_resolution.outstanding_references.set(
2483 import_resolution.outstanding_references.get() - 1);
2485 // record what this import resolves to for later uses in documentation,
2486 // this may resolve to either a value or a type, but for documentation
2487 // purposes it's good enough to just favor one over the other.
2488 let value_private = match import_resolution.value_target.get() {
2490 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2491 let mut def_map = self.def_map.borrow_mut();
2492 def_map.get().insert(directive.id, def);
2493 let did = def_id_of_def(def);
2494 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2496 // AllPublic here and below is a dummy value, it should never be used because
2497 // _exists is false.
2500 let type_private = match import_resolution.type_target.get() {
2502 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2503 let mut def_map = self.def_map.borrow_mut();
2504 def_map.get().insert(directive.id, def);
2505 let did = def_id_of_def(def);
2506 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2511 self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2513 type_priv: type_private,
2516 debug!("(resolving single import) successfully resolved import");
2520 // Resolves a glob import. Note that this function cannot fail; it either
2521 // succeeds or bails out (as importing * from an empty module or a module
2522 // that exports nothing is valid).
2523 fn resolve_glob_import(&mut self,
2525 containing_module: @Module,
2529 -> ResolveResult<()> {
2530 // This function works in a highly imperative manner; it eagerly adds
2531 // everything it can to the list of import resolutions of the module
2533 debug!("(resolving glob import) resolving glob import {}", id);
2535 // We must bail out if the node has unresolved imports of any kind
2536 // (including globs).
2537 if !(*containing_module).all_imports_resolved() {
2538 debug!("(resolving glob import) target module has unresolved \
2539 imports; bailing out");
2540 return Indeterminate;
2543 assert_eq!(containing_module.glob_count.get(), 0);
2545 // Add all resolved imports from the containing module.
2546 let import_resolutions = containing_module.import_resolutions
2548 for (ident, target_import_resolution) in import_resolutions.get()
2550 debug!("(resolving glob import) writing module resolution \
2552 target_import_resolution.type_target.get().is_none(),
2553 self.module_to_str(module_));
2555 if !target_import_resolution.is_public.get() {
2556 debug!("(resolving glob import) nevermind, just kidding");
2560 // Here we merge two import resolutions.
2561 let mut import_resolutions = module_.import_resolutions
2563 match import_resolutions.get().find(ident) {
2565 // Simple: just copy the old import resolution.
2566 let new_import_resolution =
2567 @ImportResolution::new(id, is_public);
2568 new_import_resolution.value_target.set(
2569 target_import_resolution.value_target.get());
2570 new_import_resolution.type_target.set(
2571 target_import_resolution.type_target.get());
2573 import_resolutions.get().insert
2574 (*ident, new_import_resolution);
2576 Some(&dest_import_resolution) => {
2577 // Merge the two import resolutions at a finer-grained
2580 match target_import_resolution.value_target.get() {
2584 Some(value_target) => {
2585 dest_import_resolution.value_target.set(
2586 Some(value_target));
2589 match target_import_resolution.type_target.get() {
2593 Some(type_target) => {
2594 dest_import_resolution.type_target.set(
2598 dest_import_resolution.is_public.set(is_public);
2603 // Add all children from the containing module.
2604 self.populate_module_if_necessary(containing_module);
2607 let children = containing_module.children.borrow();
2608 for (&name, name_bindings) in children.get().iter() {
2609 self.merge_import_resolution(module_, containing_module,
2611 name, *name_bindings);
2615 // Add external module children from the containing module.
2617 let external_module_children =
2618 containing_module.external_module_children.borrow();
2619 for (&name, module) in external_module_children.get().iter() {
2621 @Resolver::create_name_bindings_from_module(*module);
2622 self.merge_import_resolution(module_, containing_module,
2624 name, name_bindings);
2628 // Record the destination of this import
2629 match containing_module.def_id.get() {
2631 let mut def_map = self.def_map.borrow_mut();
2632 def_map.get().insert(id, DefMod(did));
2633 self.last_private.insert(id, lp);
2638 debug!("(resolving glob import) successfully resolved import");
2642 fn merge_import_resolution(&mut self,
2644 containing_module: @Module,
2648 name_bindings: @NameBindings) {
2649 let dest_import_resolution;
2650 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2651 match import_resolutions.get().find(&name) {
2653 // Create a new import resolution from this child.
2654 dest_import_resolution =
2655 @ImportResolution::new(id, is_public);
2656 import_resolutions.get().insert(name,
2657 dest_import_resolution);
2659 Some(&existing_import_resolution) => {
2660 dest_import_resolution = existing_import_resolution;
2664 debug!("(resolving glob import) writing resolution `{}` in `{}` \
2666 token::get_name(name).get().to_str(),
2667 self.module_to_str(containing_module),
2668 self.module_to_str(module_));
2670 // Merge the child item into the import resolution.
2671 if name_bindings.defined_in_public_namespace(ValueNS) {
2672 debug!("(resolving glob import) ... for value target");
2673 dest_import_resolution.value_target.set(
2674 Some(Target::new(containing_module, name_bindings)));
2675 dest_import_resolution.value_id.set(id);
2677 if name_bindings.defined_in_public_namespace(TypeNS) {
2678 debug!("(resolving glob import) ... for type target");
2679 dest_import_resolution.type_target.set(
2680 Some(Target::new(containing_module, name_bindings)));
2681 dest_import_resolution.type_id.set(id);
2683 dest_import_resolution.is_public.set(is_public);
2686 /// Resolves the given module path from the given root `module_`.
2687 fn resolve_module_path_from_root(&mut self,
2689 module_path: &[Ident],
2692 name_search_type: NameSearchType,
2694 -> ResolveResult<(@Module, LastPrivate)> {
2695 let mut search_module = module_;
2696 let mut index = index;
2697 let module_path_len = module_path.len();
2698 let mut closest_private = lp;
2700 // Resolve the module part of the path. This does not involve looking
2701 // upward though scope chains; we simply resolve names directly in
2702 // modules as we go.
2703 while index < module_path_len {
2704 let name = module_path[index];
2705 match self.resolve_name_in_module(search_module,
2710 let segment_name = token::get_ident(name);
2711 let module_name = self.module_to_str(search_module);
2712 if "???" == module_name {
2715 hi: span.lo + Pos::from_uint(segment_name.get().len()),
2716 expn_info: span.expn_info,
2718 self.resolve_error(span,
2719 format!("unresolved import. maybe \
2720 a missing `extern crate \
2725 self.resolve_error(span, format!("unresolved import: could not find `{}` in \
2726 `{}`.", segment_name, module_name));
2730 debug!("(resolving module path for import) module \
2731 resolution is indeterminate: {}",
2732 token::get_ident(name));
2733 return Indeterminate;
2735 Success((target, used_proxy)) => {
2736 // Check to see whether there are type bindings, and, if
2737 // so, whether there is a module within.
2738 match target.bindings.type_def.get() {
2740 match type_def.module_def {
2743 self.resolve_error(span, format!("not a module `{}`",
2744 token::get_ident(name)));
2747 Some(module_def) => {
2748 // If we're doing the search for an
2749 // import, do not allow traits and impls
2751 match (name_search_type,
2752 module_def.kind.get()) {
2753 (ImportSearch, TraitModuleKind) |
2754 (ImportSearch, ImplModuleKind) => {
2757 "cannot import from a trait \
2758 or type implementation");
2762 search_module = module_def;
2764 // Keep track of the closest
2765 // private module used when
2766 // resolving this import chain.
2768 !search_module.is_public {
2769 match search_module.def_id
2773 LastMod(DependsOn(did));
2784 // There are no type bindings at all.
2785 self.resolve_error(span,
2786 format!("not a module `{}`",
2787 token::get_ident(name)));
2797 return Success((search_module, closest_private));
2800 /// Attempts to resolve the module part of an import directive or path
2801 /// rooted at the given module.
2803 /// On success, returns the resolved module, and the closest *private*
2804 /// module found to the destination when resolving this path.
2805 fn resolve_module_path(&mut self,
2807 module_path: &[Ident],
2808 use_lexical_scope: UseLexicalScopeFlag,
2810 name_search_type: NameSearchType)
2811 -> ResolveResult<(@Module, LastPrivate)> {
2812 let module_path_len = module_path.len();
2813 assert!(module_path_len > 0);
2815 debug!("(resolving module path for import) processing `{}` rooted at \
2817 self.idents_to_str(module_path),
2818 self.module_to_str(module_));
2820 // Resolve the module prefix, if any.
2821 let module_prefix_result = self.resolve_module_prefix(module_,
2827 match module_prefix_result {
2829 let mpath = self.idents_to_str(module_path);
2830 match mpath.rfind(':') {
2832 self.resolve_error(span, format!("unresolved import: could not find `{}` \
2834 // idx +- 1 to account for the colons
2836 mpath.slice_from(idx + 1),
2837 mpath.slice_to(idx - 1)));
2844 debug!("(resolving module path for import) indeterminate; \
2846 return Indeterminate;
2848 Success(NoPrefixFound) => {
2849 // There was no prefix, so we're considering the first element
2850 // of the path. How we handle this depends on whether we were
2851 // instructed to use lexical scope or not.
2852 match use_lexical_scope {
2853 DontUseLexicalScope => {
2854 // This is a crate-relative path. We will start the
2855 // resolution process at index zero.
2856 search_module = self.graph_root.get_module();
2858 last_private = LastMod(AllPublic);
2860 UseLexicalScope => {
2861 // This is not a crate-relative path. We resolve the
2862 // first component of the path in the current lexical
2863 // scope and then proceed to resolve below that.
2864 let result = self.resolve_module_in_lexical_scope(
2869 self.resolve_error(span, "unresolved name");
2873 debug!("(resolving module path for import) \
2874 indeterminate; bailing");
2875 return Indeterminate;
2877 Success(containing_module) => {
2878 search_module = containing_module;
2880 last_private = LastMod(AllPublic);
2886 Success(PrefixFound(containing_module, index)) => {
2887 search_module = containing_module;
2888 start_index = index;
2889 last_private = LastMod(DependsOn(containing_module.def_id
2895 self.resolve_module_path_from_root(search_module,
2903 /// Invariant: This must only be called during main resolution, not during
2904 /// import resolution.
2905 fn resolve_item_in_lexical_scope(&mut self,
2908 namespace: Namespace,
2909 search_through_modules:
2910 SearchThroughModulesFlag)
2911 -> ResolveResult<(Target, bool)> {
2912 debug!("(resolving item in lexical scope) resolving `{}` in \
2913 namespace {:?} in `{}`",
2914 token::get_ident(name),
2916 self.module_to_str(module_));
2918 // The current module node is handled specially. First, check for
2919 // its immediate children.
2920 self.populate_module_if_necessary(module_);
2923 let children = module_.children.borrow();
2924 match children.get().find(&name.name) {
2926 if name_bindings.defined_in_namespace(namespace) => {
2927 debug!("top name bindings succeeded");
2928 return Success((Target::new(module_, *name_bindings),
2931 Some(_) | None => { /* Not found; continue. */ }
2935 // Now check for its import directives. We don't have to have resolved
2936 // all its imports in the usual way; this is because chains of
2937 // adjacent import statements are processed as though they mutated the
2939 let import_resolutions = module_.import_resolutions.borrow();
2940 match import_resolutions.get().find(&name.name) {
2942 // Not found; continue.
2944 Some(import_resolution) => {
2945 match (*import_resolution).target_for_namespace(namespace) {
2947 // Not found; continue.
2948 debug!("(resolving item in lexical scope) found \
2949 import resolution, but not in namespace {:?}",
2953 debug!("(resolving item in lexical scope) using \
2954 import resolution");
2955 self.used_imports.insert((import_resolution.id(namespace), namespace));
2956 return Success((target, false));
2962 // Search for external modules.
2963 if namespace == TypeNS {
2965 let external_module_children =
2966 module_.external_module_children.borrow();
2967 external_module_children.get().find_copy(&name.name)
2973 @Resolver::create_name_bindings_from_module(module);
2974 debug!("lower name bindings succeeded");
2975 return Success((Target::new(module_, name_bindings), false));
2980 // Finally, proceed up the scope chain looking for parent modules.
2981 let mut search_module = module_;
2983 // Go to the next parent.
2984 match search_module.parent_link {
2986 // No more parents. This module was unresolved.
2987 debug!("(resolving item in lexical scope) unresolved \
2991 ModuleParentLink(parent_module_node, _) => {
2992 match search_through_modules {
2993 DontSearchThroughModules => {
2994 match search_module.kind.get() {
2995 NormalModuleKind => {
2996 // We stop the search here.
2997 debug!("(resolving item in lexical \
2998 scope) unresolved module: not \
2999 searching through module \
3006 AnonymousModuleKind => {
3007 search_module = parent_module_node;
3011 SearchThroughModules => {
3012 search_module = parent_module_node;
3016 BlockParentLink(parent_module_node, _) => {
3017 search_module = parent_module_node;
3021 // Resolve the name in the parent module.
3022 match self.resolve_name_in_module(search_module,
3027 // Continue up the search chain.
3030 // We couldn't see through the higher scope because of an
3031 // unresolved import higher up. Bail.
3033 debug!("(resolving item in lexical scope) indeterminate \
3034 higher scope; bailing");
3035 return Indeterminate;
3037 Success((target, used_reexport)) => {
3038 // We found the module.
3039 debug!("(resolving item in lexical scope) found name \
3041 return Success((target, used_reexport));
3047 /// Resolves a module name in the current lexical scope.
3048 fn resolve_module_in_lexical_scope(&mut self,
3051 -> ResolveResult<@Module> {
3052 // If this module is an anonymous module, resolve the item in the
3053 // lexical scope. Otherwise, resolve the item from the crate root.
3054 let resolve_result = self.resolve_item_in_lexical_scope(
3055 module_, name, TypeNS, DontSearchThroughModules);
3056 match resolve_result {
3057 Success((target, _)) => {
3058 let bindings = &*target.bindings;
3059 match bindings.type_def.get() {
3061 match type_def.module_def {
3063 error!("!!! (resolving module in lexical \
3064 scope) module wasn't actually a \
3068 Some(module_def) => {
3069 return Success(module_def);
3074 error!("!!! (resolving module in lexical scope) module
3075 wasn't actually a module!");
3081 debug!("(resolving module in lexical scope) indeterminate; \
3083 return Indeterminate;
3086 debug!("(resolving module in lexical scope) failed to \
3093 /// Returns the nearest normal module parent of the given module.
3094 fn get_nearest_normal_module_parent(&mut self, module_: @Module)
3095 -> Option<@Module> {
3096 let mut module_ = module_;
3098 match module_.parent_link {
3099 NoParentLink => return None,
3100 ModuleParentLink(new_module, _) |
3101 BlockParentLink(new_module, _) => {
3102 match new_module.kind.get() {
3103 NormalModuleKind => return Some(new_module),
3107 AnonymousModuleKind => module_ = new_module,
3114 /// Returns the nearest normal module parent of the given module, or the
3115 /// module itself if it is a normal module.
3116 fn get_nearest_normal_module_parent_or_self(&mut self, module_: @Module)
3118 match module_.kind.get() {
3119 NormalModuleKind => return module_,
3123 AnonymousModuleKind => {
3124 match self.get_nearest_normal_module_parent(module_) {
3126 Some(new_module) => new_module
3132 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3133 /// (b) some chain of `super::`.
3134 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3135 fn resolve_module_prefix(&mut self,
3137 module_path: &[Ident])
3138 -> ResolveResult<ModulePrefixResult> {
3139 // Start at the current module if we see `self` or `super`, or at the
3140 // top of the crate otherwise.
3141 let mut containing_module;
3143 let first_module_path_string = token::get_ident(module_path[0]);
3144 if "self" == first_module_path_string.get() {
3146 self.get_nearest_normal_module_parent_or_self(module_);
3148 } else if "super" == first_module_path_string.get() {
3150 self.get_nearest_normal_module_parent_or_self(module_);
3151 i = 0; // We'll handle `super` below.
3153 return Success(NoPrefixFound);
3156 // Now loop through all the `super`s we find.
3157 while i < module_path.len() {
3158 let string = token::get_ident(module_path[i]);
3159 if "super" != string.get() {
3162 debug!("(resolving module prefix) resolving `super` at {}",
3163 self.module_to_str(containing_module));
3164 match self.get_nearest_normal_module_parent(containing_module) {
3165 None => return Failed,
3166 Some(new_module) => {
3167 containing_module = new_module;
3173 debug!("(resolving module prefix) finished resolving prefix at {}",
3174 self.module_to_str(containing_module));
3176 return Success(PrefixFound(containing_module, i));
3179 /// Attempts to resolve the supplied name in the given module for the
3180 /// given namespace. If successful, returns the target corresponding to
3183 /// The boolean returned on success is an indicator of whether this lookup
3184 /// passed through a public re-export proxy.
3185 fn resolve_name_in_module(&mut self,
3188 namespace: Namespace,
3189 name_search_type: NameSearchType)
3190 -> ResolveResult<(Target, bool)> {
3191 debug!("(resolving name in module) resolving `{}` in `{}`",
3192 token::get_ident(name),
3193 self.module_to_str(module_));
3195 // First, check the direct children of the module.
3196 self.populate_module_if_necessary(module_);
3199 let children = module_.children.borrow();
3200 match children.get().find(&name.name) {
3202 if name_bindings.defined_in_namespace(namespace) => {
3203 debug!("(resolving name in module) found node as child");
3204 return Success((Target::new(module_, *name_bindings),
3213 // Next, check the module's imports if necessary.
3215 // If this is a search of all imports, we should be done with glob
3216 // resolution at this point.
3217 if name_search_type == PathSearch {
3218 assert_eq!(module_.glob_count.get(), 0);
3221 // Check the list of resolved imports.
3222 let import_resolutions = module_.import_resolutions.borrow();
3223 match import_resolutions.get().find(&name.name) {
3224 Some(import_resolution) => {
3225 if import_resolution.is_public.get() &&
3226 import_resolution.outstanding_references.get() != 0 {
3227 debug!("(resolving name in module) import \
3228 unresolved; bailing out");
3229 return Indeterminate;
3231 match import_resolution.target_for_namespace(namespace) {
3233 debug!("(resolving name in module) name found, \
3234 but not in namespace {:?}",
3238 debug!("(resolving name in module) resolved to \
3240 self.used_imports.insert((import_resolution.id(namespace), namespace));
3241 return Success((target, true));
3245 None => {} // Continue.
3248 // Finally, search through external children.
3249 if namespace == TypeNS {
3251 let external_module_children =
3252 module_.external_module_children.borrow();
3253 external_module_children.get().find_copy(&name.name)
3259 @Resolver::create_name_bindings_from_module(module);
3260 return Success((Target::new(module_, name_bindings), false));
3265 // We're out of luck.
3266 debug!("(resolving name in module) failed to resolve `{}`",
3267 token::get_ident(name));
3271 fn report_unresolved_imports(&mut self, module_: @Module) {
3272 let index = module_.resolved_import_count.get();
3273 let mut imports = module_.imports.borrow_mut();
3274 let import_count = imports.get().len();
3275 if index != import_count {
3276 let sn = self.session
3278 .span_to_snippet(imports.get().get(index).span)
3280 if sn.contains("::") {
3281 self.resolve_error(imports.get().get(index).span,
3282 "unresolved import");
3284 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3285 sn.slice(0, sn.len()));
3286 self.resolve_error(imports.get().get(index).span, err);
3290 // Descend into children and anonymous children.
3291 self.populate_module_if_necessary(module_);
3294 let children = module_.children.borrow();
3295 for (_, &child_node) in children.get().iter() {
3296 match child_node.get_module_if_available() {
3300 Some(child_module) => {
3301 self.report_unresolved_imports(child_module);
3307 let anonymous_children = module_.anonymous_children.borrow();
3308 for (_, &module_) in anonymous_children.get().iter() {
3309 self.report_unresolved_imports(module_);
3315 // This pass simply determines what all "export" keywords refer to and
3316 // writes the results into the export map.
3318 // FIXME #4953 This pass will be removed once exports change to per-item.
3319 // Then this operation can simply be performed as part of item (or import)
3322 fn record_exports(&mut self) {
3323 let root_module = self.graph_root.get_module();
3324 self.record_exports_for_module_subtree(root_module);
3327 fn record_exports_for_module_subtree(&mut self,
3329 // If this isn't a local krate, then bail out. We don't need to record
3330 // exports for nonlocal crates.
3332 match module_.def_id.get() {
3333 Some(def_id) if def_id.krate == LOCAL_CRATE => {
3335 debug!("(recording exports for module subtree) recording \
3336 exports for local module `{}`",
3337 self.module_to_str(module_));
3340 // Record exports for the root module.
3341 debug!("(recording exports for module subtree) recording \
3342 exports for root module `{}`",
3343 self.module_to_str(module_));
3347 debug!("(recording exports for module subtree) not recording \
3349 self.module_to_str(module_));
3354 self.record_exports_for_module(module_);
3355 self.populate_module_if_necessary(module_);
3358 let children = module_.children.borrow();
3359 for (_, &child_name_bindings) in children.get().iter() {
3360 match child_name_bindings.get_module_if_available() {
3364 Some(child_module) => {
3365 self.record_exports_for_module_subtree(child_module);
3371 let anonymous_children = module_.anonymous_children.borrow();
3372 for (_, &child_module) in anonymous_children.get().iter() {
3373 self.record_exports_for_module_subtree(child_module);
3377 fn record_exports_for_module(&mut self, module_: @Module) {
3378 let mut exports2 = Vec::new();
3380 self.add_exports_for_module(&mut exports2, module_);
3381 match module_.def_id.get() {
3383 let mut export_map2 = self.export_map2.borrow_mut();
3384 export_map2.get().insert(def_id.node, exports2);
3385 debug!("(computing exports) writing exports for {} (some)",
3392 fn add_exports_of_namebindings(&mut self,
3393 exports2: &mut Vec<Export2> ,
3395 namebindings: @NameBindings,
3397 match namebindings.def_for_namespace(ns) {
3399 let name = token::get_name(name);
3400 debug!("(computing exports) YES: export '{}' => {:?}",
3401 name, def_id_of_def(d));
3402 exports2.push(Export2 {
3403 name: name.get().to_str(),
3404 def_id: def_id_of_def(d)
3408 debug!("(computing exports) NO: {:?}", d_opt);
3413 fn add_exports_for_module(&mut self,
3414 exports2: &mut Vec<Export2> ,
3416 let import_resolutions = module_.import_resolutions.borrow();
3417 for (name, importresolution) in import_resolutions.get().iter() {
3418 if !importresolution.is_public.get() {
3421 let xs = [TypeNS, ValueNS];
3422 for &ns in xs.iter() {
3423 match importresolution.target_for_namespace(ns) {
3425 debug!("(computing exports) maybe export '{}'",
3426 token::get_name(*name));
3427 self.add_exports_of_namebindings(exports2,
3440 // We maintain a list of value ribs and type ribs.
3442 // Simultaneously, we keep track of the current position in the module
3443 // graph in the `current_module` pointer. When we go to resolve a name in
3444 // the value or type namespaces, we first look through all the ribs and
3445 // then query the module graph. When we resolve a name in the module
3446 // namespace, we can skip all the ribs (since nested modules are not
3447 // allowed within blocks in Rust) and jump straight to the current module
3450 // Named implementations are handled separately. When we find a method
3451 // call, we consult the module node to find all of the implementations in
3452 // scope. This information is lazily cached in the module node. We then
3453 // generate a fake "implementation scope" containing all the
3454 // implementations thus found, for compatibility with old resolve pass.
3456 fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
3457 let orig_module = self.current_module;
3459 // Move down in the graph.
3465 self.populate_module_if_necessary(orig_module);
3467 let children = orig_module.children.borrow();
3468 match children.get().find(&name.name) {
3470 debug!("!!! (with scope) didn't find `{}` in `{}`",
3471 token::get_ident(name),
3472 self.module_to_str(orig_module));
3474 Some(name_bindings) => {
3475 match (*name_bindings).get_module_if_available() {
3477 debug!("!!! (with scope) didn't find module \
3479 token::get_ident(name),
3480 self.module_to_str(orig_module));
3483 self.current_module = module_;
3493 self.current_module = orig_module;
3496 /// Wraps the given definition in the appropriate number of `def_upvar`
3498 fn upvarify(&mut self,
3499 ribs: &mut Vec<@Rib> ,
3503 -> Option<DefLike> {
3508 DlDef(d @ DefLocal(..)) | DlDef(d @ DefUpvar(..)) |
3509 DlDef(d @ DefArg(..)) | DlDef(d @ DefBinding(..)) => {
3511 is_ty_param = false;
3513 DlDef(d @ DefTyParam(..)) => {
3518 return Some(def_like);
3522 let mut rib_index = rib_index + 1;
3523 while rib_index < ribs.len() {
3524 match ribs.get(rib_index).kind {
3526 // Nothing to do. Continue.
3528 FunctionRibKind(function_id, body_id) => {
3530 def = DefUpvar(def_id_of_def(def).node,
3536 MethodRibKind(item_id, _) => {
3537 // If the def is a ty param, and came from the parent
3540 DefTyParam(did, _) if {
3541 let def_map = self.def_map.borrow();
3542 def_map.get().find(&did.node).map(|x| *x)
3543 == Some(DefTyParamBinder(item_id))
3549 // This was an attempt to access an upvar inside a
3550 // named function item. This is not allowed, so we
3555 "can't capture dynamic environment in a fn item; \
3556 use the || { ... } closure form instead");
3558 // This was an attempt to use a type parameter outside
3561 self.resolve_error(span,
3562 "attempt to use a type \
3563 argument out of scope");
3570 OpaqueFunctionRibKind => {
3572 // This was an attempt to access an upvar inside a
3573 // named function item. This is not allowed, so we
3578 "can't capture dynamic environment in a fn item; \
3579 use the || { ... } closure form instead");
3581 // This was an attempt to use a type parameter outside
3584 self.resolve_error(span,
3585 "attempt to use a type \
3586 argument out of scope");
3591 ConstantItemRibKind => {
3594 self.resolve_error(span,
3595 "cannot use an outer type \
3596 parameter in this context");
3598 // Still doesn't deal with upvars
3599 self.resolve_error(span,
3600 "attempt to use a non-constant \
3601 value in a constant");
3610 return Some(DlDef(def));
3613 fn search_ribs(&mut self,
3614 ribs: &mut Vec<@Rib> ,
3617 -> Option<DefLike> {
3618 // FIXME #4950: This should not use a while loop.
3619 // FIXME #4950: Try caching?
3621 let mut i = ribs.len();
3625 let bindings = ribs.get(i).bindings.borrow();
3626 bindings.get().find_copy(&name)
3630 return self.upvarify(ribs, i, def_like, span);
3641 fn resolve_crate(&mut self, krate: &ast::Crate) {
3642 debug!("(resolving crate) starting");
3644 visit::walk_crate(self, krate, ());
3647 fn resolve_item(&mut self, item: &Item) {
3648 debug!("(resolving item) resolving {}",
3649 token::get_ident(item.ident));
3653 // enum item: resolve all the variants' discrs,
3654 // then resolve the ty params
3655 ItemEnum(ref enum_def, ref generics) => {
3656 for variant in (*enum_def).variants.iter() {
3657 for dis_expr in variant.node.disr_expr.iter() {
3658 // resolve the discriminator expr
3660 self.with_constant_rib(|this| {
3661 this.resolve_expr(*dis_expr);
3666 // n.b. the discr expr gets visted twice.
3667 // but maybe it's okay since the first time will signal an
3668 // error if there is one? -- tjc
3669 self.with_type_parameter_rib(HasTypeParameters(generics,
3674 visit::walk_item(this, item, ());
3678 ItemTy(_, ref generics) => {
3679 self.with_type_parameter_rib(HasTypeParameters(generics,
3684 visit::walk_item(this, item, ());
3688 ItemImpl(ref generics,
3689 ref implemented_traits,
3692 self.resolve_implementation(item.id,
3696 methods.as_slice());
3699 ItemTrait(ref generics, ref traits, ref methods) => {
3700 // Create a new rib for the self type.
3701 let self_type_rib = @Rib::new(NormalRibKind);
3703 let mut type_ribs = self.type_ribs.borrow_mut();
3704 type_ribs.get().push(self_type_rib);
3706 // plain insert (no renaming)
3707 let name = self.type_self_ident.name;
3709 let mut bindings = self_type_rib.bindings.borrow_mut();
3710 bindings.get().insert(name, DlDef(DefSelfTy(item.id)));
3713 // Create a new rib for the trait-wide type parameters.
3714 self.with_type_parameter_rib(HasTypeParameters(generics,
3719 this.resolve_type_parameters(&generics.ty_params);
3721 // Resolve derived traits.
3722 for trt in traits.iter() {
3723 this.resolve_trait_reference(item.id, trt, TraitDerivation);
3726 for method in (*methods).iter() {
3727 // Create a new rib for the method-specific type
3730 // FIXME #4951: Do we need a node ID here?
3733 ast::Required(ref ty_m) => {
3734 this.with_type_parameter_rib
3735 (HasTypeParameters(&ty_m.generics,
3737 generics.ty_params.len(),
3738 MethodRibKind(item.id, Required)),
3741 // Resolve the method-specific type
3743 this.resolve_type_parameters(
3744 &ty_m.generics.ty_params);
3746 for argument in ty_m.decl.inputs.iter() {
3747 this.resolve_type(argument.ty);
3750 this.resolve_type(ty_m.decl.output);
3753 ast::Provided(m) => {
3754 this.resolve_method(MethodRibKind(item.id,
3757 generics.ty_params.len())
3763 let mut type_ribs = self.type_ribs.borrow_mut();
3764 type_ribs.get().pop();
3767 ItemStruct(ref struct_def, ref generics) => {
3768 self.resolve_struct(item.id,
3770 struct_def.fields.as_slice());
3773 ItemMod(ref module_) => {
3774 self.with_scope(Some(item.ident), |this| {
3775 this.resolve_module(module_, item.span, item.ident,
3780 ItemForeignMod(ref foreign_module) => {
3781 self.with_scope(Some(item.ident), |this| {
3782 for foreign_item in foreign_module.items.iter() {
3783 match foreign_item.node {
3784 ForeignItemFn(_, ref generics) => {
3785 this.with_type_parameter_rib(
3787 generics, foreign_item.id, 0,
3789 |this| visit::walk_foreign_item(this,
3793 ForeignItemStatic(..) => {
3794 visit::walk_foreign_item(this,
3803 ItemFn(fn_decl, _, _, ref generics, block) => {
3804 self.resolve_function(OpaqueFunctionRibKind,
3810 OpaqueFunctionRibKind),
3815 self.with_constant_rib(|this| {
3816 visit::walk_item(this, item, ());
3821 // do nothing, these are just around to be encoded
3826 fn with_type_parameter_rib(&mut self,
3827 type_parameters: TypeParameters,
3828 f: |&mut Resolver|) {
3829 match type_parameters {
3830 HasTypeParameters(generics, node_id, initial_index,
3833 let function_type_rib = @Rib::new(rib_kind);
3835 let mut type_ribs = self.type_ribs.borrow_mut();
3836 type_ribs.get().push(function_type_rib);
3839 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
3840 let ident = type_parameter.ident;
3841 debug!("with_type_parameter_rib: {} {}", node_id,
3843 let def_like = DlDef(DefTyParam
3844 (local_def(type_parameter.id),
3845 index + initial_index));
3846 // Associate this type parameter with
3847 // the item that bound it
3848 self.record_def(type_parameter.id,
3849 (DefTyParamBinder(node_id), LastMod(AllPublic)));
3850 // plain insert (no renaming)
3851 let mut bindings = function_type_rib.bindings
3853 bindings.get().insert(ident.name, def_like);
3857 NoTypeParameters => {
3864 match type_parameters {
3865 HasTypeParameters(..) => {
3866 let mut type_ribs = self.type_ribs.borrow_mut();
3867 type_ribs.get().pop();
3870 NoTypeParameters => {
3876 fn with_label_rib(&mut self, f: |&mut Resolver|) {
3878 let mut label_ribs = self.label_ribs.borrow_mut();
3879 label_ribs.get().push(@Rib::new(NormalRibKind));
3885 let mut label_ribs = self.label_ribs.borrow_mut();
3886 label_ribs.get().pop();
3890 fn with_constant_rib(&mut self, f: |&mut Resolver|) {
3892 let mut value_ribs = self.value_ribs.borrow_mut();
3893 let mut type_ribs = self.type_ribs.borrow_mut();
3894 value_ribs.get().push(@Rib::new(ConstantItemRibKind));
3895 type_ribs.get().push(@Rib::new(ConstantItemRibKind));
3899 let mut value_ribs = self.value_ribs.borrow_mut();
3900 let mut type_ribs = self.type_ribs.borrow_mut();
3901 type_ribs.get().pop();
3902 value_ribs.get().pop();
3906 fn resolve_function(&mut self,
3908 optional_declaration: Option<P<FnDecl>>,
3909 type_parameters: TypeParameters,
3911 // Create a value rib for the function.
3912 let function_value_rib = @Rib::new(rib_kind);
3914 let mut value_ribs = self.value_ribs.borrow_mut();
3915 value_ribs.get().push(function_value_rib);
3918 // Create a label rib for the function.
3920 let mut label_ribs = self.label_ribs.borrow_mut();
3921 let function_label_rib = @Rib::new(rib_kind);
3922 label_ribs.get().push(function_label_rib);
3925 // If this function has type parameters, add them now.
3926 self.with_type_parameter_rib(type_parameters, |this| {
3927 // Resolve the type parameters.
3928 match type_parameters {
3929 NoTypeParameters => {
3932 HasTypeParameters(ref generics, _, _, _) => {
3933 this.resolve_type_parameters(&generics.ty_params);
3937 // Add each argument to the rib.
3938 match optional_declaration {
3942 Some(declaration) => {
3943 for argument in declaration.inputs.iter() {
3944 let binding_mode = ArgumentIrrefutableMode;
3945 this.resolve_pattern(argument.pat,
3949 this.resolve_type(argument.ty);
3951 debug!("(resolving function) recorded argument");
3954 this.resolve_type(declaration.output);
3958 // Resolve the function body.
3959 this.resolve_block(block);
3961 debug!("(resolving function) leaving function");
3964 let mut label_ribs = self.label_ribs.borrow_mut();
3965 label_ribs.get().pop();
3967 let mut value_ribs = self.value_ribs.borrow_mut();
3968 value_ribs.get().pop();
3971 fn resolve_type_parameters(&mut self,
3972 type_parameters: &OptVec<TyParam>) {
3973 for type_parameter in type_parameters.iter() {
3974 for bound in type_parameter.bounds.iter() {
3975 self.resolve_type_parameter_bound(type_parameter.id, bound);
3977 match type_parameter.default {
3978 Some(ty) => self.resolve_type(ty),
3984 fn resolve_type_parameter_bound(&mut self,
3986 type_parameter_bound: &TyParamBound) {
3987 match *type_parameter_bound {
3988 TraitTyParamBound(ref tref) => {
3989 self.resolve_trait_reference(id, tref, TraitBoundingTypeParameter)
3991 RegionTyParamBound => {}
3995 fn resolve_trait_reference(&mut self,
3997 trait_reference: &TraitRef,
3998 reference_type: TraitReferenceType) {
3999 match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
4001 let path_str = self.path_idents_to_str(&trait_reference.path);
4002 let usage_str = match reference_type {
4003 TraitBoundingTypeParameter => "bound type parameter with",
4004 TraitImplementation => "implement",
4005 TraitDerivation => "derive"
4008 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
4009 self.resolve_error(trait_reference.path.span, msg);
4012 debug!("(resolving trait) found trait def: {:?}", def);
4013 self.record_def(trait_reference.ref_id, def);
4018 fn resolve_struct(&mut self,
4020 generics: &Generics,
4021 fields: &[StructField]) {
4022 let mut ident_map: HashMap<ast::Ident, &StructField> = HashMap::new();
4023 for field in fields.iter() {
4024 match field.node.kind {
4025 NamedField(ident, _) => {
4026 match ident_map.find(&ident) {
4027 Some(&prev_field) => {
4028 let ident_str = token::get_ident(ident);
4029 self.resolve_error(field.span,
4030 format!("field `{}` is already declared", ident_str));
4031 self.session.span_note(prev_field.span,
4032 "previously declared here");
4035 ident_map.insert(ident, field);
4043 // If applicable, create a rib for the type parameters.
4044 self.with_type_parameter_rib(HasTypeParameters(generics,
4047 OpaqueFunctionRibKind),
4049 // Resolve the type parameters.
4050 this.resolve_type_parameters(&generics.ty_params);
4053 for field in fields.iter() {
4054 this.resolve_type(field.node.ty);
4059 // Does this really need to take a RibKind or is it always going
4060 // to be NormalRibKind?
4061 fn resolve_method(&mut self,
4064 outer_type_parameter_count: uint) {
4065 let method_generics = &method.generics;
4066 let type_parameters =
4067 HasTypeParameters(method_generics,
4069 outer_type_parameter_count,
4072 self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
4075 fn resolve_implementation(&mut self,
4077 generics: &Generics,
4078 opt_trait_reference: &Option<TraitRef>,
4080 methods: &[@Method]) {
4081 // If applicable, create a rib for the type parameters.
4082 let outer_type_parameter_count = generics.ty_params.len();
4083 self.with_type_parameter_rib(HasTypeParameters(generics,
4088 // Resolve the type parameters.
4089 this.resolve_type_parameters(&generics.ty_params);
4091 // Resolve the trait reference, if necessary.
4092 let original_trait_refs;
4093 match opt_trait_reference {
4094 &Some(ref trait_reference) => {
4095 this.resolve_trait_reference(id, trait_reference,
4096 TraitImplementation);
4098 // Record the current set of trait references.
4099 let mut new_trait_refs = Vec::new();
4101 let def_map = this.def_map.borrow();
4102 let r = def_map.get().find(&trait_reference.ref_id);
4103 for &def in r.iter() {
4104 new_trait_refs.push(def_id_of_def(*def));
4107 original_trait_refs = Some(replace(
4108 &mut this.current_trait_refs,
4109 Some(new_trait_refs)));
4112 original_trait_refs = None;
4116 // Resolve the self type.
4117 this.resolve_type(self_type);
4119 for method in methods.iter() {
4120 // We also need a new scope for the method-specific
4122 this.resolve_method(MethodRibKind(
4124 Provided(method.id)),
4126 outer_type_parameter_count);
4128 let borrowed_type_parameters = &method.tps;
4129 self.resolve_function(MethodRibKind(
4131 Provided(method.id)),
4134 (borrowed_type_parameters,
4136 outer_type_parameter_count,
4142 // Restore the original trait references.
4143 match original_trait_refs {
4144 Some(r) => { this.current_trait_refs = r; }
4150 fn resolve_module(&mut self, module: &Mod, _span: Span,
4151 _name: Ident, id: NodeId) {
4152 // Write the implementations in scope into the module metadata.
4153 debug!("(resolving module) resolving module ID {}", id);
4154 visit::walk_mod(self, module, ());
4157 fn resolve_local(&mut self, local: &Local) {
4158 // Resolve the type.
4159 self.resolve_type(local.ty);
4161 // Resolve the initializer, if necessary.
4166 Some(initializer) => {
4167 self.resolve_expr(initializer);
4171 // Resolve the pattern.
4172 self.resolve_pattern(local.pat, LocalIrrefutableMode, None);
4175 // build a map from pattern identifiers to binding-info's.
4176 // this is done hygienically. This could arise for a macro
4177 // that expands into an or-pattern where one 'x' was from the
4178 // user and one 'x' came from the macro.
4179 fn binding_mode_map(&mut self, pat: @Pat) -> BindingMap {
4180 let mut result = HashMap::new();
4181 pat_bindings(self.def_map, pat, |binding_mode, _id, sp, path| {
4182 let name = mtwt::resolve(path_to_ident(path));
4184 binding_info {span: sp,
4185 binding_mode: binding_mode});
4190 // check that all of the arms in an or-pattern have exactly the
4191 // same set of bindings, with the same binding modes for each.
4192 fn check_consistent_bindings(&mut self, arm: &Arm) {
4193 if arm.pats.len() == 0 {
4196 let map_0 = self.binding_mode_map(*arm.pats.get(0));
4197 for (i, p) in arm.pats.iter().enumerate() {
4198 let map_i = self.binding_mode_map(*p);
4200 for (&key, &binding_0) in map_0.iter() {
4201 match map_i.find(&key) {
4205 format!("variable `{}` from pattern \\#1 is \
4206 not bound in pattern \\#{}",
4207 token::get_name(key),
4210 Some(binding_i) => {
4211 if binding_0.binding_mode != binding_i.binding_mode {
4214 format!("variable `{}` is bound with different \
4215 mode in pattern \\#{} than in pattern \\#1",
4216 token::get_name(key),
4223 for (&key, &binding) in map_i.iter() {
4224 if !map_0.contains_key(&key) {
4227 format!("variable `{}` from pattern \\#{} is \
4228 not bound in pattern \\#1",
4229 token::get_name(key),
4236 fn resolve_arm(&mut self, arm: &Arm) {
4238 let mut value_ribs = self.value_ribs.borrow_mut();
4239 value_ribs.get().push(@Rib::new(NormalRibKind));
4242 let mut bindings_list = HashMap::new();
4243 for pattern in arm.pats.iter() {
4244 self.resolve_pattern(*pattern,
4246 Some(&mut bindings_list));
4249 // This has to happen *after* we determine which
4250 // pat_idents are variants
4251 self.check_consistent_bindings(arm);
4253 visit::walk_expr_opt(self, arm.guard, ());
4254 self.resolve_expr(arm.body);
4256 let mut value_ribs = self.value_ribs.borrow_mut();
4257 value_ribs.get().pop();
4260 fn resolve_block(&mut self, block: &Block) {
4261 debug!("(resolving block) entering block");
4263 let mut value_ribs = self.value_ribs.borrow_mut();
4264 value_ribs.get().push(@Rib::new(NormalRibKind));
4267 // Move down in the graph, if there's an anonymous module rooted here.
4268 let orig_module = self.current_module;
4269 let anonymous_children = self.current_module
4272 match anonymous_children.get().find(&block.id) {
4273 None => { /* Nothing to do. */ }
4274 Some(&anonymous_module) => {
4275 debug!("(resolving block) found anonymous module, moving \
4277 self.current_module = anonymous_module;
4281 // Descend into the block.
4282 visit::walk_block(self, block, ());
4285 self.current_module = orig_module;
4287 let mut value_ribs = self.value_ribs.borrow_mut();
4288 value_ribs.get().pop();
4289 debug!("(resolving block) leaving block");
4292 fn resolve_type(&mut self, ty: &Ty) {
4294 // Like path expressions, the interpretation of path types depends
4295 // on whether the path has multiple elements in it or not.
4297 TyPath(ref path, ref bounds, path_id) => {
4298 // This is a path in the type namespace. Walk through scopes
4300 let mut result_def = None;
4302 // First, check to see whether the name is a primitive type.
4303 if path.segments.len() == 1 {
4304 let id = path.segments.last().unwrap().identifier;
4306 match self.primitive_type_table
4310 Some(&primitive_type) => {
4312 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4316 .any(|s| !s.lifetimes.is_empty()) {
4317 self.session.span_err(path.span,
4318 "lifetime parameters \
4319 are not allowed on \
4321 } else if path.segments
4323 .any(|s| s.types.len() > 0) {
4324 self.session.span_err(path.span,
4325 "type parameters are \
4326 not allowed on this \
4338 match self.resolve_path(ty.id, path, TypeNS, true) {
4340 debug!("(resolving type) resolved `{}` to \
4342 token::get_ident(path.segments
4346 result_def = Some(def);
4353 Some(_) => {} // Continue.
4358 // Write the result into the def map.
4359 debug!("(resolving type) writing resolution for `{}` \
4361 self.path_idents_to_str(path),
4363 self.record_def(path_id, def);
4366 let msg = format!("use of undeclared type name `{}`",
4367 self.path_idents_to_str(path));
4368 self.resolve_error(ty.span, msg);
4372 bounds.as_ref().map(|bound_vec| {
4373 for bound in bound_vec.iter() {
4374 self.resolve_type_parameter_bound(ty.id, bound);
4380 c.bounds.as_ref().map(|bounds| {
4381 for bound in bounds.iter() {
4382 self.resolve_type_parameter_bound(ty.id, bound);
4385 visit::walk_ty(self, ty, ());
4389 // Just resolve embedded types.
4390 visit::walk_ty(self, ty, ());
4395 fn resolve_pattern(&mut self,
4397 mode: PatternBindingMode,
4398 // Maps idents to the node ID for the (outermost)
4399 // pattern that binds them
4400 mut bindings_list: Option<&mut HashMap<Name,NodeId>>) {
4401 let pat_id = pattern.id;
4402 walk_pat(pattern, |pattern| {
4403 match pattern.node {
4404 PatIdent(binding_mode, ref path, _)
4405 if !path.global && path.segments.len() == 1 => {
4407 // The meaning of pat_ident with no type parameters
4408 // depends on whether an enum variant or unit-like struct
4409 // with that name is in scope. The probing lookup has to
4410 // be careful not to emit spurious errors. Only matching
4411 // patterns (match) can match nullary variants or
4412 // unit-like structs. For binding patterns (let), matching
4413 // such a value is simply disallowed (since it's rarely
4416 let ident = path.segments.get(0).identifier;
4417 let renamed = mtwt::resolve(ident);
4419 match self.resolve_bare_identifier_pattern(ident) {
4420 FoundStructOrEnumVariant(def, lp)
4421 if mode == RefutableMode => {
4422 debug!("(resolving pattern) resolving `{}` to \
4423 struct or enum variant",
4424 token::get_name(renamed));
4426 self.enforce_default_binding_mode(
4430 self.record_def(pattern.id, (def, lp));
4432 FoundStructOrEnumVariant(..) => {
4433 self.resolve_error(pattern.span,
4434 format!("declaration of `{}` \
4436 variant or unit-like \
4438 token::get_name(renamed)));
4440 FoundConst(def, lp) if mode == RefutableMode => {
4441 debug!("(resolving pattern) resolving `{}` to \
4443 token::get_name(renamed));
4445 self.enforce_default_binding_mode(
4449 self.record_def(pattern.id, (def, lp));
4452 self.resolve_error(pattern.span,
4453 "only irrefutable patterns \
4456 BareIdentifierPatternUnresolved => {
4457 debug!("(resolving pattern) binding `{}`",
4458 token::get_name(renamed));
4460 let def = match mode {
4462 // For pattern arms, we must use
4463 // `def_binding` definitions.
4465 DefBinding(pattern.id, binding_mode)
4467 LocalIrrefutableMode => {
4468 // But for locals, we use `def_local`.
4469 DefLocal(pattern.id, binding_mode)
4471 ArgumentIrrefutableMode => {
4472 // And for function arguments, `def_arg`.
4473 DefArg(pattern.id, binding_mode)
4477 // Record the definition so that later passes
4478 // will be able to distinguish variants from
4479 // locals in patterns.
4481 self.record_def(pattern.id, (def, LastMod(AllPublic)));
4483 // Add the binding to the local ribs, if it
4484 // doesn't already exist in the bindings list. (We
4485 // must not add it if it's in the bindings list
4486 // because that breaks the assumptions later
4487 // passes make about or-patterns.)
4489 match bindings_list {
4490 Some(ref mut bindings_list)
4491 if !bindings_list.contains_key(&renamed) => {
4492 let this = &mut *self;
4494 let mut value_ribs =
4495 this.value_ribs.borrow_mut();
4496 let length = value_ribs.get().len();
4497 let last_rib = value_ribs.get().get(
4500 last_rib.bindings.borrow_mut();
4501 bindings.get().insert(renamed,
4504 bindings_list.insert(renamed, pat_id);
4506 Some(ref mut b) => {
4507 if b.find(&renamed) == Some(&pat_id) {
4508 // Then this is a duplicate variable
4509 // in the same disjunct, which is an
4511 self.resolve_error(pattern.span,
4512 format!("identifier `{}` is bound more \
4513 than once in the same pattern",
4514 path_to_str(path)));
4516 // Not bound in the same pattern: do nothing
4519 let this = &mut *self;
4521 let mut value_ribs =
4522 this.value_ribs.borrow_mut();
4523 let length = value_ribs.get().len();
4524 let last_rib = value_ribs.get().get(
4527 last_rib.bindings.borrow_mut();
4528 bindings.get().insert(renamed,
4536 // Check the types in the path pattern.
4537 for &ty in path.segments
4539 .flat_map(|seg| seg.types.iter()) {
4540 self.resolve_type(ty);
4544 PatIdent(binding_mode, ref path, _) => {
4545 // This must be an enum variant, struct, or constant.
4546 match self.resolve_path(pat_id, path, ValueNS, false) {
4547 Some(def @ (DefVariant(..), _)) |
4548 Some(def @ (DefStruct(..), _)) => {
4549 self.record_def(pattern.id, def);
4551 Some(def @ (DefStatic(..), _)) => {
4552 self.enforce_default_binding_mode(
4556 self.record_def(pattern.id, def);
4561 format!("`{}` is not an enum variant or constant",
4563 path.segments.last().unwrap().identifier)))
4566 self.resolve_error(path.span,
4567 "unresolved enum variant");
4571 // Check the types in the path pattern.
4572 for &ty in path.segments
4574 .flat_map(|s| s.types.iter()) {
4575 self.resolve_type(ty);
4579 PatEnum(ref path, _) => {
4580 // This must be an enum variant, struct or const.
4581 match self.resolve_path(pat_id, path, ValueNS, false) {
4582 Some(def @ (DefFn(..), _)) |
4583 Some(def @ (DefVariant(..), _)) |
4584 Some(def @ (DefStruct(..), _)) |
4585 Some(def @ (DefStatic(..), _)) => {
4586 self.record_def(pattern.id, def);
4589 self.resolve_error(path.span,
4590 format!("`{}` is not an enum variant, struct or const",
4591 token::get_ident(path.segments
4596 self.resolve_error(path.span,
4597 format!("unresolved enum variant, struct or const `{}`",
4598 token::get_ident(path.segments
4604 // Check the types in the path pattern.
4605 for &ty in path.segments
4607 .flat_map(|s| s.types.iter()) {
4608 self.resolve_type(ty);
4613 self.resolve_expr(expr);
4616 PatRange(first_expr, last_expr) => {
4617 self.resolve_expr(first_expr);
4618 self.resolve_expr(last_expr);
4621 PatStruct(ref path, _, _) => {
4622 match self.resolve_path(pat_id, path, TypeNS, false) {
4623 Some((DefTy(class_id), lp))
4624 if self.structs.contains(&class_id) => {
4625 let class_def = DefStruct(class_id);
4626 self.record_def(pattern.id, (class_def, lp));
4628 Some(definition @ (DefStruct(class_id), _)) => {
4629 assert!(self.structs.contains(&class_id));
4630 self.record_def(pattern.id, definition);
4632 Some(definition @ (DefVariant(_, variant_id, _), _))
4633 if self.structs.contains(&variant_id) => {
4634 self.record_def(pattern.id, definition);
4637 debug!("(resolving pattern) didn't find struct \
4638 def: {:?}", result);
4639 let msg = format!("`{}` does not name a structure",
4640 self.path_idents_to_str(path));
4641 self.resolve_error(path.span, msg);
4654 fn resolve_bare_identifier_pattern(&mut self, name: Ident)
4656 BareIdentifierPatternResolution {
4657 match self.resolve_item_in_lexical_scope(self.current_module,
4660 SearchThroughModules) {
4661 Success((target, _)) => {
4662 debug!("(resolve bare identifier pattern) succeeded in \
4663 finding {} at {:?}",
4664 token::get_ident(name),
4665 target.bindings.value_def.get());
4666 match target.bindings.value_def.get() {
4668 fail!("resolved name in the value namespace to a \
4669 set of name bindings with no def?!");
4672 // For the two success cases, this lookup can be
4673 // considered as not having a private component because
4674 // the lookup happened only within the current module.
4676 def @ DefVariant(..) | def @ DefStruct(..) => {
4677 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
4679 def @ DefStatic(_, false) => {
4680 return FoundConst(def, LastMod(AllPublic));
4683 return BareIdentifierPatternUnresolved;
4691 fail!("unexpected indeterminate result");
4695 debug!("(resolve bare identifier pattern) failed to find {}",
4696 token::get_ident(name));
4697 return BareIdentifierPatternUnresolved;
4702 /// If `check_ribs` is true, checks the local definitions first; i.e.
4703 /// doesn't skip straight to the containing module.
4704 fn resolve_path(&mut self,
4707 namespace: Namespace,
4708 check_ribs: bool) -> Option<(Def, LastPrivate)> {
4709 // First, resolve the types.
4710 for &ty in path.segments.iter().flat_map(|s| s.types.iter()) {
4711 self.resolve_type(ty);
4715 return self.resolve_crate_relative_path(path, namespace);
4718 let unqualified_def =
4719 self.resolve_identifier(path.segments
4726 if path.segments.len() > 1 {
4727 let def = self.resolve_module_relative_path(path, namespace);
4728 match (def, unqualified_def) {
4729 (Some((d, _)), Some((ud, _))) if d == ud => {
4730 self.session.add_lint(UnnecessaryQualification,
4733 ~"unnecessary qualification");
4741 return unqualified_def;
4744 // resolve a single identifier (used as a varref)
4745 fn resolve_identifier(&mut self,
4747 namespace: Namespace,
4750 -> Option<(Def, LastPrivate)> {
4752 match self.resolve_identifier_in_local_ribs(identifier,
4756 return Some((def, LastMod(AllPublic)));
4764 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
4768 // FIXME #4952: Merge me with resolve_name_in_module?
4769 fn resolve_definition_of_name_in_module(&mut self,
4770 containing_module: @Module,
4772 namespace: Namespace)
4774 // First, search children.
4775 self.populate_module_if_necessary(containing_module);
4778 let children = containing_module.children.borrow();
4779 match children.get().find(&name.name) {
4780 Some(child_name_bindings) => {
4781 match child_name_bindings.def_for_namespace(namespace) {
4783 // Found it. Stop the search here.
4784 let p = child_name_bindings.defined_in_public_namespace(
4786 let lp = if p {LastMod(AllPublic)} else {
4787 LastMod(DependsOn(def_id_of_def(def)))
4789 return ChildNameDefinition(def, lp);
4798 // Next, search import resolutions.
4799 let import_resolutions = containing_module.import_resolutions
4801 match import_resolutions.get().find(&name.name) {
4802 Some(import_resolution) if import_resolution.is_public.get() => {
4803 match (*import_resolution).target_for_namespace(namespace) {
4805 match target.bindings.def_for_namespace(namespace) {
4808 let id = import_resolution.id(namespace);
4809 self.used_imports.insert((id, namespace));
4810 return ImportNameDefinition(def, LastMod(AllPublic));
4813 // This can happen with external impls, due to
4814 // the imperfect way we read the metadata.
4821 Some(..) | None => {} // Continue.
4824 // Finally, search through external children.
4825 if namespace == TypeNS {
4827 let external_module_children =
4828 containing_module.external_module_children.borrow();
4829 external_module_children.get().find_copy(&name.name)
4834 match module.def_id.get() {
4835 None => {} // Continue.
4837 let lp = if module.is_public {LastMod(AllPublic)} else {
4838 LastMod(DependsOn(def_id))
4840 return ChildNameDefinition(DefMod(def_id), lp);
4847 return NoNameDefinition;
4850 // resolve a "module-relative" path, e.g. a::b::c
4851 fn resolve_module_relative_path(&mut self,
4853 namespace: Namespace)
4854 -> Option<(Def, LastPrivate)> {
4855 let module_path_idents = path.segments.init().map(|ps| ps.identifier);
4857 let containing_module;
4859 match self.resolve_module_path(self.current_module,
4865 let msg = format!("use of undeclared module `{}`",
4866 self.idents_to_str(module_path_idents));
4867 self.resolve_error(path.span, msg);
4872 fail!("indeterminate unexpected");
4875 Success((resulting_module, resulting_last_private)) => {
4876 containing_module = resulting_module;
4877 last_private = resulting_last_private;
4881 let ident = path.segments.last().unwrap().identifier;
4882 let def = match self.resolve_definition_of_name_in_module(containing_module,
4885 NoNameDefinition => {
4886 // We failed to resolve the name. Report an error.
4889 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4890 (def, last_private.or(lp))
4893 match containing_module.kind.get() {
4894 TraitModuleKind | ImplModuleKind => {
4895 let method_map = self.method_map.borrow();
4896 match method_map.get().find(&ident.name) {
4898 match containing_module.def_id.get() {
4899 Some(def_id) if s.contains(&def_id) => {
4900 debug!("containing module was a trait or impl \
4901 and name was a method -> not resolved");
4915 /// Invariant: This must be called only during main resolution, not during
4916 /// import resolution.
4917 fn resolve_crate_relative_path(&mut self,
4919 namespace: Namespace)
4920 -> Option<(Def, LastPrivate)> {
4921 let module_path_idents = path.segments.init().map(|ps| ps.identifier);
4923 let root_module = self.graph_root.get_module();
4925 let containing_module;
4927 match self.resolve_module_path_from_root(root_module,
4932 LastMod(AllPublic)) {
4934 let msg = format!("use of undeclared module `::{}`",
4935 self.idents_to_str(module_path_idents));
4936 self.resolve_error(path.span, msg);
4941 fail!("indeterminate unexpected");
4944 Success((resulting_module, resulting_last_private)) => {
4945 containing_module = resulting_module;
4946 last_private = resulting_last_private;
4950 let name = path.segments.last().unwrap().identifier;
4951 match self.resolve_definition_of_name_in_module(containing_module,
4954 NoNameDefinition => {
4955 // We failed to resolve the name. Report an error.
4958 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4959 return Some((def, last_private.or(lp)));
4964 fn resolve_identifier_in_local_ribs(&mut self,
4966 namespace: Namespace,
4969 // Check the local set of ribs.
4973 let renamed = mtwt::resolve(ident);
4974 let mut value_ribs = self.value_ribs.borrow_mut();
4975 search_result = self.search_ribs(value_ribs.get(),
4980 let name = ident.name;
4981 let mut type_ribs = self.type_ribs.borrow_mut();
4982 search_result = self.search_ribs(type_ribs.get(),
4988 match search_result {
4989 Some(DlDef(def)) => {
4990 debug!("(resolving path in local ribs) resolved `{}` to \
4992 token::get_ident(ident),
4996 Some(DlField) | Some(DlImpl(_)) | None => {
5002 fn resolve_item_by_identifier_in_lexical_scope(&mut self,
5004 namespace: Namespace)
5005 -> Option<(Def, LastPrivate)> {
5007 match self.resolve_item_in_lexical_scope(self.current_module,
5010 DontSearchThroughModules) {
5011 Success((target, _)) => {
5012 match (*target.bindings).def_for_namespace(namespace) {
5014 // This can happen if we were looking for a type and
5015 // found a module instead. Modules don't have defs.
5016 debug!("(resolving item path by identifier in lexical \
5017 scope) failed to resolve {} after success...",
5018 token::get_ident(ident));
5022 debug!("(resolving item path in lexical scope) \
5023 resolved `{}` to item",
5024 token::get_ident(ident));
5025 // This lookup is "all public" because it only searched
5026 // for one identifier in the current module (couldn't
5027 // have passed through reexports or anything like that.
5028 return Some((def, LastMod(AllPublic)));
5033 fail!("unexpected indeterminate result");
5036 debug!("(resolving item path by identifier in lexical scope) \
5037 failed to resolve {}", token::get_ident(ident));
5043 fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
5044 self.emit_errors = false;
5046 self.emit_errors = true;
5050 fn resolve_error(&mut self, span: Span, s: &str) {
5051 if self.emit_errors {
5052 self.session.span_err(span, s);
5056 fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5058 let this = &mut *self;
5060 let mut maybes: Vec<token::InternedString> = Vec::new();
5061 let mut values: Vec<uint> = Vec::new();
5064 let value_ribs = this.value_ribs.borrow();
5065 value_ribs.get().len()
5069 let value_ribs = this.value_ribs.borrow();
5070 let bindings = value_ribs.get().get(j).bindings.borrow();
5071 for (&k, _) in bindings.get().iter() {
5072 maybes.push(token::get_name(k));
5073 values.push(uint::MAX);
5077 let mut smallest = 0;
5078 for (i, other) in maybes.iter().enumerate() {
5079 *values.get_mut(i) = name.lev_distance(other.get());
5081 if *values.get(i) <= *values.get(smallest) {
5086 if values.len() > 0 &&
5087 *values.get(smallest) != uint::MAX &&
5088 *values.get(smallest) < name.len() + 2 &&
5089 *values.get(smallest) <= max_distance &&
5090 name != maybes.get(smallest).get() {
5092 Some(maybes.get(smallest).get().to_str())
5099 fn resolve_expr(&mut self, expr: &Expr) {
5100 // First, record candidate traits for this expression if it could
5101 // result in the invocation of a method call.
5103 self.record_candidate_traits_for_expr_if_necessary(expr);
5105 // Next, resolve the node.
5107 // The interpretation of paths depends on whether the path has
5108 // multiple elements in it or not.
5110 ExprPath(ref path) => {
5111 // This is a local path in the value namespace. Walk through
5112 // scopes looking for it.
5114 match self.resolve_path(expr.id, path, ValueNS, true) {
5116 // Write the result into the def map.
5117 debug!("(resolving expr) resolved `{}`",
5118 self.path_idents_to_str(path));
5120 // First-class methods are not supported yet; error
5123 (DefMethod(..), _) => {
5124 self.resolve_error(expr.span,
5125 "first-class methods \
5126 are not supported");
5127 self.session.span_note(expr.span,
5135 self.record_def(expr.id, def);
5138 let wrong_name = self.path_idents_to_str(path);
5139 // Be helpful if the name refers to a struct
5140 // (The pattern matching def_tys where the id is in self.structs
5141 // matches on regular structs while excluding tuple- and enum-like
5142 // structs, which wouldn't result in this error.)
5143 match self.with_no_errors(|this|
5144 this.resolve_path(expr.id, path, TypeNS, false)) {
5145 Some((DefTy(struct_id), _))
5146 if self.structs.contains(&struct_id) => {
5147 self.resolve_error(expr.span,
5148 format!("`{}` is a structure name, but \
5150 uses it like a function name",
5153 self.session.span_note(expr.span,
5154 format!("Did you mean to write: \
5155 `{} \\{ /* fields */ \\}`?",
5160 // limit search to 5 to reduce the number
5161 // of stupid suggestions
5162 match self.find_best_match_for_name(wrong_name, 5) {
5164 self.resolve_error(expr.span,
5165 format!("unresolved name `{}`. \
5166 Did you mean `{}`?",
5170 self.resolve_error(expr.span,
5171 format!("unresolved name `{}`.",
5179 visit::walk_expr(self, expr, ());
5182 ExprFnBlock(fn_decl, block) |
5183 ExprProc(fn_decl, block) => {
5184 self.resolve_function(FunctionRibKind(expr.id, block.id),
5185 Some(fn_decl), NoTypeParameters,
5189 ExprStruct(ref path, _, _) => {
5190 // Resolve the path to the structure it goes to.
5191 match self.resolve_path(expr.id, path, TypeNS, false) {
5192 Some((DefTy(class_id), lp)) | Some((DefStruct(class_id), lp))
5193 if self.structs.contains(&class_id) => {
5194 let class_def = DefStruct(class_id);
5195 self.record_def(expr.id, (class_def, lp));
5197 Some(definition @ (DefVariant(_, class_id, _), _))
5198 if self.structs.contains(&class_id) => {
5199 self.record_def(expr.id, definition);
5202 debug!("(resolving expression) didn't find struct \
5203 def: {:?}", result);
5204 let msg = format!("`{}` does not name a structure",
5205 self.path_idents_to_str(path));
5206 self.resolve_error(path.span, msg);
5210 visit::walk_expr(self, expr, ());
5213 ExprLoop(_, Some(label)) => {
5214 self.with_label_rib(|this| {
5215 let def_like = DlDef(DefLabel(expr.id));
5217 let mut label_ribs = this.label_ribs.borrow_mut();
5218 let length = label_ribs.get().len();
5219 let rib = label_ribs.get().get(length - 1);
5220 let mut bindings = rib.bindings.borrow_mut();
5221 let renamed = mtwt::resolve(label);
5222 bindings.get().insert(renamed, def_like);
5225 visit::walk_expr(this, expr, ());
5229 ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
5231 ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5232 let mut label_ribs = self.label_ribs.borrow_mut();
5233 let renamed = mtwt::resolve(label);
5234 match self.search_ribs(label_ribs.get(), renamed, expr.span) {
5236 self.resolve_error(expr.span,
5237 format!("use of undeclared label `{}`",
5238 token::get_ident(label))),
5239 Some(DlDef(def @ DefLabel(_))) => {
5240 // Since this def is a label, it is never read.
5241 self.record_def(expr.id, (def, LastMod(AllPublic)))
5244 self.session.span_bug(expr.span,
5245 "label wasn't mapped to a \
5252 visit::walk_expr(self, expr, ());
5257 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5259 ExprField(_, ident, _) => {
5260 // FIXME(#6890): Even though you can't treat a method like a
5261 // field, we need to add any trait methods we find that match
5262 // the field name so that we can do some nice error reporting
5263 // later on in typeck.
5264 let traits = self.search_for_traits_containing_method(ident);
5265 self.trait_map.insert(expr.id, traits);
5267 ExprMethodCall(ident, _, _) => {
5268 debug!("(recording candidate traits for expr) recording \
5271 let traits = self.search_for_traits_containing_method(ident);
5272 self.trait_map.insert(expr.id, traits);
5280 fn search_for_traits_containing_method(&mut self, name: Ident) -> Vec<DefId> {
5281 debug!("(searching for traits containing method) looking for '{}'",
5282 token::get_ident(name));
5284 let mut found_traits = Vec::new();
5285 let mut search_module = self.current_module;
5286 let method_map = self.method_map.borrow();
5287 match method_map.get().find(&name.name) {
5288 Some(candidate_traits) => loop {
5289 // Look for the current trait.
5290 match self.current_trait_refs {
5291 Some(ref trait_def_ids) => {
5292 for trait_def_id in trait_def_ids.iter() {
5293 if candidate_traits.contains(trait_def_id) {
5294 self.add_trait_info(&mut found_traits,
5305 // Look for trait children.
5306 self.populate_module_if_necessary(search_module);
5308 let children = search_module.children.borrow();
5309 for (_, &child_names) in children.get().iter() {
5310 let def = match child_names.def_for_namespace(TypeNS) {
5314 let trait_def_id = match def {
5315 DefTrait(trait_def_id) => trait_def_id,
5318 if candidate_traits.contains(&trait_def_id) {
5319 self.add_trait_info(&mut found_traits, trait_def_id,
5324 // Look for imports.
5325 let import_resolutions = search_module.import_resolutions
5327 for (_, &import) in import_resolutions.get().iter() {
5328 let target = match import.target_for_namespace(TypeNS) {
5330 Some(target) => target,
5332 let did = match target.bindings.def_for_namespace(TypeNS) {
5333 Some(DefTrait(trait_def_id)) => trait_def_id,
5334 Some(..) | None => continue,
5336 if candidate_traits.contains(&did) {
5337 self.add_trait_info(&mut found_traits, did, name);
5338 self.used_imports.insert((import.type_id.get(), TypeNS));
5342 match search_module.parent_link {
5343 NoParentLink | ModuleParentLink(..) => break,
5344 BlockParentLink(parent_module, _) => {
5345 search_module = parent_module;
5352 return found_traits;
5355 fn add_trait_info(&self,
5356 found_traits: &mut Vec<DefId> ,
5357 trait_def_id: DefId,
5359 debug!("(adding trait info) found trait {}:{} for method '{}'",
5362 token::get_ident(name));
5363 found_traits.push(trait_def_id);
5366 fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
5367 debug!("(recording def) recording {:?} for {:?}, last private {:?}",
5369 assert!(match lp {LastImport{..} => false, _ => true},
5370 "Import should only be used for `use` directives");
5371 self.last_private.insert(node_id, lp);
5372 let mut def_map = self.def_map.borrow_mut();
5373 def_map.get().insert_or_update_with(node_id, def, |_, old_value| {
5374 // Resolve appears to "resolve" the same ID multiple
5375 // times, so here is a sanity check it at least comes to
5376 // the same conclusion! - nmatsakis
5377 if def != *old_value {
5378 self.session.bug(format!("node_id {:?} resolved first to {:?} \
5379 and then {:?}", node_id, *old_value, def));
5384 fn enforce_default_binding_mode(&mut self,
5386 pat_binding_mode: BindingMode,
5388 match pat_binding_mode {
5389 BindByValue(_) => {}
5393 format!("cannot use `ref` binding mode with {}",
5400 // Unused import checking
5402 // Although this is mostly a lint pass, it lives in here because it depends on
5403 // resolve data structures and because it finalises the privacy information for
5404 // `use` directives.
5407 fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
5408 let mut visitor = UnusedImportCheckVisitor{ resolver: self };
5409 visit::walk_crate(&mut visitor, krate, ());
5412 fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
5413 // Ignore is_public import statements because there's no way to be sure
5414 // whether they're used or not. Also ignore imports with a dummy span
5415 // because this means that they were generated in some fashion by the
5416 // compiler and we don't need to consider them.
5417 if vi.vis == Public { return }
5418 if vi.span == DUMMY_SP { return }
5421 ViewItemExternCrate(..) => {} // ignore
5422 ViewItemUse(ref path) => {
5423 for p in path.iter() {
5425 ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
5426 ViewPathList(_, ref list, _) => {
5427 for i in list.iter() {
5428 self.finalize_import(i.node.id, i.span);
5431 ViewPathGlob(_, id) => {
5432 if !self.used_imports.contains(&(id, TypeNS)) &&
5433 !self.used_imports.contains(&(id, ValueNS)) {
5434 self.session.add_lint(UnusedImports, id, p.span, ~"unused import");
5443 // We have information about whether `use` (import) directives are actually used now.
5444 // If an import is not used at all, we signal a lint error. If an import is only used
5445 // for a single namespace, we remove the other namespace from the recorded privacy
5446 // information. That means in privacy.rs, we will only check imports and namespaces
5447 // which are used. In particular, this means that if an import could name either a
5448 // public or private item, we will check the correct thing, dependent on how the import
5450 fn finalize_import(&mut self, id: NodeId, span: Span) {
5451 debug!("finalizing import uses for {}", self.session.codemap().span_to_snippet(span));
5453 if !self.used_imports.contains(&(id, TypeNS)) &&
5454 !self.used_imports.contains(&(id, ValueNS)) {
5455 self.session.add_lint(UnusedImports, id, span, ~"unused import");
5458 let (v_priv, t_priv) = match self.last_private.find(&id) {
5459 Some(&LastImport{value_priv: v,
5462 type_used: _}) => (v, t),
5463 Some(_) => fail!("We should only have LastImport for `use` directives"),
5467 let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
5472 let t_used = if self.used_imports.contains(&(id, TypeNS)) {
5478 match (v_priv, t_priv) {
5479 // Since some items may be both in the value _and_ type namespaces (e.g., structs)
5480 // we might have two LastPrivates pointing at the same thing. There is no point
5481 // checking both, so lets not check the value one.
5482 (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
5486 self.last_private.insert(id, LastImport{value_priv: v_priv,
5489 type_used: t_used});
5495 // Diagnostics are not particularly efficient, because they're rarely
5499 /// A somewhat inefficient routine to obtain the name of a module.
5500 fn module_to_str(&mut self, module_: @Module) -> ~str {
5501 let mut idents = Vec::new();
5502 let mut current_module = module_;
5504 match current_module.parent_link {
5508 ModuleParentLink(module_, name) => {
5510 current_module = module_;
5512 BlockParentLink(module_, _) => {
5513 idents.push(special_idents::opaque);
5514 current_module = module_;
5519 if idents.len() == 0 {
5522 return self.idents_to_str(idents.move_iter()
5524 .collect::<Vec<ast::Ident>>()
5528 #[allow(dead_code)] // useful for debugging
5529 fn dump_module(&mut self, module_: @Module) {
5530 debug!("Dump of module `{}`:", self.module_to_str(module_));
5532 debug!("Children:");
5533 self.populate_module_if_necessary(module_);
5534 let children = module_.children.borrow();
5535 for (&name, _) in children.get().iter() {
5536 debug!("* {}", token::get_name(name));
5539 debug!("Import resolutions:");
5540 let import_resolutions = module_.import_resolutions.borrow();
5541 for (&name, import_resolution) in import_resolutions.get().iter() {
5543 match import_resolution.target_for_namespace(ValueNS) {
5544 None => { value_repr = ~""; }
5546 value_repr = ~" value:?";
5552 match import_resolution.target_for_namespace(TypeNS) {
5553 None => { type_repr = ~""; }
5555 type_repr = ~" type:?";
5560 debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
5565 pub struct CrateMap {
5567 exp_map2: ExportMap2,
5568 trait_map: TraitMap,
5569 external_exports: ExternalExports,
5570 last_private_map: LastPrivateMap,
5573 /// Entry point to crate resolution.
5574 pub fn resolve_crate(session: &Session,
5575 lang_items: @LanguageItems,
5578 let mut resolver = Resolver(session, lang_items, krate.span);
5579 resolver.resolve(krate);
5580 let Resolver { def_map, export_map2, trait_map, last_private,
5581 external_exports, .. } = resolver;
5584 exp_map2: export_map2,
5585 trait_map: trait_map,
5586 external_exports: external_exports,
5587 last_private_map: last_private,