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;
22 use syntax::ast_util::{def_id_of_def, local_def, mtwt_resolve};
23 use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
24 use syntax::parse::token::special_idents;
25 use syntax::parse::token;
26 use syntax::print::pprust::path_to_str;
27 use syntax::codemap::{Span, DUMMY_SP, Pos};
28 use syntax::opt_vec::OptVec;
30 use syntax::visit::Visitor;
32 use std::cell::{Cell, RefCell};
34 use std::mem::replace;
35 use collections::{HashMap, HashSet};
38 pub type DefMap = @RefCell<HashMap<NodeId,Def>>;
42 binding_mode: BindingMode,
45 // Map from the name in a pattern to its binding mode.
46 type BindingMap = HashMap<Name,binding_info>;
48 // Trait method resolution
49 pub type TraitMap = HashMap<NodeId, ~[DefId]>;
51 // This is the replacement export map. It maps a module to all of the exports
53 pub type ExportMap2 = @RefCell<HashMap<NodeId, ~[Export2]>>;
56 name: ~str, // The name of the target.
57 def_id: DefId, // The definition of the target.
60 // This set contains all exported definitions from external crates. The set does
61 // not contain any entries from local crates.
62 pub type ExternalExports = HashSet<DefId>;
65 pub type LastPrivateMap = HashMap<NodeId, LastPrivate>;
67 pub enum LastPrivate {
69 // `use` directives (imports) can refer to two separate definitions in the
70 // type and value namespaces. We record here the last private node for each
71 // and whether the import is in fact used for each.
72 // If the Option<PrivateDep> fields are None, it means there is no defintion
74 LastImport{value_priv: Option<PrivateDep>,
75 value_used: ImportUse,
76 type_priv: Option<PrivateDep>,
77 type_used: ImportUse},
85 // How an import is used.
88 Unused, // The import is not used.
89 Used, // The import is used.
93 fn or(self, other: LastPrivate) -> LastPrivate {
95 (me, LastMod(AllPublic)) => me,
102 enum PatternBindingMode {
104 LocalIrrefutableMode,
105 ArgumentIrrefutableMode,
108 #[deriving(Eq, Hash)]
115 enum NamespaceError {
122 /// A NamespaceResult represents the result of resolving an import in
123 /// a particular namespace. The result is either definitely-resolved,
124 /// definitely- unresolved, or unknown.
125 enum NamespaceResult {
126 /// Means that resolve hasn't gathered enough information yet to determine
127 /// whether the name is bound in this namespace. (That is, it hasn't
128 /// resolved all `use` directives yet.)
130 /// Means that resolve has determined that the name is definitely
131 /// not bound in the namespace.
133 /// Means that resolve has determined that the name is bound in the Module
134 /// argument, and specified by the NameBindings argument.
135 BoundResult(@Module, @NameBindings)
138 impl NamespaceResult {
139 fn is_unknown(&self) -> bool {
141 UnknownResult => true,
147 enum NameDefinition {
148 NoNameDefinition, //< The name was unbound.
149 ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
150 ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
153 impl Visitor<()> for Resolver {
154 fn visit_item(&mut self, item: &Item, _: ()) {
155 self.resolve_item(item);
157 fn visit_arm(&mut self, arm: &Arm, _: ()) {
158 self.resolve_arm(arm);
160 fn visit_block(&mut self, block: &Block, _: ()) {
161 self.resolve_block(block);
163 fn visit_expr(&mut self, expr: &Expr, _: ()) {
164 self.resolve_expr(expr);
166 fn visit_local(&mut self, local: &Local, _: ()) {
167 self.resolve_local(local);
169 fn visit_ty(&mut self, ty: &Ty, _: ()) {
170 self.resolve_type(ty);
174 /// Contains data for specific types of import directives.
175 enum ImportDirectiveSubclass {
176 SingleImport(Ident /* target */, Ident /* source */),
180 /// The context that we thread through while building the reduced graph.
182 enum ReducedGraphParent {
183 ModuleReducedGraphParent(@Module)
186 impl ReducedGraphParent {
187 fn module(&self) -> @Module {
189 ModuleReducedGraphParent(m) => {
196 enum ResolveResult<T> {
197 Failed, // Failed to resolve the name.
198 Indeterminate, // Couldn't determine due to unresolved globs.
199 Success(T) // Successfully resolved the import.
202 impl<T> ResolveResult<T> {
203 fn indeterminate(&self) -> bool {
204 match *self { Indeterminate => true, _ => false }
208 enum TypeParameters<'a> {
209 NoTypeParameters, //< No type parameters.
210 HasTypeParameters(&'a Generics, //< Type parameters.
211 NodeId, //< ID of the enclosing item
213 // The index to start numbering the type parameters at.
214 // This is zero if this is the outermost set of type
215 // parameters, or equal to the number of outer type
216 // parameters. For example, if we have:
219 // fn method<U>() { ... }
222 // The index at the method site will be 1, because the
223 // outer T had index 0.
226 // The kind of the rib used for type parameters.
230 // The rib kind controls the translation of argument or local definitions
231 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
234 // No translation needs to be applied.
237 // We passed through a function scope at the given node ID. Translate
238 // upvars as appropriate.
239 FunctionRibKind(NodeId /* func id */, NodeId /* body id */),
241 // We passed through an impl or trait and are now in one of its
242 // methods. Allow references to ty params that impl or trait
243 // binds. Disallow any other upvars (including other ty params that are
245 // parent; method itself
246 MethodRibKind(NodeId, MethodSort),
248 // We passed through a function *item* scope. Disallow upvars.
249 OpaqueFunctionRibKind,
251 // We're in a constant item. Can't refer to dynamic stuff.
255 // Methods can be required or provided. Required methods only occur in traits.
261 enum UseLexicalScopeFlag {
266 enum SearchThroughModulesFlag {
267 DontSearchThroughModules,
271 enum ModulePrefixResult {
273 PrefixFound(@Module, uint)
277 enum NameSearchType {
278 /// We're doing a name search in order to resolve a `use` directive.
281 /// We're doing a name search in order to resolve a path type, a path
282 /// expression, or a path pattern.
286 enum BareIdentifierPatternResolution {
287 FoundStructOrEnumVariant(Def, LastPrivate),
288 FoundConst(Def, LastPrivate),
289 BareIdentifierPatternUnresolved
292 // Specifies how duplicates should be handled when adding a child item if
293 // another item exists with the same name in some namespace.
295 enum DuplicateCheckingMode {
296 ForbidDuplicateModules,
297 ForbidDuplicateTypes,
298 ForbidDuplicateValues,
299 ForbidDuplicateTypesAndValues,
305 bindings: RefCell<HashMap<Name, DefLike>>,
310 fn new(kind: RibKind) -> Rib {
312 bindings: RefCell::new(HashMap::new()),
318 /// One import directive.
319 struct ImportDirective {
320 module_path: ~[Ident],
321 subclass: @ImportDirectiveSubclass,
324 is_public: bool, // see note in ImportResolution about how to use this
327 impl ImportDirective {
328 fn new(module_path: ~[Ident],
329 subclass: @ImportDirectiveSubclass,
335 module_path: module_path,
339 is_public: is_public,
344 /// The item that an import resolves to.
347 target_module: @Module,
348 bindings: @NameBindings,
352 fn new(target_module: @Module, bindings: @NameBindings) -> Target {
354 target_module: target_module,
360 /// An ImportResolution represents a particular `use` directive.
361 struct ImportResolution {
362 /// Whether this resolution came from a `use` or a `pub use`. Note that this
363 /// should *not* be used whenever resolution is being performed, this is
364 /// only looked at for glob imports statements currently. Privacy testing
365 /// occurs during a later phase of compilation.
366 is_public: Cell<bool>,
368 // The number of outstanding references to this name. When this reaches
369 // zero, outside modules can count on the targets being correct. Before
370 // then, all bets are off; future imports could override this name.
371 outstanding_references: Cell<uint>,
373 /// The value that this `use` directive names, if there is one.
374 value_target: RefCell<Option<Target>>,
375 /// The source node of the `use` directive leading to the value target
377 value_id: Cell<NodeId>,
379 /// The type that this `use` directive names, if there is one.
380 type_target: RefCell<Option<Target>>,
381 /// The source node of the `use` directive leading to the type target
383 type_id: Cell<NodeId>,
386 impl ImportResolution {
387 fn new(id: NodeId, is_public: bool) -> ImportResolution {
389 type_id: Cell::new(id),
390 value_id: Cell::new(id),
391 outstanding_references: Cell::new(0),
392 value_target: RefCell::new(None),
393 type_target: RefCell::new(None),
394 is_public: Cell::new(is_public),
398 fn target_for_namespace(&self, namespace: Namespace)
401 TypeNS => return self.type_target.get(),
402 ValueNS => return self.value_target.get(),
406 fn id(&self, namespace: Namespace) -> NodeId {
408 TypeNS => self.type_id.get(),
409 ValueNS => self.value_id.get(),
414 /// The link from a module up to its nearest parent node.
417 ModuleParentLink(@Module, Ident),
418 BlockParentLink(@Module, NodeId)
421 /// The type of module this is.
431 /// One node in the tree of modules.
433 parent_link: ParentLink,
434 def_id: Cell<Option<DefId>>,
435 kind: Cell<ModuleKind>,
438 children: RefCell<HashMap<Name, @NameBindings>>,
439 imports: RefCell<~[@ImportDirective]>,
441 // The external module children of this node that were declared with
443 external_module_children: RefCell<HashMap<Name, @Module>>,
445 // The anonymous children of this node. Anonymous children are pseudo-
446 // modules that are implicitly created around items contained within
449 // For example, if we have this:
457 // There will be an anonymous module created around `g` with the ID of the
458 // entry block for `f`.
459 anonymous_children: RefCell<HashMap<NodeId,@Module>>,
461 // The status of resolving each import in this module.
462 import_resolutions: RefCell<HashMap<Name, @ImportResolution>>,
464 // The number of unresolved globs that this module exports.
465 glob_count: Cell<uint>,
467 // The index of the import we're resolving.
468 resolved_import_count: Cell<uint>,
470 // Whether this module is populated. If not populated, any attempt to
471 // access the children must be preceded with a
472 // `populate_module_if_necessary` call.
473 populated: Cell<bool>,
477 fn new(parent_link: ParentLink,
478 def_id: Option<DefId>,
484 parent_link: parent_link,
485 def_id: Cell::new(def_id),
486 kind: Cell::new(kind),
487 is_public: is_public,
488 children: RefCell::new(HashMap::new()),
489 imports: RefCell::new(~[]),
490 external_module_children: RefCell::new(HashMap::new()),
491 anonymous_children: RefCell::new(HashMap::new()),
492 import_resolutions: RefCell::new(HashMap::new()),
493 glob_count: Cell::new(0),
494 resolved_import_count: Cell::new(0),
495 populated: Cell::new(!external),
499 fn all_imports_resolved(&self) -> bool {
500 let mut imports = self.imports.borrow_mut();
501 return imports.get().len() == self.resolved_import_count.get();
505 // Records a possibly-private type definition.
508 is_public: bool, // see note in ImportResolution about how to use this
509 module_def: Option<@Module>,
510 type_def: Option<Def>,
511 type_span: Option<Span>
514 // Records a possibly-private value definition.
517 is_public: bool, // see note in ImportResolution about how to use this
519 value_span: Option<Span>,
522 // Records the definitions (at most one for each namespace) that a name is
524 struct NameBindings {
525 type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
526 value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
529 /// Ways in which a trait can be referenced
530 enum TraitReferenceType {
531 TraitImplementation, // impl SomeTrait for T { ... }
532 TraitDerivation, // trait T : SomeTrait { ... }
533 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
537 /// Creates a new module in this set of name bindings.
538 fn define_module(&self,
539 parent_link: ParentLink,
540 def_id: Option<DefId>,
545 // Merges the module with the existing type def or creates a new one.
546 let module_ = @Module::new(parent_link, def_id, kind, external,
548 match self.type_def.get() {
550 self.type_def.set(Some(TypeNsDef {
551 is_public: is_public,
552 module_def: Some(module_),
558 self.type_def.set(Some(TypeNsDef {
559 is_public: is_public,
560 module_def: Some(module_),
562 type_def: type_def.type_def
568 /// Sets the kind of the module, creating a new one if necessary.
569 fn set_module_kind(&self,
570 parent_link: ParentLink,
571 def_id: Option<DefId>,
576 match self.type_def.get() {
578 let module = @Module::new(parent_link, def_id, kind,
579 external, is_public);
580 self.type_def.set(Some(TypeNsDef {
581 is_public: is_public,
582 module_def: Some(module),
588 match type_def.module_def {
590 let module = @Module::new(parent_link,
595 self.type_def.set(Some(TypeNsDef {
596 is_public: is_public,
597 module_def: Some(module),
598 type_def: type_def.type_def,
602 Some(module_def) => module_def.kind.set(kind),
608 /// Records a type definition.
609 fn define_type(&self, def: Def, sp: Span, is_public: bool) {
610 // Merges the type with the existing type def or creates a new one.
611 match self.type_def.get() {
613 self.type_def.set(Some(TypeNsDef {
617 is_public: is_public,
621 self.type_def.set(Some(TypeNsDef {
624 module_def: type_def.module_def,
625 is_public: is_public,
631 /// Records a value definition.
632 fn define_value(&self, def: Def, sp: Span, is_public: bool) {
633 self.value_def.set(Some(ValueNsDef {
635 value_span: Some(sp),
636 is_public: is_public,
640 /// Returns the module node if applicable.
641 fn get_module_if_available(&self) -> Option<@Module> {
642 let type_def = self.type_def.borrow();
643 match *type_def.get() {
644 Some(ref type_def) => (*type_def).module_def,
650 * Returns the module node. Fails if this node does not have a module
653 fn get_module(&self) -> @Module {
654 match self.get_module_if_available() {
656 fail!("get_module called on a node with no module \
659 Some(module_def) => module_def
663 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
665 TypeNS => return self.type_def.get().is_some(),
666 ValueNS => return self.value_def.get().is_some()
670 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
672 TypeNS => match self.type_def.get() {
673 Some(def) => def.is_public, None => false
675 ValueNS => match self.value_def.get() {
676 Some(def) => def.is_public, None => false
681 fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
684 match self.type_def.get() {
687 match type_def.type_def {
688 Some(type_def) => Some(type_def),
690 match type_def.module_def {
692 match module.def_id.get() {
693 Some(did) => Some(DefMod(did)),
705 match self.value_def.get() {
707 Some(value_def) => Some(value_def.def)
713 fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
714 if self.defined_in_namespace(namespace) {
717 match self.type_def.get() {
719 Some(type_def) => type_def.type_span
723 match self.value_def.get() {
725 Some(value_def) => value_def.value_span
735 fn NameBindings() -> NameBindings {
737 type_def: RefCell::new(None),
738 value_def: RefCell::new(None),
742 /// Interns the names of the primitive types.
743 struct PrimitiveTypeTable {
744 primitive_types: HashMap<Name, PrimTy>,
747 impl PrimitiveTypeTable {
748 fn intern(&mut self, string: &str, primitive_type: PrimTy) {
749 self.primitive_types.insert(token::intern(string), primitive_type);
753 fn PrimitiveTypeTable() -> PrimitiveTypeTable {
754 let mut table = PrimitiveTypeTable {
755 primitive_types: HashMap::new()
758 table.intern("bool", TyBool);
759 table.intern("char", TyChar);
760 table.intern("f32", TyFloat(TyF32));
761 table.intern("f64", TyFloat(TyF64));
762 table.intern("int", TyInt(TyI));
763 table.intern("i8", TyInt(TyI8));
764 table.intern("i16", TyInt(TyI16));
765 table.intern("i32", TyInt(TyI32));
766 table.intern("i64", TyInt(TyI64));
767 table.intern("str", TyStr);
768 table.intern("uint", TyUint(TyU));
769 table.intern("u8", TyUint(TyU8));
770 table.intern("u16", TyUint(TyU16));
771 table.intern("u32", TyUint(TyU32));
772 table.intern("u64", TyUint(TyU64));
778 fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
781 ModuleError => "module",
783 ValueError => "value",
787 fn Resolver(session: Session,
788 lang_items: @LanguageItems,
789 crate_span: Span) -> Resolver {
790 let graph_root = @NameBindings();
792 graph_root.define_module(NoParentLink,
793 Some(DefId { krate: 0, node: 0 }),
799 let current_module = graph_root.get_module();
801 let this = Resolver {
803 lang_items: lang_items,
805 // The outermost module has def ID 0; this is not reflected in the
808 graph_root: graph_root,
810 method_map: @RefCell::new(HashMap::new()),
811 structs: HashSet::new(),
813 unresolved_imports: 0,
815 current_module: current_module,
816 value_ribs: @RefCell::new(~[]),
817 type_ribs: @RefCell::new(~[]),
818 label_ribs: @RefCell::new(~[]),
820 current_trait_refs: None,
822 self_ident: special_idents::self_,
823 type_self_ident: special_idents::type_self,
825 primitive_type_table: @PrimitiveTypeTable(),
827 namespaces: ~[ TypeNS, ValueNS ],
829 def_map: @RefCell::new(HashMap::new()),
830 export_map2: @RefCell::new(HashMap::new()),
831 trait_map: HashMap::new(),
832 used_imports: HashSet::new(),
833 external_exports: HashSet::new(),
834 last_private: HashMap::new(),
842 /// The main resolver class.
845 lang_items: @LanguageItems,
847 graph_root: @NameBindings,
849 method_map: @RefCell<HashMap<Name, HashSet<DefId>>>,
850 structs: HashSet<DefId>,
852 // The number of imports that are currently unresolved.
853 unresolved_imports: uint,
855 // The module that represents the current item scope.
856 current_module: @Module,
858 // The current set of local scopes, for values.
859 // FIXME #4948: Reuse ribs to avoid allocation.
860 value_ribs: @RefCell<~[@Rib]>,
862 // The current set of local scopes, for types.
863 type_ribs: @RefCell<~[@Rib]>,
865 // The current set of local scopes, for labels.
866 label_ribs: @RefCell<~[@Rib]>,
868 // The trait that the current context can refer to.
869 current_trait_refs: Option<~[DefId]>,
871 // The ident for the keyword "self".
873 // The ident for the non-keyword "Self".
874 type_self_ident: Ident,
876 // The idents for the primitive types.
877 primitive_type_table: @PrimitiveTypeTable,
879 // The four namespaces.
880 namespaces: ~[Namespace],
883 export_map2: ExportMap2,
885 external_exports: ExternalExports,
886 last_private: LastPrivateMap,
888 // Whether or not to print error messages. Can be set to true
889 // when getting additional info for error message suggestions,
890 // so as to avoid printing duplicate errors
893 used_imports: HashSet<(NodeId, Namespace)>,
896 struct BuildReducedGraphVisitor<'a> {
897 resolver: &'a mut Resolver,
900 impl<'a> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a> {
902 fn visit_item(&mut self, item: &Item, context: ReducedGraphParent) {
903 let p = self.resolver.build_reduced_graph_for_item(item, context);
904 visit::walk_item(self, item, p);
907 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem,
908 context: ReducedGraphParent) {
909 self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
912 let mut v = BuildReducedGraphVisitor{ resolver: r };
913 visit::walk_foreign_item(&mut v, foreign_item, c);
917 fn visit_view_item(&mut self, view_item: &ViewItem, context: ReducedGraphParent) {
918 self.resolver.build_reduced_graph_for_view_item(view_item, context);
921 fn visit_block(&mut self, block: &Block, context: ReducedGraphParent) {
922 let np = self.resolver.build_reduced_graph_for_block(block, context);
923 visit::walk_block(self, block, np);
928 struct UnusedImportCheckVisitor<'a> { resolver: &'a mut Resolver }
930 impl<'a> Visitor<()> for UnusedImportCheckVisitor<'a> {
931 fn visit_view_item(&mut self, vi: &ViewItem, _: ()) {
932 self.resolver.check_for_item_unused_imports(vi);
933 visit::walk_view_item(self, vi, ());
938 /// The main name resolution procedure.
939 fn resolve(&mut self, krate: &ast::Crate) {
940 self.build_reduced_graph(krate);
941 self.session.abort_if_errors();
943 self.resolve_imports();
944 self.session.abort_if_errors();
946 self.record_exports();
947 self.session.abort_if_errors();
949 self.resolve_crate(krate);
950 self.session.abort_if_errors();
952 self.check_for_unused_imports(krate);
956 // Reduced graph building
958 // Here we build the "reduced graph": the graph of the module tree without
959 // any imports resolved.
962 /// Constructs the reduced graph for the entire crate.
963 fn build_reduced_graph(&mut self, krate: &ast::Crate) {
965 ModuleReducedGraphParent(self.graph_root.get_module());
967 let mut visitor = BuildReducedGraphVisitor { resolver: self, };
968 visit::walk_crate(&mut visitor, krate, initial_parent);
971 /// Returns the current module tracked by the reduced graph parent.
972 fn get_module_from_parent(&mut self,
973 reduced_graph_parent: ReducedGraphParent)
975 match reduced_graph_parent {
976 ModuleReducedGraphParent(module_) => {
983 * Adds a new child item to the module definition of the parent node and
984 * returns its corresponding name bindings as well as the current parent.
985 * Or, if we're inside a block, creates (or reuses) an anonymous module
986 * corresponding to the innermost block ID and returns the name bindings
987 * as well as the newly-created parent.
989 * If this node does not have a module definition and we are not inside
992 fn add_child(&mut self,
994 reduced_graph_parent: ReducedGraphParent,
995 duplicate_checking_mode: DuplicateCheckingMode,
996 // For printing errors
998 -> (@NameBindings, ReducedGraphParent) {
999 // If this is the immediate descendant of a module, then we add the
1000 // child name directly. Otherwise, we create or reuse an anonymous
1001 // module and add the child to that.
1004 match reduced_graph_parent {
1005 ModuleReducedGraphParent(parent_module) => {
1006 module_ = parent_module;
1010 // Add or reuse the child.
1011 let new_parent = ModuleReducedGraphParent(module_);
1013 let children = module_.children.borrow();
1014 children.get().find_copy(&name.name)
1018 let child = @NameBindings();
1019 let mut children = module_.children.borrow_mut();
1020 children.get().insert(name.name, child);
1021 return (child, new_parent);
1024 // Enforce the duplicate checking mode:
1026 // * If we're requesting duplicate module checking, check that
1027 // there isn't a module in the module with the same name.
1029 // * If we're requesting duplicate type checking, check that
1030 // there isn't a type in the module with the same name.
1032 // * If we're requesting duplicate value checking, check that
1033 // there isn't a value in the module with the same name.
1035 // * If we're requesting duplicate type checking and duplicate
1036 // value checking, check that there isn't a duplicate type
1037 // and a duplicate value with the same name.
1039 // * If no duplicate checking was requested at all, do
1042 let mut duplicate_type = NoError;
1043 let ns = match duplicate_checking_mode {
1044 ForbidDuplicateModules => {
1045 if child.get_module_if_available().is_some() {
1046 duplicate_type = ModuleError;
1050 ForbidDuplicateTypes => {
1051 match child.def_for_namespace(TypeNS) {
1052 Some(DefMod(_)) | None => {}
1053 Some(_) => duplicate_type = TypeError
1057 ForbidDuplicateValues => {
1058 if child.defined_in_namespace(ValueNS) {
1059 duplicate_type = ValueError;
1063 ForbidDuplicateTypesAndValues => {
1065 match child.def_for_namespace(TypeNS) {
1066 Some(DefMod(_)) | None => {}
1069 duplicate_type = TypeError;
1072 if child.defined_in_namespace(ValueNS) {
1073 duplicate_type = ValueError;
1078 OverwriteDuplicates => None
1080 if duplicate_type != NoError {
1081 // Return an error here by looking up the namespace that
1082 // had the duplicate.
1083 let ns = ns.unwrap();
1084 self.resolve_error(sp,
1085 format!("duplicate definition of {} `{}`",
1086 namespace_error_to_str(duplicate_type),
1087 token::get_ident(name)));
1089 let r = child.span_for_namespace(ns);
1090 for sp in r.iter() {
1091 self.session.span_note(*sp,
1092 format!("first definition of {} `{}` here",
1093 namespace_error_to_str(duplicate_type),
1094 token::get_ident(name)));
1098 return (child, new_parent);
1103 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1104 // If the block has view items, we need an anonymous module.
1105 if block.view_items.len() > 0 {
1109 // Check each statement.
1110 for statement in block.stmts.iter() {
1111 match statement.node {
1112 StmtDecl(declaration, _) => {
1113 match declaration.node {
1128 // If we found neither view items nor items, we don't need to create
1129 // an anonymous module.
1134 fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Ident)
1137 ModuleReducedGraphParent(module_) => {
1138 return ModuleParentLink(module_, name);
1143 /// Constructs the reduced graph for one item.
1144 fn build_reduced_graph_for_item(&mut self,
1146 parent: ReducedGraphParent)
1147 -> ReducedGraphParent
1149 let ident = item.ident;
1151 let is_public = item.vis == ast::Public;
1155 let (name_bindings, new_parent) =
1156 self.add_child(ident, parent, ForbidDuplicateModules, sp);
1158 let parent_link = self.get_parent_link(new_parent, ident);
1159 let def_id = DefId { krate: 0, node: item.id };
1160 name_bindings.define_module(parent_link,
1164 item.vis == ast::Public,
1167 ModuleReducedGraphParent(name_bindings.get_module())
1170 ItemForeignMod(..) => parent,
1172 // These items live in the value namespace.
1173 ItemStatic(_, m, _) => {
1174 let (name_bindings, _) =
1175 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1176 let mutbl = m == ast::MutMutable;
1178 name_bindings.define_value
1179 (DefStatic(local_def(item.id), mutbl), sp, is_public);
1182 ItemFn(_, purity, _, _, _) => {
1183 let (name_bindings, new_parent) =
1184 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1186 let def = DefFn(local_def(item.id), purity);
1187 name_bindings.define_value(def, sp, is_public);
1191 // These items live in the type namespace.
1193 let (name_bindings, _) =
1194 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1196 name_bindings.define_type
1197 (DefTy(local_def(item.id)), sp, is_public);
1201 ItemEnum(ref enum_definition, _) => {
1202 let (name_bindings, new_parent) =
1203 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1205 name_bindings.define_type
1206 (DefTy(local_def(item.id)), sp, is_public);
1208 for &variant in (*enum_definition).variants.iter() {
1209 self.build_reduced_graph_for_variant(
1218 // These items live in both the type and value namespaces.
1219 ItemStruct(struct_def, _) => {
1220 // Adding to both Type and Value namespaces or just Type?
1221 let (forbid, ctor_id) = match struct_def.ctor_id {
1222 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1223 None => (ForbidDuplicateTypes, None)
1226 let (name_bindings, new_parent) = self.add_child(ident, parent, forbid, sp);
1228 // Define a name in the type namespace.
1229 name_bindings.define_type(DefTy(local_def(item.id)), sp, is_public);
1231 // If this is a newtype or unit-like struct, define a name
1232 // in the value namespace as well
1233 ctor_id.while_some(|cid| {
1234 name_bindings.define_value(DefStruct(local_def(cid)), sp,
1239 // Record the def ID of this struct.
1240 self.structs.insert(local_def(item.id));
1245 ItemImpl(_, None, ty, ref methods) => {
1246 // If this implements an anonymous trait, then add all the
1247 // methods within to a new module, if the type was defined
1248 // within this module.
1250 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1251 // should modify anonymous traits to only be implementable in
1252 // the same module that declared the type.
1254 // Create the module and add all methods.
1256 TyPath(ref path, _, _) if path.segments.len() == 1 => {
1257 let name = path_to_ident(path);
1259 let existing_parent_opt = {
1260 let children = parent.module().children.borrow();
1261 children.get().find_copy(&name.name)
1263 let new_parent = match existing_parent_opt {
1264 // It already exists
1265 Some(child) if child.get_module_if_available()
1267 child.get_module().kind.get() ==
1269 ModuleReducedGraphParent(child.get_module())
1271 // Create the module
1273 let (name_bindings, new_parent) =
1274 self.add_child(name,
1276 ForbidDuplicateModules,
1280 self.get_parent_link(new_parent, ident);
1281 let def_id = local_def(item.id);
1284 !name_bindings.defined_in_namespace(ns) ||
1285 name_bindings.defined_in_public_namespace(ns);
1287 name_bindings.define_module(parent_link,
1294 ModuleReducedGraphParent(
1295 name_bindings.get_module())
1299 // For each method...
1300 for method in methods.iter() {
1301 // Add the method to the module.
1302 let ident = method.ident;
1303 let (method_name_bindings, _) =
1304 self.add_child(ident,
1306 ForbidDuplicateValues,
1308 let def = match method.explicit_self.node {
1310 // Static methods become
1311 // `def_static_method`s.
1312 DefStaticMethod(local_def(method.id),
1318 // Non-static methods become
1320 DefMethod(local_def(method.id), None)
1324 let is_public = method.vis == ast::Public;
1325 method_name_bindings.define_value(def,
1336 ItemImpl(_, Some(_), _, _) => parent,
1338 ItemTrait(_, _, ref methods) => {
1339 let (name_bindings, new_parent) =
1340 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1342 // Add all the methods within to a new module.
1343 let parent_link = self.get_parent_link(parent, ident);
1344 name_bindings.define_module(parent_link,
1345 Some(local_def(item.id)),
1348 item.vis == ast::Public,
1350 let module_parent = ModuleReducedGraphParent(name_bindings.
1353 // Add the names of all the methods to the trait info.
1354 let mut method_names = HashMap::new();
1355 for method in methods.iter() {
1356 let ty_m = trait_method_to_ty_method(method);
1358 let ident = ty_m.ident;
1360 // Add it as a name in the trait module.
1361 let def = match ty_m.explicit_self.node {
1363 // Static methods become `def_static_method`s.
1364 DefStaticMethod(local_def(ty_m.id),
1365 FromTrait(local_def(item.id)),
1369 // Non-static methods become `def_method`s.
1370 DefMethod(local_def(ty_m.id),
1371 Some(local_def(item.id)))
1375 let (method_name_bindings, _) =
1376 self.add_child(ident,
1378 ForbidDuplicateValues,
1380 method_name_bindings.define_value(def, ty_m.span, true);
1382 // Add it to the trait info if not static.
1383 match ty_m.explicit_self.node {
1386 method_names.insert(ident.name, ());
1391 let def_id = local_def(item.id);
1392 for (name, _) in method_names.iter() {
1393 let mut method_map = self.method_map.borrow_mut();
1394 if !method_map.get().contains_key(name) {
1395 method_map.get().insert(*name, HashSet::new());
1397 match method_map.get().find_mut(name) {
1398 Some(s) => { s.insert(def_id); },
1399 _ => fail!("can't happen"),
1403 name_bindings.define_type(DefTrait(def_id), sp, is_public);
1406 ItemMac(..) => parent
1410 // Constructs the reduced graph for one variant. Variants exist in the
1411 // type and/or value namespaces.
1412 fn build_reduced_graph_for_variant(&mut self,
1415 parent: ReducedGraphParent,
1416 parent_public: bool) {
1417 let ident = variant.node.name;
1418 // FIXME: this is unfortunate to have to do this privacy calculation
1419 // here. This should be living in middle::privacy, but it's
1420 // necessary to keep around in some form becaues of glob imports...
1421 let is_public = parent_public && variant.node.vis != ast::Private;
1423 match variant.node.kind {
1424 TupleVariantKind(_) => {
1425 let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues,
1427 child.define_value(DefVariant(item_id,
1428 local_def(variant.node.id), false),
1429 variant.span, is_public);
1431 StructVariantKind(_) => {
1432 let (child, _) = self.add_child(ident, parent, ForbidDuplicateTypesAndValues,
1434 child.define_type(DefVariant(item_id,
1435 local_def(variant.node.id), true),
1436 variant.span, is_public);
1437 self.structs.insert(local_def(variant.node.id));
1442 /// Constructs the reduced graph for one 'view item'. View items consist
1443 /// of imports and use directives.
1444 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1445 parent: ReducedGraphParent) {
1446 match view_item.node {
1447 ViewItemUse(ref view_paths) => {
1448 for view_path in view_paths.iter() {
1449 // Extract and intern the module part of the path. For
1450 // globs and lists, the path is found directly in the AST;
1451 // for simple paths we have to munge the path a little.
1453 let mut module_path = ~[];
1454 match view_path.node {
1455 ViewPathSimple(_, ref full_path, _) => {
1456 let path_len = full_path.segments.len();
1457 assert!(path_len != 0);
1459 for (i, segment) in full_path.segments
1462 if i != path_len - 1 {
1463 module_path.push(segment.identifier)
1468 ViewPathGlob(ref module_ident_path, _) |
1469 ViewPathList(ref module_ident_path, _, _) => {
1470 for segment in module_ident_path.segments.iter() {
1471 module_path.push(segment.identifier)
1476 // Build up the import directives.
1477 let module_ = self.get_module_from_parent(parent);
1478 let is_public = view_item.vis == ast::Public;
1479 match view_path.node {
1480 ViewPathSimple(binding, ref full_path, id) => {
1482 full_path.segments.last().unwrap().identifier;
1483 let subclass = @SingleImport(binding,
1485 self.build_import_directive(module_,
1492 ViewPathList(_, ref source_idents, _) => {
1493 for source_ident in source_idents.iter() {
1494 let name = source_ident.node.name;
1495 let subclass = @SingleImport(name, name);
1496 self.build_import_directive(
1498 module_path.clone(),
1501 source_ident.node.id,
1505 ViewPathGlob(_, id) => {
1506 self.build_import_directive(module_,
1517 ViewItemExternMod(name, _, node_id) => {
1518 // n.b. we don't need to look at the path option here, because cstore already did
1519 match self.session.cstore.find_extern_mod_stmt_cnum(node_id) {
1521 let def_id = DefId { krate: crate_id, node: 0 };
1522 self.external_exports.insert(def_id);
1523 let parent_link = ModuleParentLink
1524 (self.get_module_from_parent(parent), name);
1525 let external_module = @Module::new(parent_link,
1532 let mut external_module_children =
1533 parent.module().external_module_children.borrow_mut();
1534 external_module_children.get().insert(
1539 self.build_reduced_graph_for_external_crate(
1542 None => {} // Ignore.
1548 /// Constructs the reduced graph for one foreign item.
1549 fn build_reduced_graph_for_foreign_item(&mut self,
1550 foreign_item: &ForeignItem,
1551 parent: ReducedGraphParent,
1553 ReducedGraphParent|) {
1554 let name = foreign_item.ident;
1555 let is_public = foreign_item.vis == ast::Public;
1556 let (name_bindings, new_parent) =
1557 self.add_child(name, parent, ForbidDuplicateValues,
1560 match foreign_item.node {
1561 ForeignItemFn(_, ref generics) => {
1562 let def = DefFn(local_def(foreign_item.id), UnsafeFn);
1563 name_bindings.define_value(def, foreign_item.span, is_public);
1565 self.with_type_parameter_rib(
1566 HasTypeParameters(generics,
1570 |this| f(this, new_parent));
1572 ForeignItemStatic(_, m) => {
1573 let def = DefStatic(local_def(foreign_item.id), m);
1574 name_bindings.define_value(def, foreign_item.span, is_public);
1581 fn build_reduced_graph_for_block(&mut self,
1583 parent: ReducedGraphParent)
1584 -> ReducedGraphParent
1586 if self.block_needs_anonymous_module(block) {
1587 let block_id = block.id;
1589 debug!("(building reduced graph for block) creating a new \
1590 anonymous module for block {}",
1593 let parent_module = self.get_module_from_parent(parent);
1594 let new_module = @Module::new(
1595 BlockParentLink(parent_module, block_id),
1597 AnonymousModuleKind,
1601 let mut anonymous_children = parent_module.anonymous_children
1603 anonymous_children.get().insert(block_id, new_module);
1604 ModuleReducedGraphParent(new_module)
1611 fn handle_external_def(&mut self,
1614 child_name_bindings: @NameBindings,
1617 new_parent: ReducedGraphParent) {
1618 debug!("(building reduced graph for \
1619 external crate) building external def, priv {:?}",
1621 let is_public = vis == ast::Public;
1622 let is_exported = is_public && match new_parent {
1623 ModuleReducedGraphParent(module) => {
1624 match module.def_id.get() {
1626 Some(did) => self.external_exports.contains(&did)
1631 self.external_exports.insert(def_id_of_def(def));
1634 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1636 match child_name_bindings.type_def.get() {
1637 Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1638 debug!("(building reduced graph for external crate) \
1639 already created module");
1640 module_def.def_id.set(Some(def_id));
1643 debug!("(building reduced graph for \
1644 external crate) building module \
1646 let parent_link = self.get_parent_link(new_parent, ident);
1648 child_name_bindings.define_module(parent_link,
1661 DefMod(_) | DefForeignMod(_) => {}
1662 DefVariant(_, variant_id, is_struct) => {
1663 debug!("(building reduced graph for external crate) building \
1666 // We assume the parent is visible, or else we wouldn't have seen
1667 // it. Also variants are public-by-default if the parent was also
1669 let is_public = vis != ast::Private;
1671 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1672 self.structs.insert(variant_id);
1674 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1677 DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
1678 debug!("(building reduced graph for external \
1679 crate) building value (fn/static) {}", final_ident);
1680 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1682 DefTrait(def_id) => {
1683 debug!("(building reduced graph for external \
1684 crate) building type {}", final_ident);
1686 // If this is a trait, add all the method names
1687 // to the trait info.
1689 let method_def_ids =
1690 csearch::get_trait_method_def_ids(self.session.cstore, def_id);
1691 let mut interned_method_names = HashSet::new();
1692 for &method_def_id in method_def_ids.iter() {
1693 let (method_name, explicit_self) =
1694 csearch::get_method_name_and_explicit_self(self.session.cstore,
1697 debug!("(building reduced graph for \
1698 external crate) ... adding \
1700 token::get_ident(method_name));
1702 // Add it to the trait info if not static.
1703 if explicit_self != SelfStatic {
1704 interned_method_names.insert(method_name.name);
1707 self.external_exports.insert(method_def_id);
1710 for name in interned_method_names.iter() {
1711 let mut method_map = self.method_map.borrow_mut();
1712 if !method_map.get().contains_key(name) {
1713 method_map.get().insert(*name, HashSet::new());
1715 match method_map.get().find_mut(name) {
1716 Some(s) => { s.insert(def_id); },
1717 _ => fail!("can't happen"),
1721 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1723 // Define a module if necessary.
1724 let parent_link = self.get_parent_link(new_parent, ident);
1725 child_name_bindings.set_module_kind(parent_link,
1733 debug!("(building reduced graph for external \
1734 crate) building type {}", final_ident);
1736 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1738 DefStruct(def_id) => {
1739 debug!("(building reduced graph for external \
1740 crate) building type and value for {}",
1742 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1743 if csearch::get_struct_fields(self.session.cstore, def_id).len() == 0 {
1744 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1746 self.structs.insert(def_id);
1749 debug!("(building reduced graph for external crate) \
1750 ignoring {:?}", def);
1751 // Ignored; handled elsewhere.
1753 DefArg(..) | DefLocal(..) | DefPrimTy(..) |
1754 DefTyParam(..) | DefBinding(..) |
1755 DefUse(..) | DefUpvar(..) | DefRegion(..) |
1756 DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
1757 fail!("didn't expect `{:?}`", def);
1762 /// Builds the reduced graph for a single item in an external crate.
1763 fn build_reduced_graph_for_external_crate_def(&mut self,
1767 visibility: Visibility) {
1770 // Add the new child item, if necessary.
1772 DefForeignMod(def_id) => {
1773 // Foreign modules have no names. Recur and populate
1775 csearch::each_child_of_item(self.session.cstore,
1780 self.build_reduced_graph_for_external_crate_def(
1788 let (child_name_bindings, new_parent) =
1789 self.add_child(ident,
1790 ModuleReducedGraphParent(root),
1791 OverwriteDuplicates,
1794 self.handle_external_def(def,
1796 child_name_bindings,
1797 token::get_ident(ident).get(),
1804 // We only process static methods of impls here.
1805 match csearch::get_type_name_if_impl(self.session.cstore, def) {
1807 Some(final_ident) => {
1808 let static_methods_opt =
1809 csearch::get_static_methods_if_impl(self.session.cstore, def);
1810 match static_methods_opt {
1811 Some(ref static_methods) if
1812 static_methods.len() >= 1 => {
1813 debug!("(building reduced graph for \
1814 external crate) processing \
1815 static methods for type name {}",
1816 token::get_ident(final_ident));
1818 let (child_name_bindings, new_parent) =
1821 ModuleReducedGraphParent(root),
1822 OverwriteDuplicates,
1825 // Process the static methods. First,
1826 // create the module.
1828 match child_name_bindings.type_def.get() {
1830 module_def: Some(module_def),
1833 // We already have a module. This
1835 type_module = module_def;
1837 // Mark it as an impl module if
1839 type_module.kind.set(ImplModuleKind);
1843 self.get_parent_link(new_parent,
1845 child_name_bindings.define_module(
1853 child_name_bindings.
1858 // Add each static method to the module.
1860 ModuleReducedGraphParent(type_module);
1861 for static_method_info in
1862 static_methods.iter() {
1863 let ident = static_method_info.ident;
1864 debug!("(building reduced graph for \
1865 external crate) creating \
1866 static method '{}'",
1867 token::get_ident(ident));
1869 let (method_name_bindings, _) =
1870 self.add_child(ident,
1872 OverwriteDuplicates,
1875 static_method_info.def_id,
1876 static_method_info.purity);
1878 method_name_bindings.define_value(
1880 visibility == ast::Public);
1884 // Otherwise, do nothing.
1885 Some(_) | None => {}
1891 debug!("(building reduced graph for external crate) \
1897 /// Builds the reduced graph rooted at the given external module.
1898 fn populate_external_module(&mut self, module: @Module) {
1899 debug!("(populating external module) attempting to populate {}",
1900 self.module_to_str(module));
1902 let def_id = match module.def_id.get() {
1904 debug!("(populating external module) ... no def ID!");
1907 Some(def_id) => def_id,
1910 csearch::each_child_of_item(self.session.cstore,
1912 |def_like, child_ident, visibility| {
1913 debug!("(populating external module) ... found ident: {}",
1914 token::get_ident(child_ident));
1915 self.build_reduced_graph_for_external_crate_def(module,
1920 module.populated.set(true)
1923 /// Ensures that the reduced graph rooted at the given external module
1924 /// is built, building it if it is not.
1925 fn populate_module_if_necessary(&mut self, module: @Module) {
1926 if !module.populated.get() {
1927 self.populate_external_module(module)
1929 assert!(module.populated.get())
1932 /// Builds the reduced graph rooted at the 'use' directive for an external
1934 fn build_reduced_graph_for_external_crate(&mut self,
1936 csearch::each_top_level_item_of_crate(self.session.cstore,
1941 |def_like, ident, visibility| {
1942 self.build_reduced_graph_for_external_crate_def(root,
1949 /// Creates and adds an import directive to the given module.
1950 fn build_import_directive(&mut self,
1952 module_path: ~[Ident],
1953 subclass: @ImportDirectiveSubclass,
1957 let directive = @ImportDirective::new(module_path,
1962 let mut imports = module_.imports.borrow_mut();
1963 imports.get().push(directive);
1966 // Bump the reference count on the name. Or, if this is a glob, set
1967 // the appropriate flag.
1970 SingleImport(target, _) => {
1971 debug!("(building import directive) building import \
1973 self.idents_to_str(directive.module_path),
1974 token::get_ident(target));
1976 let mut import_resolutions = module_.import_resolutions
1978 match import_resolutions.get().find(&target.name) {
1979 Some(&resolution) => {
1980 debug!("(building import directive) bumping \
1982 resolution.outstanding_references.set(
1983 resolution.outstanding_references.get() + 1);
1985 // the source of this name is different now
1986 resolution.type_id.set(id);
1987 resolution.value_id.set(id);
1990 debug!("(building import directive) creating new");
1991 let resolution = @ImportResolution::new(id, is_public);
1992 resolution.outstanding_references.set(1);
1993 import_resolutions.get().insert(target.name,
1999 // Set the glob flag. This tells us that we don't know the
2000 // module's exports ahead of time.
2002 module_.glob_count.set(module_.glob_count.get() + 1);
2006 self.unresolved_imports += 1;
2009 // Import resolution
2011 // This is a fixed-point algorithm. We resolve imports until our efforts
2012 // are stymied by an unresolved import; then we bail out of the current
2013 // module and continue. We terminate successfully once no more imports
2014 // remain or unsuccessfully when no forward progress in resolving imports
2017 /// Resolves all imports for the crate. This method performs the fixed-
2018 /// point iteration.
2019 fn resolve_imports(&mut self) {
2021 let mut prev_unresolved_imports = 0;
2023 debug!("(resolving imports) iteration {}, {} imports left",
2024 i, self.unresolved_imports);
2026 let module_root = self.graph_root.get_module();
2027 self.resolve_imports_for_module_subtree(module_root);
2029 if self.unresolved_imports == 0 {
2030 debug!("(resolving imports) success");
2034 if self.unresolved_imports == prev_unresolved_imports {
2035 self.report_unresolved_imports(module_root);
2040 prev_unresolved_imports = self.unresolved_imports;
2044 /// Attempts to resolve imports for the given module and all of its
2046 fn resolve_imports_for_module_subtree(&mut self,
2048 debug!("(resolving imports for module subtree) resolving {}",
2049 self.module_to_str(module_));
2050 self.resolve_imports_for_module(module_);
2052 self.populate_module_if_necessary(module_);
2054 let children = module_.children.borrow();
2055 for (_, &child_node) in children.get().iter() {
2056 match child_node.get_module_if_available() {
2060 Some(child_module) => {
2061 self.resolve_imports_for_module_subtree(child_module);
2067 let anonymous_children = module_.anonymous_children.borrow();
2068 for (_, &child_module) in anonymous_children.get().iter() {
2069 self.resolve_imports_for_module_subtree(child_module);
2073 /// Attempts to resolve imports for the given module only.
2074 fn resolve_imports_for_module(&mut self, module: @Module) {
2075 if module.all_imports_resolved() {
2076 debug!("(resolving imports for module) all imports resolved for \
2078 self.module_to_str(module));
2082 let mut imports = module.imports.borrow_mut();
2083 let import_count = imports.get().len();
2084 while module.resolved_import_count.get() < import_count {
2085 let import_index = module.resolved_import_count.get();
2086 let import_directive = imports.get()[import_index];
2087 match self.resolve_import_for_module(module, import_directive) {
2089 // We presumably emitted an error. Continue.
2090 let msg = format!("failed to resolve import `{}`",
2091 self.import_path_to_str(
2092 import_directive.module_path,
2093 *import_directive.subclass));
2094 self.resolve_error(import_directive.span, msg);
2097 // Bail out. We'll come around next time.
2105 module.resolved_import_count
2106 .set(module.resolved_import_count.get() + 1);
2110 fn idents_to_str(&mut self, idents: &[Ident]) -> ~str {
2111 let mut first = true;
2112 let mut result = ~"";
2113 for ident in idents.iter() {
2117 result.push_str("::")
2119 result.push_str(token::get_ident(*ident).get());
2124 fn path_idents_to_str(&mut self, path: &Path) -> ~str {
2125 let identifiers: ~[ast::Ident] = path.segments
2127 .map(|seg| seg.identifier)
2129 self.idents_to_str(identifiers)
2132 fn import_directive_subclass_to_str(&mut self,
2133 subclass: ImportDirectiveSubclass)
2136 SingleImport(_, source) => {
2137 token::get_ident(source).get().to_str()
2143 fn import_path_to_str(&mut self,
2145 subclass: ImportDirectiveSubclass)
2147 if idents.is_empty() {
2148 self.import_directive_subclass_to_str(subclass)
2151 self.idents_to_str(idents),
2152 self.import_directive_subclass_to_str(subclass)))
2156 /// Attempts to resolve the given import. The return value indicates
2157 /// failure if we're certain the name does not exist, indeterminate if we
2158 /// don't know whether the name exists at the moment due to other
2159 /// currently-unresolved imports, or success if we know the name exists.
2160 /// If successful, the resolved bindings are written into the module.
2161 fn resolve_import_for_module(&mut self,
2163 import_directive: @ImportDirective)
2164 -> ResolveResult<()> {
2165 let mut resolution_result = Failed;
2166 let module_path = &import_directive.module_path;
2168 debug!("(resolving import for module) resolving import `{}::...` in \
2170 self.idents_to_str(*module_path),
2171 self.module_to_str(module_));
2173 // First, resolve the module path for the directive, if necessary.
2174 let container = if module_path.len() == 0 {
2175 // Use the crate root.
2176 Some((self.graph_root.get_module(), LastMod(AllPublic)))
2178 match self.resolve_module_path(module_,
2180 DontUseLexicalScope,
2181 import_directive.span,
2186 resolution_result = Indeterminate;
2189 Success(container) => Some(container),
2195 Some((containing_module, lp)) => {
2196 // We found the module that the target is contained
2197 // within. Attempt to resolve the import within it.
2199 match *import_directive.subclass {
2200 SingleImport(target, source) => {
2202 self.resolve_single_import(module_,
2211 self.resolve_glob_import(module_,
2213 import_directive.id,
2214 import_directive.is_public,
2221 // Decrement the count of unresolved imports.
2222 match resolution_result {
2224 assert!(self.unresolved_imports >= 1);
2225 self.unresolved_imports -= 1;
2228 // Nothing to do here; just return the error.
2232 // Decrement the count of unresolved globs if necessary. But only if
2233 // the resolution result is indeterminate -- otherwise we'll stop
2234 // processing imports here. (See the loop in
2235 // resolve_imports_for_module.)
2237 if !resolution_result.indeterminate() {
2238 match *import_directive.subclass {
2240 assert!(module_.glob_count.get() >= 1);
2241 module_.glob_count.set(module_.glob_count.get() - 1);
2243 SingleImport(..) => {
2249 return resolution_result;
2252 fn create_name_bindings_from_module(module: @Module) -> NameBindings {
2254 type_def: RefCell::new(Some(TypeNsDef {
2256 module_def: Some(module),
2260 value_def: RefCell::new(None),
2264 fn resolve_single_import(&mut self,
2266 containing_module: @Module,
2269 directive: &ImportDirective,
2271 -> ResolveResult<()> {
2272 debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2273 `{}` id {}, last private {:?}",
2274 token::get_ident(target),
2275 self.module_to_str(containing_module),
2276 token::get_ident(source),
2277 self.module_to_str(module_),
2283 LastImport{..} => self.session.span_bug(directive.span,
2284 "Not expecting Import here, must be LastMod"),
2287 // We need to resolve both namespaces for this to succeed.
2290 let mut value_result = UnknownResult;
2291 let mut type_result = UnknownResult;
2293 // Search for direct children of the containing module.
2294 self.populate_module_if_necessary(containing_module);
2297 let children = containing_module.children.borrow();
2298 match children.get().find(&source.name) {
2302 Some(child_name_bindings) => {
2303 if child_name_bindings.defined_in_namespace(ValueNS) {
2304 value_result = BoundResult(containing_module,
2305 *child_name_bindings);
2307 if child_name_bindings.defined_in_namespace(TypeNS) {
2308 type_result = BoundResult(containing_module,
2309 *child_name_bindings);
2315 // Unless we managed to find a result in both namespaces (unlikely),
2316 // search imports as well.
2317 let mut value_used_reexport = false;
2318 let mut type_used_reexport = false;
2319 match (value_result, type_result) {
2320 (BoundResult(..), BoundResult(..)) => {} // Continue.
2322 // If there is an unresolved glob at this point in the
2323 // containing module, bail out. We don't know enough to be
2324 // able to resolve this import.
2326 if containing_module.glob_count.get() > 0 {
2327 debug!("(resolving single import) unresolved glob; \
2329 return Indeterminate;
2332 // Now search the exported imports within the containing
2335 let import_resolutions = containing_module.import_resolutions
2337 match import_resolutions.get().find(&source.name) {
2339 // The containing module definitely doesn't have an
2340 // exported import with the name in question. We can
2341 // therefore accurately report that the names are
2344 if value_result.is_unknown() {
2345 value_result = UnboundResult;
2347 if type_result.is_unknown() {
2348 type_result = UnboundResult;
2351 Some(import_resolution)
2352 if import_resolution.outstanding_references.get()
2355 fn get_binding(this: &mut Resolver,
2356 import_resolution: @ImportResolution,
2357 namespace: Namespace)
2358 -> NamespaceResult {
2360 // Import resolutions must be declared with "pub"
2361 // in order to be exported.
2362 if !import_resolution.is_public.get() {
2363 return UnboundResult;
2366 match (*import_resolution).
2367 target_for_namespace(namespace) {
2369 return UnboundResult;
2372 let id = import_resolution.id(namespace);
2373 this.used_imports.insert((id, namespace));
2374 return BoundResult(target.target_module,
2380 // The name is an import which has been fully
2381 // resolved. We can, therefore, just follow it.
2382 if value_result.is_unknown() {
2383 value_result = get_binding(self, *import_resolution,
2385 value_used_reexport = import_resolution.is_public.get();
2387 if type_result.is_unknown() {
2388 type_result = get_binding(self, *import_resolution,
2390 type_used_reexport = import_resolution.is_public.get();
2395 // The import is unresolved. Bail out.
2396 debug!("(resolving single import) unresolved import; \
2398 return Indeterminate;
2404 // If we didn't find a result in the type namespace, search the
2405 // external modules.
2406 let mut value_used_public = false;
2407 let mut type_used_public = false;
2409 BoundResult(..) => {}
2412 let mut external_module_children =
2413 containing_module.external_module_children
2415 external_module_children.get().find_copy(&source.name)
2418 None => {} // Continue.
2421 @Resolver::create_name_bindings_from_module(
2423 type_result = BoundResult(containing_module,
2425 type_used_public = true;
2431 // We've successfully resolved the import. Write the results in.
2432 let import_resolution = {
2433 let import_resolutions = module_.import_resolutions.borrow();
2434 assert!(import_resolutions.get().contains_key(&target.name));
2435 import_resolutions.get().get_copy(&target.name)
2438 match value_result {
2439 BoundResult(target_module, name_bindings) => {
2440 debug!("(resolving single import) found value target");
2441 import_resolution.value_target.set(
2442 Some(Target::new(target_module, name_bindings)));
2443 import_resolution.value_id.set(directive.id);
2444 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2446 UnboundResult => { /* Continue. */ }
2448 fail!("value result should be known at this point");
2452 BoundResult(target_module, name_bindings) => {
2453 debug!("(resolving single import) found type target: {:?}",
2454 {name_bindings.type_def.get().unwrap().type_def});
2455 import_resolution.type_target.set(
2456 Some(Target::new(target_module, name_bindings)));
2457 import_resolution.type_id.set(directive.id);
2458 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2460 UnboundResult => { /* Continue. */ }
2462 fail!("type result should be known at this point");
2466 if import_resolution.value_target.get().is_none() &&
2467 import_resolution.type_target.get().is_none() {
2468 let msg = format!("unresolved import: there is no \
2470 token::get_ident(source),
2471 self.module_to_str(containing_module));
2472 self.resolve_error(directive.span, msg);
2475 let value_used_public = value_used_reexport || value_used_public;
2476 let type_used_public = type_used_reexport || type_used_public;
2478 assert!(import_resolution.outstanding_references.get() >= 1);
2479 import_resolution.outstanding_references.set(
2480 import_resolution.outstanding_references.get() - 1);
2482 // record what this import resolves to for later uses in documentation,
2483 // this may resolve to either a value or a type, but for documentation
2484 // purposes it's good enough to just favor one over the other.
2485 let value_private = match import_resolution.value_target.get() {
2487 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2488 let mut def_map = self.def_map.borrow_mut();
2489 def_map.get().insert(directive.id, def);
2490 let did = def_id_of_def(def);
2491 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2493 // AllPublic here and below is a dummy value, it should never be used because
2494 // _exists is false.
2497 let type_private = match import_resolution.type_target.get() {
2499 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2500 let mut def_map = self.def_map.borrow_mut();
2501 def_map.get().insert(directive.id, def);
2502 let did = def_id_of_def(def);
2503 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2508 self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2510 type_priv: type_private,
2513 debug!("(resolving single import) successfully resolved import");
2517 // Resolves a glob import. Note that this function cannot fail; it either
2518 // succeeds or bails out (as importing * from an empty module or a module
2519 // that exports nothing is valid).
2520 fn resolve_glob_import(&mut self,
2522 containing_module: @Module,
2526 -> ResolveResult<()> {
2527 // This function works in a highly imperative manner; it eagerly adds
2528 // everything it can to the list of import resolutions of the module
2530 debug!("(resolving glob import) resolving glob import {}", id);
2532 // We must bail out if the node has unresolved imports of any kind
2533 // (including globs).
2534 if !(*containing_module).all_imports_resolved() {
2535 debug!("(resolving glob import) target module has unresolved \
2536 imports; bailing out");
2537 return Indeterminate;
2540 assert_eq!(containing_module.glob_count.get(), 0);
2542 // Add all resolved imports from the containing module.
2543 let import_resolutions = containing_module.import_resolutions
2545 for (ident, target_import_resolution) in import_resolutions.get()
2547 debug!("(resolving glob import) writing module resolution \
2549 target_import_resolution.type_target.get().is_none(),
2550 self.module_to_str(module_));
2552 if !target_import_resolution.is_public.get() {
2553 debug!("(resolving glob import) nevermind, just kidding");
2557 // Here we merge two import resolutions.
2558 let mut import_resolutions = module_.import_resolutions
2560 match import_resolutions.get().find(ident) {
2562 // Simple: just copy the old import resolution.
2563 let new_import_resolution =
2564 @ImportResolution::new(id, is_public);
2565 new_import_resolution.value_target.set(
2566 target_import_resolution.value_target.get());
2567 new_import_resolution.type_target.set(
2568 target_import_resolution.type_target.get());
2570 import_resolutions.get().insert
2571 (*ident, new_import_resolution);
2573 Some(&dest_import_resolution) => {
2574 // Merge the two import resolutions at a finer-grained
2577 match target_import_resolution.value_target.get() {
2581 Some(value_target) => {
2582 dest_import_resolution.value_target.set(
2583 Some(value_target));
2586 match target_import_resolution.type_target.get() {
2590 Some(type_target) => {
2591 dest_import_resolution.type_target.set(
2595 dest_import_resolution.is_public.set(is_public);
2600 // Add all children from the containing module.
2601 self.populate_module_if_necessary(containing_module);
2604 let children = containing_module.children.borrow();
2605 for (&name, name_bindings) in children.get().iter() {
2606 self.merge_import_resolution(module_, containing_module,
2608 name, *name_bindings);
2612 // Add external module children from the containing module.
2614 let external_module_children =
2615 containing_module.external_module_children.borrow();
2616 for (&name, module) in external_module_children.get().iter() {
2618 @Resolver::create_name_bindings_from_module(*module);
2619 self.merge_import_resolution(module_, containing_module,
2621 name, name_bindings);
2625 // Record the destination of this import
2626 match containing_module.def_id.get() {
2628 let mut def_map = self.def_map.borrow_mut();
2629 def_map.get().insert(id, DefMod(did));
2630 self.last_private.insert(id, lp);
2635 debug!("(resolving glob import) successfully resolved import");
2639 fn merge_import_resolution(&mut self,
2641 containing_module: @Module,
2645 name_bindings: @NameBindings) {
2646 let dest_import_resolution;
2647 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2648 match import_resolutions.get().find(&name) {
2650 // Create a new import resolution from this child.
2651 dest_import_resolution =
2652 @ImportResolution::new(id, is_public);
2653 import_resolutions.get().insert(name,
2654 dest_import_resolution);
2656 Some(&existing_import_resolution) => {
2657 dest_import_resolution = existing_import_resolution;
2661 debug!("(resolving glob import) writing resolution `{}` in `{}` \
2663 token::get_name(name).get().to_str(),
2664 self.module_to_str(containing_module),
2665 self.module_to_str(module_));
2667 // Merge the child item into the import resolution.
2668 if name_bindings.defined_in_public_namespace(ValueNS) {
2669 debug!("(resolving glob import) ... for value target");
2670 dest_import_resolution.value_target.set(
2671 Some(Target::new(containing_module, name_bindings)));
2672 dest_import_resolution.value_id.set(id);
2674 if name_bindings.defined_in_public_namespace(TypeNS) {
2675 debug!("(resolving glob import) ... for type target");
2676 dest_import_resolution.type_target.set(
2677 Some(Target::new(containing_module, name_bindings)));
2678 dest_import_resolution.type_id.set(id);
2680 dest_import_resolution.is_public.set(is_public);
2683 /// Resolves the given module path from the given root `module_`.
2684 fn resolve_module_path_from_root(&mut self,
2686 module_path: &[Ident],
2689 name_search_type: NameSearchType,
2691 -> ResolveResult<(@Module, LastPrivate)> {
2692 let mut search_module = module_;
2693 let mut index = index;
2694 let module_path_len = module_path.len();
2695 let mut closest_private = lp;
2697 // Resolve the module part of the path. This does not involve looking
2698 // upward though scope chains; we simply resolve names directly in
2699 // modules as we go.
2700 while index < module_path_len {
2701 let name = module_path[index];
2702 match self.resolve_name_in_module(search_module,
2707 let segment_name = token::get_ident(name);
2708 let module_name = self.module_to_str(search_module);
2709 if "???" == module_name {
2712 hi: span.lo + Pos::from_uint(segment_name.get().len()),
2713 expn_info: span.expn_info,
2715 self.resolve_error(span,
2716 format!("unresolved import. maybe \
2717 a missing `extern crate \
2722 self.resolve_error(span, format!("unresolved import: could not find `{}` in \
2723 `{}`.", segment_name, module_name));
2727 debug!("(resolving module path for import) module \
2728 resolution is indeterminate: {}",
2729 token::get_ident(name));
2730 return Indeterminate;
2732 Success((target, used_proxy)) => {
2733 // Check to see whether there are type bindings, and, if
2734 // so, whether there is a module within.
2735 match target.bindings.type_def.get() {
2737 match type_def.module_def {
2740 self.resolve_error(span, format!("not a module `{}`",
2741 token::get_ident(name)));
2744 Some(module_def) => {
2745 // If we're doing the search for an
2746 // import, do not allow traits and impls
2748 match (name_search_type,
2749 module_def.kind.get()) {
2750 (ImportSearch, TraitModuleKind) |
2751 (ImportSearch, ImplModuleKind) => {
2754 "cannot import from a trait \
2755 or type implementation");
2759 search_module = module_def;
2761 // Keep track of the closest
2762 // private module used when
2763 // resolving this import chain.
2765 !search_module.is_public {
2766 match search_module.def_id
2770 LastMod(DependsOn(did));
2781 // There are no type bindings at all.
2782 self.resolve_error(span,
2783 format!("not a module `{}`",
2784 token::get_ident(name)));
2794 return Success((search_module, closest_private));
2797 /// Attempts to resolve the module part of an import directive or path
2798 /// rooted at the given module.
2800 /// On success, returns the resolved module, and the closest *private*
2801 /// module found to the destination when resolving this path.
2802 fn resolve_module_path(&mut self,
2804 module_path: &[Ident],
2805 use_lexical_scope: UseLexicalScopeFlag,
2807 name_search_type: NameSearchType)
2808 -> ResolveResult<(@Module, LastPrivate)> {
2809 let module_path_len = module_path.len();
2810 assert!(module_path_len > 0);
2812 debug!("(resolving module path for import) processing `{}` rooted at \
2814 self.idents_to_str(module_path),
2815 self.module_to_str(module_));
2817 // Resolve the module prefix, if any.
2818 let module_prefix_result = self.resolve_module_prefix(module_,
2824 match module_prefix_result {
2826 let mpath = self.idents_to_str(module_path);
2827 match mpath.rfind(':') {
2829 self.resolve_error(span, format!("unresolved import: could not find `{}` \
2831 // idx +- 1 to account for the colons
2833 mpath.slice_from(idx + 1),
2834 mpath.slice_to(idx - 1)));
2841 debug!("(resolving module path for import) indeterminate; \
2843 return Indeterminate;
2845 Success(NoPrefixFound) => {
2846 // There was no prefix, so we're considering the first element
2847 // of the path. How we handle this depends on whether we were
2848 // instructed to use lexical scope or not.
2849 match use_lexical_scope {
2850 DontUseLexicalScope => {
2851 // This is a crate-relative path. We will start the
2852 // resolution process at index zero.
2853 search_module = self.graph_root.get_module();
2855 last_private = LastMod(AllPublic);
2857 UseLexicalScope => {
2858 // This is not a crate-relative path. We resolve the
2859 // first component of the path in the current lexical
2860 // scope and then proceed to resolve below that.
2861 let result = self.resolve_module_in_lexical_scope(
2866 self.resolve_error(span, "unresolved name");
2870 debug!("(resolving module path for import) \
2871 indeterminate; bailing");
2872 return Indeterminate;
2874 Success(containing_module) => {
2875 search_module = containing_module;
2877 last_private = LastMod(AllPublic);
2883 Success(PrefixFound(containing_module, index)) => {
2884 search_module = containing_module;
2885 start_index = index;
2886 last_private = LastMod(DependsOn(containing_module.def_id
2892 self.resolve_module_path_from_root(search_module,
2900 /// Invariant: This must only be called during main resolution, not during
2901 /// import resolution.
2902 fn resolve_item_in_lexical_scope(&mut self,
2905 namespace: Namespace,
2906 search_through_modules:
2907 SearchThroughModulesFlag)
2908 -> ResolveResult<(Target, bool)> {
2909 debug!("(resolving item in lexical scope) resolving `{}` in \
2910 namespace {:?} in `{}`",
2911 token::get_ident(name),
2913 self.module_to_str(module_));
2915 // The current module node is handled specially. First, check for
2916 // its immediate children.
2917 self.populate_module_if_necessary(module_);
2920 let children = module_.children.borrow();
2921 match children.get().find(&name.name) {
2923 if name_bindings.defined_in_namespace(namespace) => {
2924 debug!("top name bindings succeeded");
2925 return Success((Target::new(module_, *name_bindings),
2928 Some(_) | None => { /* Not found; continue. */ }
2932 // Now check for its import directives. We don't have to have resolved
2933 // all its imports in the usual way; this is because chains of
2934 // adjacent import statements are processed as though they mutated the
2936 let import_resolutions = module_.import_resolutions.borrow();
2937 match import_resolutions.get().find(&name.name) {
2939 // Not found; continue.
2941 Some(import_resolution) => {
2942 match (*import_resolution).target_for_namespace(namespace) {
2944 // Not found; continue.
2945 debug!("(resolving item in lexical scope) found \
2946 import resolution, but not in namespace {:?}",
2950 debug!("(resolving item in lexical scope) using \
2951 import resolution");
2952 self.used_imports.insert((import_resolution.id(namespace), namespace));
2953 return Success((target, false));
2959 // Search for external modules.
2960 if namespace == TypeNS {
2962 let external_module_children =
2963 module_.external_module_children.borrow();
2964 external_module_children.get().find_copy(&name.name)
2970 @Resolver::create_name_bindings_from_module(module);
2971 debug!("lower name bindings succeeded");
2972 return Success((Target::new(module_, name_bindings), false));
2977 // Finally, proceed up the scope chain looking for parent modules.
2978 let mut search_module = module_;
2980 // Go to the next parent.
2981 match search_module.parent_link {
2983 // No more parents. This module was unresolved.
2984 debug!("(resolving item in lexical scope) unresolved \
2988 ModuleParentLink(parent_module_node, _) => {
2989 match search_through_modules {
2990 DontSearchThroughModules => {
2991 match search_module.kind.get() {
2992 NormalModuleKind => {
2993 // We stop the search here.
2994 debug!("(resolving item in lexical \
2995 scope) unresolved module: not \
2996 searching through module \
3003 AnonymousModuleKind => {
3004 search_module = parent_module_node;
3008 SearchThroughModules => {
3009 search_module = parent_module_node;
3013 BlockParentLink(parent_module_node, _) => {
3014 search_module = parent_module_node;
3018 // Resolve the name in the parent module.
3019 match self.resolve_name_in_module(search_module,
3024 // Continue up the search chain.
3027 // We couldn't see through the higher scope because of an
3028 // unresolved import higher up. Bail.
3030 debug!("(resolving item in lexical scope) indeterminate \
3031 higher scope; bailing");
3032 return Indeterminate;
3034 Success((target, used_reexport)) => {
3035 // We found the module.
3036 debug!("(resolving item in lexical scope) found name \
3038 return Success((target, used_reexport));
3044 /// Resolves a module name in the current lexical scope.
3045 fn resolve_module_in_lexical_scope(&mut self,
3048 -> ResolveResult<@Module> {
3049 // If this module is an anonymous module, resolve the item in the
3050 // lexical scope. Otherwise, resolve the item from the crate root.
3051 let resolve_result = self.resolve_item_in_lexical_scope(
3052 module_, name, TypeNS, DontSearchThroughModules);
3053 match resolve_result {
3054 Success((target, _)) => {
3055 let bindings = &*target.bindings;
3056 match bindings.type_def.get() {
3058 match type_def.module_def {
3060 error!("!!! (resolving module in lexical \
3061 scope) module wasn't actually a \
3065 Some(module_def) => {
3066 return Success(module_def);
3071 error!("!!! (resolving module in lexical scope) module
3072 wasn't actually a module!");
3078 debug!("(resolving module in lexical scope) indeterminate; \
3080 return Indeterminate;
3083 debug!("(resolving module in lexical scope) failed to \
3090 /// Returns the nearest normal module parent of the given module.
3091 fn get_nearest_normal_module_parent(&mut self, module_: @Module)
3092 -> Option<@Module> {
3093 let mut module_ = module_;
3095 match module_.parent_link {
3096 NoParentLink => return None,
3097 ModuleParentLink(new_module, _) |
3098 BlockParentLink(new_module, _) => {
3099 match new_module.kind.get() {
3100 NormalModuleKind => return Some(new_module),
3104 AnonymousModuleKind => module_ = new_module,
3111 /// Returns the nearest normal module parent of the given module, or the
3112 /// module itself if it is a normal module.
3113 fn get_nearest_normal_module_parent_or_self(&mut self, module_: @Module)
3115 match module_.kind.get() {
3116 NormalModuleKind => return module_,
3120 AnonymousModuleKind => {
3121 match self.get_nearest_normal_module_parent(module_) {
3123 Some(new_module) => new_module
3129 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3130 /// (b) some chain of `super::`.
3131 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3132 fn resolve_module_prefix(&mut self,
3134 module_path: &[Ident])
3135 -> ResolveResult<ModulePrefixResult> {
3136 // Start at the current module if we see `self` or `super`, or at the
3137 // top of the crate otherwise.
3138 let mut containing_module;
3140 let first_module_path_string = token::get_ident(module_path[0]);
3141 if "self" == first_module_path_string.get() {
3143 self.get_nearest_normal_module_parent_or_self(module_);
3145 } else if "super" == first_module_path_string.get() {
3147 self.get_nearest_normal_module_parent_or_self(module_);
3148 i = 0; // We'll handle `super` below.
3150 return Success(NoPrefixFound);
3153 // Now loop through all the `super`s we find.
3154 while i < module_path.len() {
3155 let string = token::get_ident(module_path[i]);
3156 if "super" != string.get() {
3159 debug!("(resolving module prefix) resolving `super` at {}",
3160 self.module_to_str(containing_module));
3161 match self.get_nearest_normal_module_parent(containing_module) {
3162 None => return Failed,
3163 Some(new_module) => {
3164 containing_module = new_module;
3170 debug!("(resolving module prefix) finished resolving prefix at {}",
3171 self.module_to_str(containing_module));
3173 return Success(PrefixFound(containing_module, i));
3176 /// Attempts to resolve the supplied name in the given module for the
3177 /// given namespace. If successful, returns the target corresponding to
3180 /// The boolean returned on success is an indicator of whether this lookup
3181 /// passed through a public re-export proxy.
3182 fn resolve_name_in_module(&mut self,
3185 namespace: Namespace,
3186 name_search_type: NameSearchType)
3187 -> ResolveResult<(Target, bool)> {
3188 debug!("(resolving name in module) resolving `{}` in `{}`",
3189 token::get_ident(name),
3190 self.module_to_str(module_));
3192 // First, check the direct children of the module.
3193 self.populate_module_if_necessary(module_);
3196 let children = module_.children.borrow();
3197 match children.get().find(&name.name) {
3199 if name_bindings.defined_in_namespace(namespace) => {
3200 debug!("(resolving name in module) found node as child");
3201 return Success((Target::new(module_, *name_bindings),
3210 // Next, check the module's imports if necessary.
3212 // If this is a search of all imports, we should be done with glob
3213 // resolution at this point.
3214 if name_search_type == PathSearch {
3215 assert_eq!(module_.glob_count.get(), 0);
3218 // Check the list of resolved imports.
3219 let import_resolutions = module_.import_resolutions.borrow();
3220 match import_resolutions.get().find(&name.name) {
3221 Some(import_resolution) => {
3222 if import_resolution.is_public.get() &&
3223 import_resolution.outstanding_references.get() != 0 {
3224 debug!("(resolving name in module) import \
3225 unresolved; bailing out");
3226 return Indeterminate;
3228 match import_resolution.target_for_namespace(namespace) {
3230 debug!("(resolving name in module) name found, \
3231 but not in namespace {:?}",
3235 debug!("(resolving name in module) resolved to \
3237 self.used_imports.insert((import_resolution.id(namespace), namespace));
3238 return Success((target, true));
3242 None => {} // Continue.
3245 // Finally, search through external children.
3246 if namespace == TypeNS {
3248 let external_module_children =
3249 module_.external_module_children.borrow();
3250 external_module_children.get().find_copy(&name.name)
3256 @Resolver::create_name_bindings_from_module(module);
3257 return Success((Target::new(module_, name_bindings), false));
3262 // We're out of luck.
3263 debug!("(resolving name in module) failed to resolve `{}`",
3264 token::get_ident(name));
3268 fn report_unresolved_imports(&mut self, module_: @Module) {
3269 let index = module_.resolved_import_count.get();
3270 let mut imports = module_.imports.borrow_mut();
3271 let import_count = imports.get().len();
3272 if index != import_count {
3273 let sn = self.session
3275 .span_to_snippet(imports.get()[index].span)
3277 if sn.contains("::") {
3278 self.resolve_error(imports.get()[index].span,
3279 "unresolved import");
3281 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3282 sn.slice(0, sn.len()));
3283 self.resolve_error(imports.get()[index].span, err);
3287 // Descend into children and anonymous children.
3288 self.populate_module_if_necessary(module_);
3291 let children = module_.children.borrow();
3292 for (_, &child_node) in children.get().iter() {
3293 match child_node.get_module_if_available() {
3297 Some(child_module) => {
3298 self.report_unresolved_imports(child_module);
3304 let anonymous_children = module_.anonymous_children.borrow();
3305 for (_, &module_) in anonymous_children.get().iter() {
3306 self.report_unresolved_imports(module_);
3312 // This pass simply determines what all "export" keywords refer to and
3313 // writes the results into the export map.
3315 // FIXME #4953 This pass will be removed once exports change to per-item.
3316 // Then this operation can simply be performed as part of item (or import)
3319 fn record_exports(&mut self) {
3320 let root_module = self.graph_root.get_module();
3321 self.record_exports_for_module_subtree(root_module);
3324 fn record_exports_for_module_subtree(&mut self,
3326 // If this isn't a local krate, then bail out. We don't need to record
3327 // exports for nonlocal crates.
3329 match module_.def_id.get() {
3330 Some(def_id) if def_id.krate == LOCAL_CRATE => {
3332 debug!("(recording exports for module subtree) recording \
3333 exports for local module `{}`",
3334 self.module_to_str(module_));
3337 // Record exports for the root module.
3338 debug!("(recording exports for module subtree) recording \
3339 exports for root module `{}`",
3340 self.module_to_str(module_));
3344 debug!("(recording exports for module subtree) not recording \
3346 self.module_to_str(module_));
3351 self.record_exports_for_module(module_);
3352 self.populate_module_if_necessary(module_);
3355 let children = module_.children.borrow();
3356 for (_, &child_name_bindings) in children.get().iter() {
3357 match child_name_bindings.get_module_if_available() {
3361 Some(child_module) => {
3362 self.record_exports_for_module_subtree(child_module);
3368 let anonymous_children = module_.anonymous_children.borrow();
3369 for (_, &child_module) in anonymous_children.get().iter() {
3370 self.record_exports_for_module_subtree(child_module);
3374 fn record_exports_for_module(&mut self, module_: @Module) {
3375 let mut exports2 = ~[];
3377 self.add_exports_for_module(&mut exports2, module_);
3378 match module_.def_id.get() {
3380 let mut export_map2 = self.export_map2.borrow_mut();
3381 export_map2.get().insert(def_id.node, exports2);
3382 debug!("(computing exports) writing exports for {} (some)",
3389 fn add_exports_of_namebindings(&mut self,
3390 exports2: &mut ~[Export2],
3392 namebindings: @NameBindings,
3394 match namebindings.def_for_namespace(ns) {
3396 let name = token::get_name(name);
3397 debug!("(computing exports) YES: export '{}' => {:?}",
3398 name, def_id_of_def(d));
3399 exports2.push(Export2 {
3400 name: name.get().to_str(),
3401 def_id: def_id_of_def(d)
3405 debug!("(computing exports) NO: {:?}", d_opt);
3410 fn add_exports_for_module(&mut self,
3411 exports2: &mut ~[Export2],
3413 let import_resolutions = module_.import_resolutions.borrow();
3414 for (name, importresolution) in import_resolutions.get().iter() {
3415 if !importresolution.is_public.get() {
3418 let xs = [TypeNS, ValueNS];
3419 for &ns in xs.iter() {
3420 match importresolution.target_for_namespace(ns) {
3422 debug!("(computing exports) maybe export '{}'",
3423 token::get_name(*name));
3424 self.add_exports_of_namebindings(exports2,
3437 // We maintain a list of value ribs and type ribs.
3439 // Simultaneously, we keep track of the current position in the module
3440 // graph in the `current_module` pointer. When we go to resolve a name in
3441 // the value or type namespaces, we first look through all the ribs and
3442 // then query the module graph. When we resolve a name in the module
3443 // namespace, we can skip all the ribs (since nested modules are not
3444 // allowed within blocks in Rust) and jump straight to the current module
3447 // Named implementations are handled separately. When we find a method
3448 // call, we consult the module node to find all of the implementations in
3449 // scope. This information is lazily cached in the module node. We then
3450 // generate a fake "implementation scope" containing all the
3451 // implementations thus found, for compatibility with old resolve pass.
3453 fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
3454 let orig_module = self.current_module;
3456 // Move down in the graph.
3462 self.populate_module_if_necessary(orig_module);
3464 let children = orig_module.children.borrow();
3465 match children.get().find(&name.name) {
3467 debug!("!!! (with scope) didn't find `{}` in `{}`",
3468 token::get_ident(name),
3469 self.module_to_str(orig_module));
3471 Some(name_bindings) => {
3472 match (*name_bindings).get_module_if_available() {
3474 debug!("!!! (with scope) didn't find module \
3476 token::get_ident(name),
3477 self.module_to_str(orig_module));
3480 self.current_module = module_;
3490 self.current_module = orig_module;
3493 /// Wraps the given definition in the appropriate number of `def_upvar`
3495 fn upvarify(&mut self,
3500 -> Option<DefLike> {
3505 DlDef(d @ DefLocal(..)) | DlDef(d @ DefUpvar(..)) |
3506 DlDef(d @ DefArg(..)) | DlDef(d @ DefBinding(..)) => {
3508 is_ty_param = false;
3510 DlDef(d @ DefTyParam(..)) => {
3515 return Some(def_like);
3519 let mut rib_index = rib_index + 1;
3520 while rib_index < ribs.len() {
3521 match ribs[rib_index].kind {
3523 // Nothing to do. Continue.
3525 FunctionRibKind(function_id, body_id) => {
3527 def = DefUpvar(def_id_of_def(def).node,
3533 MethodRibKind(item_id, _) => {
3534 // If the def is a ty param, and came from the parent
3537 DefTyParam(did, _) if {
3538 let def_map = self.def_map.borrow();
3539 def_map.get().find(&did.node).map(|x| *x)
3540 == Some(DefTyParamBinder(item_id))
3546 // This was an attempt to access an upvar inside a
3547 // named function item. This is not allowed, so we
3552 "can't capture dynamic environment in a fn item; \
3553 use the || { ... } closure form instead");
3555 // This was an attempt to use a type parameter outside
3558 self.resolve_error(span,
3559 "attempt to use a type \
3560 argument out of scope");
3567 OpaqueFunctionRibKind => {
3569 // This was an attempt to access an upvar inside a
3570 // named function item. This is not allowed, so we
3575 "can't capture dynamic environment in a fn item; \
3576 use the || { ... } closure form instead");
3578 // This was an attempt to use a type parameter outside
3581 self.resolve_error(span,
3582 "attempt to use a type \
3583 argument out of scope");
3588 ConstantItemRibKind => {
3591 self.resolve_error(span,
3592 "cannot use an outer type \
3593 parameter in this context");
3595 // Still doesn't deal with upvars
3596 self.resolve_error(span,
3597 "attempt to use a non-constant \
3598 value in a constant");
3607 return Some(DlDef(def));
3610 fn search_ribs(&mut self,
3614 -> Option<DefLike> {
3615 // FIXME #4950: This should not use a while loop.
3616 // FIXME #4950: Try caching?
3618 let mut i = ribs.len();
3622 let bindings = ribs[i].bindings.borrow();
3623 bindings.get().find_copy(&name)
3627 return self.upvarify(ribs, i, def_like, span);
3638 fn resolve_crate(&mut self, krate: &ast::Crate) {
3639 debug!("(resolving crate) starting");
3641 visit::walk_crate(self, krate, ());
3644 fn resolve_item(&mut self, item: &Item) {
3645 debug!("(resolving item) resolving {}",
3646 token::get_ident(item.ident));
3650 // enum item: resolve all the variants' discrs,
3651 // then resolve the ty params
3652 ItemEnum(ref enum_def, ref generics) => {
3653 for variant in (*enum_def).variants.iter() {
3654 for dis_expr in variant.node.disr_expr.iter() {
3655 // resolve the discriminator expr
3657 self.with_constant_rib(|this| {
3658 this.resolve_expr(*dis_expr);
3663 // n.b. the discr expr gets visted twice.
3664 // but maybe it's okay since the first time will signal an
3665 // error if there is one? -- tjc
3666 self.with_type_parameter_rib(HasTypeParameters(generics,
3671 visit::walk_item(this, item, ());
3675 ItemTy(_, ref generics) => {
3676 self.with_type_parameter_rib(HasTypeParameters(generics,
3681 visit::walk_item(this, item, ());
3685 ItemImpl(ref generics,
3686 ref implemented_traits,
3689 self.resolve_implementation(item.id,
3696 ItemTrait(ref generics, ref traits, ref methods) => {
3697 // Create a new rib for the self type.
3698 let self_type_rib = @Rib::new(NormalRibKind);
3700 let mut type_ribs = self.type_ribs.borrow_mut();
3701 type_ribs.get().push(self_type_rib);
3703 // plain insert (no renaming)
3704 let name = self.type_self_ident.name;
3706 let mut bindings = self_type_rib.bindings.borrow_mut();
3707 bindings.get().insert(name, DlDef(DefSelfTy(item.id)));
3710 // Create a new rib for the trait-wide type parameters.
3711 self.with_type_parameter_rib(HasTypeParameters(generics,
3716 this.resolve_type_parameters(&generics.ty_params);
3718 // Resolve derived traits.
3719 for trt in traits.iter() {
3720 this.resolve_trait_reference(item.id, trt, TraitDerivation);
3723 for method in (*methods).iter() {
3724 // Create a new rib for the method-specific type
3727 // FIXME #4951: Do we need a node ID here?
3730 ast::Required(ref ty_m) => {
3731 this.with_type_parameter_rib
3732 (HasTypeParameters(&ty_m.generics,
3734 generics.ty_params.len(),
3735 MethodRibKind(item.id, Required)),
3738 // Resolve the method-specific type
3740 this.resolve_type_parameters(
3741 &ty_m.generics.ty_params);
3743 for argument in ty_m.decl.inputs.iter() {
3744 this.resolve_type(argument.ty);
3747 this.resolve_type(ty_m.decl.output);
3750 ast::Provided(m) => {
3751 this.resolve_method(MethodRibKind(item.id,
3754 generics.ty_params.len())
3760 let mut type_ribs = self.type_ribs.borrow_mut();
3761 type_ribs.get().pop();
3764 ItemStruct(ref struct_def, ref generics) => {
3765 self.resolve_struct(item.id,
3770 ItemMod(ref module_) => {
3771 self.with_scope(Some(item.ident), |this| {
3772 this.resolve_module(module_, item.span, item.ident,
3777 ItemForeignMod(ref foreign_module) => {
3778 self.with_scope(Some(item.ident), |this| {
3779 for foreign_item in foreign_module.items.iter() {
3780 match foreign_item.node {
3781 ForeignItemFn(_, ref generics) => {
3782 this.with_type_parameter_rib(
3784 generics, foreign_item.id, 0,
3786 |this| visit::walk_foreign_item(this,
3790 ForeignItemStatic(..) => {
3791 visit::walk_foreign_item(this,
3800 ItemFn(fn_decl, _, _, ref generics, block) => {
3801 self.resolve_function(OpaqueFunctionRibKind,
3807 OpaqueFunctionRibKind),
3812 self.with_constant_rib(|this| {
3813 visit::walk_item(this, item, ());
3818 // do nothing, these are just around to be encoded
3823 fn with_type_parameter_rib(&mut self,
3824 type_parameters: TypeParameters,
3825 f: |&mut Resolver|) {
3826 match type_parameters {
3827 HasTypeParameters(generics, node_id, initial_index,
3830 let function_type_rib = @Rib::new(rib_kind);
3832 let mut type_ribs = self.type_ribs.borrow_mut();
3833 type_ribs.get().push(function_type_rib);
3836 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
3837 let ident = type_parameter.ident;
3838 debug!("with_type_parameter_rib: {} {}", node_id,
3840 let def_like = DlDef(DefTyParam
3841 (local_def(type_parameter.id),
3842 index + initial_index));
3843 // Associate this type parameter with
3844 // the item that bound it
3845 self.record_def(type_parameter.id,
3846 (DefTyParamBinder(node_id), LastMod(AllPublic)));
3847 // plain insert (no renaming)
3848 let mut bindings = function_type_rib.bindings
3850 bindings.get().insert(ident.name, def_like);
3854 NoTypeParameters => {
3861 match type_parameters {
3862 HasTypeParameters(..) => {
3863 let mut type_ribs = self.type_ribs.borrow_mut();
3864 type_ribs.get().pop();
3867 NoTypeParameters => {
3873 fn with_label_rib(&mut self, f: |&mut Resolver|) {
3875 let mut label_ribs = self.label_ribs.borrow_mut();
3876 label_ribs.get().push(@Rib::new(NormalRibKind));
3882 let mut label_ribs = self.label_ribs.borrow_mut();
3883 label_ribs.get().pop();
3887 fn with_constant_rib(&mut self, f: |&mut Resolver|) {
3889 let mut value_ribs = self.value_ribs.borrow_mut();
3890 let mut type_ribs = self.type_ribs.borrow_mut();
3891 value_ribs.get().push(@Rib::new(ConstantItemRibKind));
3892 type_ribs.get().push(@Rib::new(ConstantItemRibKind));
3896 let mut value_ribs = self.value_ribs.borrow_mut();
3897 let mut type_ribs = self.type_ribs.borrow_mut();
3898 type_ribs.get().pop();
3899 value_ribs.get().pop();
3903 fn resolve_function(&mut self,
3905 optional_declaration: Option<P<FnDecl>>,
3906 type_parameters: TypeParameters,
3908 // Create a value rib for the function.
3909 let function_value_rib = @Rib::new(rib_kind);
3911 let mut value_ribs = self.value_ribs.borrow_mut();
3912 value_ribs.get().push(function_value_rib);
3915 // Create a label rib for the function.
3917 let mut label_ribs = self.label_ribs.borrow_mut();
3918 let function_label_rib = @Rib::new(rib_kind);
3919 label_ribs.get().push(function_label_rib);
3922 // If this function has type parameters, add them now.
3923 self.with_type_parameter_rib(type_parameters, |this| {
3924 // Resolve the type parameters.
3925 match type_parameters {
3926 NoTypeParameters => {
3929 HasTypeParameters(ref generics, _, _, _) => {
3930 this.resolve_type_parameters(&generics.ty_params);
3934 // Add each argument to the rib.
3935 match optional_declaration {
3939 Some(declaration) => {
3940 for argument in declaration.inputs.iter() {
3941 let binding_mode = ArgumentIrrefutableMode;
3942 this.resolve_pattern(argument.pat,
3946 this.resolve_type(argument.ty);
3948 debug!("(resolving function) recorded argument");
3951 this.resolve_type(declaration.output);
3955 // Resolve the function body.
3956 this.resolve_block(block);
3958 debug!("(resolving function) leaving function");
3961 let mut label_ribs = self.label_ribs.borrow_mut();
3962 label_ribs.get().pop();
3964 let mut value_ribs = self.value_ribs.borrow_mut();
3965 value_ribs.get().pop();
3968 fn resolve_type_parameters(&mut self,
3969 type_parameters: &OptVec<TyParam>) {
3970 for type_parameter in type_parameters.iter() {
3971 for bound in type_parameter.bounds.iter() {
3972 self.resolve_type_parameter_bound(type_parameter.id, bound);
3974 match type_parameter.default {
3975 Some(ty) => self.resolve_type(ty),
3981 fn resolve_type_parameter_bound(&mut self,
3983 type_parameter_bound: &TyParamBound) {
3984 match *type_parameter_bound {
3985 TraitTyParamBound(ref tref) => {
3986 self.resolve_trait_reference(id, tref, TraitBoundingTypeParameter)
3988 RegionTyParamBound => {}
3992 fn resolve_trait_reference(&mut self,
3994 trait_reference: &TraitRef,
3995 reference_type: TraitReferenceType) {
3996 match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
3998 let path_str = self.path_idents_to_str(&trait_reference.path);
3999 let usage_str = match reference_type {
4000 TraitBoundingTypeParameter => "bound type parameter with",
4001 TraitImplementation => "implement",
4002 TraitDerivation => "derive"
4005 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
4006 self.resolve_error(trait_reference.path.span, msg);
4009 debug!("(resolving trait) found trait def: {:?}", def);
4010 self.record_def(trait_reference.ref_id, def);
4015 fn resolve_struct(&mut self,
4017 generics: &Generics,
4018 fields: &[StructField]) {
4019 let mut ident_map: HashMap<ast::Ident, &StructField> = HashMap::new();
4020 for field in fields.iter() {
4021 match field.node.kind {
4022 NamedField(ident, _) => {
4023 match ident_map.find(&ident) {
4024 Some(&prev_field) => {
4025 let ident_str = token::get_ident(ident);
4026 self.resolve_error(field.span,
4027 format!("field `{}` is already declared", ident_str));
4028 self.session.span_note(prev_field.span,
4029 "previously declared here");
4032 ident_map.insert(ident, field);
4040 // If applicable, create a rib for the type parameters.
4041 self.with_type_parameter_rib(HasTypeParameters(generics,
4044 OpaqueFunctionRibKind),
4046 // Resolve the type parameters.
4047 this.resolve_type_parameters(&generics.ty_params);
4050 for field in fields.iter() {
4051 this.resolve_type(field.node.ty);
4056 // Does this really need to take a RibKind or is it always going
4057 // to be NormalRibKind?
4058 fn resolve_method(&mut self,
4061 outer_type_parameter_count: uint) {
4062 let method_generics = &method.generics;
4063 let type_parameters =
4064 HasTypeParameters(method_generics,
4066 outer_type_parameter_count,
4069 self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
4072 fn resolve_implementation(&mut self,
4074 generics: &Generics,
4075 opt_trait_reference: &Option<TraitRef>,
4077 methods: &[@Method]) {
4078 // If applicable, create a rib for the type parameters.
4079 let outer_type_parameter_count = generics.ty_params.len();
4080 self.with_type_parameter_rib(HasTypeParameters(generics,
4085 // Resolve the type parameters.
4086 this.resolve_type_parameters(&generics.ty_params);
4088 // Resolve the trait reference, if necessary.
4089 let original_trait_refs;
4090 match opt_trait_reference {
4091 &Some(ref trait_reference) => {
4092 this.resolve_trait_reference(id, trait_reference,
4093 TraitImplementation);
4095 // Record the current set of trait references.
4096 let mut new_trait_refs = ~[];
4098 let def_map = this.def_map.borrow();
4099 let r = def_map.get().find(&trait_reference.ref_id);
4100 for &def in r.iter() {
4101 new_trait_refs.push(def_id_of_def(*def));
4104 original_trait_refs = Some(replace(
4105 &mut this.current_trait_refs,
4106 Some(new_trait_refs)));
4109 original_trait_refs = None;
4113 // Resolve the self type.
4114 this.resolve_type(self_type);
4116 for method in methods.iter() {
4117 // We also need a new scope for the method-specific
4119 this.resolve_method(MethodRibKind(
4121 Provided(method.id)),
4123 outer_type_parameter_count);
4125 let borrowed_type_parameters = &method.tps;
4126 self.resolve_function(MethodRibKind(
4128 Provided(method.id)),
4131 (borrowed_type_parameters,
4133 outer_type_parameter_count,
4139 // Restore the original trait references.
4140 match original_trait_refs {
4141 Some(r) => { this.current_trait_refs = r; }
4147 fn resolve_module(&mut self, module: &Mod, _span: Span,
4148 _name: Ident, id: NodeId) {
4149 // Write the implementations in scope into the module metadata.
4150 debug!("(resolving module) resolving module ID {}", id);
4151 visit::walk_mod(self, module, ());
4154 fn resolve_local(&mut self, local: &Local) {
4155 // Resolve the type.
4156 self.resolve_type(local.ty);
4158 // Resolve the initializer, if necessary.
4163 Some(initializer) => {
4164 self.resolve_expr(initializer);
4168 // Resolve the pattern.
4169 self.resolve_pattern(local.pat, LocalIrrefutableMode, None);
4172 // build a map from pattern identifiers to binding-info's.
4173 // this is done hygienically. This could arise for a macro
4174 // that expands into an or-pattern where one 'x' was from the
4175 // user and one 'x' came from the macro.
4176 fn binding_mode_map(&mut self, pat: @Pat) -> BindingMap {
4177 let mut result = HashMap::new();
4178 pat_bindings(self.def_map, pat, |binding_mode, _id, sp, path| {
4179 let name = mtwt_resolve(path_to_ident(path));
4181 binding_info {span: sp,
4182 binding_mode: binding_mode});
4187 // check that all of the arms in an or-pattern have exactly the
4188 // same set of bindings, with the same binding modes for each.
4189 fn check_consistent_bindings(&mut self, arm: &Arm) {
4190 if arm.pats.len() == 0 { return; }
4191 let map_0 = self.binding_mode_map(arm.pats[0]);
4192 for (i, p) in arm.pats.iter().enumerate() {
4193 let map_i = self.binding_mode_map(*p);
4195 for (&key, &binding_0) in map_0.iter() {
4196 match map_i.find(&key) {
4200 format!("variable `{}` from pattern \\#1 is \
4201 not bound in pattern \\#{}",
4202 token::get_name(key),
4205 Some(binding_i) => {
4206 if binding_0.binding_mode != binding_i.binding_mode {
4209 format!("variable `{}` is bound with different \
4210 mode in pattern \\#{} than in pattern \\#1",
4211 token::get_name(key),
4218 for (&key, &binding) in map_i.iter() {
4219 if !map_0.contains_key(&key) {
4222 format!("variable `{}` from pattern \\#{} is \
4223 not bound in pattern \\#1",
4224 token::get_name(key),
4231 fn resolve_arm(&mut self, arm: &Arm) {
4233 let mut value_ribs = self.value_ribs.borrow_mut();
4234 value_ribs.get().push(@Rib::new(NormalRibKind));
4237 let mut bindings_list = HashMap::new();
4238 for pattern in arm.pats.iter() {
4239 self.resolve_pattern(*pattern,
4241 Some(&mut bindings_list));
4244 // This has to happen *after* we determine which
4245 // pat_idents are variants
4246 self.check_consistent_bindings(arm);
4248 visit::walk_expr_opt(self, arm.guard, ());
4249 self.resolve_block(arm.body);
4251 let mut value_ribs = self.value_ribs.borrow_mut();
4252 value_ribs.get().pop();
4255 fn resolve_block(&mut self, block: &Block) {
4256 debug!("(resolving block) entering block");
4258 let mut value_ribs = self.value_ribs.borrow_mut();
4259 value_ribs.get().push(@Rib::new(NormalRibKind));
4262 // Move down in the graph, if there's an anonymous module rooted here.
4263 let orig_module = self.current_module;
4264 let anonymous_children = self.current_module
4267 match anonymous_children.get().find(&block.id) {
4268 None => { /* Nothing to do. */ }
4269 Some(&anonymous_module) => {
4270 debug!("(resolving block) found anonymous module, moving \
4272 self.current_module = anonymous_module;
4276 // Descend into the block.
4277 visit::walk_block(self, block, ());
4280 self.current_module = orig_module;
4282 let mut value_ribs = self.value_ribs.borrow_mut();
4283 value_ribs.get().pop();
4284 debug!("(resolving block) leaving block");
4287 fn resolve_type(&mut self, ty: &Ty) {
4289 // Like path expressions, the interpretation of path types depends
4290 // on whether the path has multiple elements in it or not.
4292 TyPath(ref path, ref bounds, path_id) => {
4293 // This is a path in the type namespace. Walk through scopes
4294 // scopes looking for it.
4295 let mut result_def = None;
4297 // First, check to see whether the name is a primitive type.
4298 if path.segments.len() == 1 {
4299 let id = path.segments.last().unwrap().identifier;
4301 match self.primitive_type_table
4305 Some(&primitive_type) => {
4307 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4311 .any(|s| !s.lifetimes.is_empty()) {
4312 self.session.span_err(path.span,
4313 "lifetime parameters \
4314 are not allowed on \
4316 } else if path.segments
4318 .any(|s| s.types.len() > 0) {
4319 self.session.span_err(path.span,
4320 "type parameters are \
4321 not allowed on this \
4333 match self.resolve_path(ty.id, path, TypeNS, true) {
4335 debug!("(resolving type) resolved `{}` to \
4337 token::get_ident(path.segments
4341 result_def = Some(def);
4348 Some(_) => {} // Continue.
4353 // Write the result into the def map.
4354 debug!("(resolving type) writing resolution for `{}` \
4356 self.path_idents_to_str(path),
4358 self.record_def(path_id, def);
4361 let msg = format!("use of undeclared type name `{}`",
4362 self.path_idents_to_str(path));
4363 self.resolve_error(ty.span, msg);
4367 bounds.as_ref().map(|bound_vec| {
4368 for bound in bound_vec.iter() {
4369 self.resolve_type_parameter_bound(ty.id, bound);
4375 c.bounds.as_ref().map(|bounds| {
4376 for bound in bounds.iter() {
4377 self.resolve_type_parameter_bound(ty.id, bound);
4380 visit::walk_ty(self, ty, ());
4384 // Just resolve embedded types.
4385 visit::walk_ty(self, ty, ());
4390 fn resolve_pattern(&mut self,
4392 mode: PatternBindingMode,
4393 // Maps idents to the node ID for the (outermost)
4394 // pattern that binds them
4395 mut bindings_list: Option<&mut HashMap<Name,NodeId>>) {
4396 let pat_id = pattern.id;
4397 walk_pat(pattern, |pattern| {
4398 match pattern.node {
4399 PatIdent(binding_mode, ref path, _)
4400 if !path.global && path.segments.len() == 1 => {
4402 // The meaning of pat_ident with no type parameters
4403 // depends on whether an enum variant or unit-like struct
4404 // with that name is in scope. The probing lookup has to
4405 // be careful not to emit spurious errors. Only matching
4406 // patterns (match) can match nullary variants or
4407 // unit-like structs. For binding patterns (let), matching
4408 // such a value is simply disallowed (since it's rarely
4411 let ident = path.segments[0].identifier;
4412 let renamed = mtwt_resolve(ident);
4414 match self.resolve_bare_identifier_pattern(ident) {
4415 FoundStructOrEnumVariant(def, lp)
4416 if mode == RefutableMode => {
4417 debug!("(resolving pattern) resolving `{}` to \
4418 struct or enum variant",
4419 token::get_name(renamed));
4421 self.enforce_default_binding_mode(
4425 self.record_def(pattern.id, (def, lp));
4427 FoundStructOrEnumVariant(..) => {
4428 self.resolve_error(pattern.span,
4429 format!("declaration of `{}` \
4431 variant or unit-like \
4433 token::get_name(renamed)));
4435 FoundConst(def, lp) if mode == RefutableMode => {
4436 debug!("(resolving pattern) resolving `{}` to \
4438 token::get_name(renamed));
4440 self.enforce_default_binding_mode(
4444 self.record_def(pattern.id, (def, lp));
4447 self.resolve_error(pattern.span,
4448 "only irrefutable patterns \
4451 BareIdentifierPatternUnresolved => {
4452 debug!("(resolving pattern) binding `{}`",
4453 token::get_name(renamed));
4455 let def = match mode {
4457 // For pattern arms, we must use
4458 // `def_binding` definitions.
4460 DefBinding(pattern.id, binding_mode)
4462 LocalIrrefutableMode => {
4463 // But for locals, we use `def_local`.
4464 DefLocal(pattern.id, binding_mode)
4466 ArgumentIrrefutableMode => {
4467 // And for function arguments, `def_arg`.
4468 DefArg(pattern.id, binding_mode)
4472 // Record the definition so that later passes
4473 // will be able to distinguish variants from
4474 // locals in patterns.
4476 self.record_def(pattern.id, (def, LastMod(AllPublic)));
4478 // Add the binding to the local ribs, if it
4479 // doesn't already exist in the bindings list. (We
4480 // must not add it if it's in the bindings list
4481 // because that breaks the assumptions later
4482 // passes make about or-patterns.)
4484 match bindings_list {
4485 Some(ref mut bindings_list)
4486 if !bindings_list.contains_key(&renamed) => {
4487 let this = &mut *self;
4489 let mut value_ribs =
4490 this.value_ribs.borrow_mut();
4491 let last_rib = value_ribs.get()[
4492 value_ribs.get().len() - 1];
4494 last_rib.bindings.borrow_mut();
4495 bindings.get().insert(renamed,
4498 bindings_list.insert(renamed, pat_id);
4500 Some(ref mut b) => {
4501 if b.find(&renamed) == Some(&pat_id) {
4502 // Then this is a duplicate variable
4503 // in the same disjunct, which is an
4505 self.resolve_error(pattern.span,
4506 format!("identifier `{}` is bound more \
4507 than once in the same pattern",
4508 path_to_str(path)));
4510 // Not bound in the same pattern: do nothing
4513 let this = &mut *self;
4515 let mut value_ribs =
4516 this.value_ribs.borrow_mut();
4517 let last_rib = value_ribs.get()[
4518 value_ribs.get().len() - 1];
4520 last_rib.bindings.borrow_mut();
4521 bindings.get().insert(renamed,
4529 // Check the types in the path pattern.
4530 for &ty in path.segments
4532 .flat_map(|seg| seg.types.iter()) {
4533 self.resolve_type(ty);
4537 PatIdent(binding_mode, ref path, _) => {
4538 // This must be an enum variant, struct, or constant.
4539 match self.resolve_path(pat_id, path, ValueNS, false) {
4540 Some(def @ (DefVariant(..), _)) |
4541 Some(def @ (DefStruct(..), _)) => {
4542 self.record_def(pattern.id, def);
4544 Some(def @ (DefStatic(..), _)) => {
4545 self.enforce_default_binding_mode(
4549 self.record_def(pattern.id, def);
4554 format!("`{}` is not an enum variant or constant",
4556 path.segments.last().unwrap().identifier)))
4559 self.resolve_error(path.span,
4560 "unresolved enum variant");
4564 // Check the types in the path pattern.
4565 for &ty in path.segments
4567 .flat_map(|s| s.types.iter()) {
4568 self.resolve_type(ty);
4572 PatEnum(ref path, _) => {
4573 // This must be an enum variant, struct or const.
4574 match self.resolve_path(pat_id, path, ValueNS, false) {
4575 Some(def @ (DefFn(..), _)) |
4576 Some(def @ (DefVariant(..), _)) |
4577 Some(def @ (DefStruct(..), _)) |
4578 Some(def @ (DefStatic(..), _)) => {
4579 self.record_def(pattern.id, def);
4582 self.resolve_error(path.span,
4583 format!("`{}` is not an enum variant, struct or const",
4584 token::get_ident(path.segments
4589 self.resolve_error(path.span,
4590 format!("unresolved enum variant, struct or const `{}`",
4591 token::get_ident(path.segments
4597 // Check the types in the path pattern.
4598 for &ty in path.segments
4600 .flat_map(|s| s.types.iter()) {
4601 self.resolve_type(ty);
4606 self.resolve_expr(expr);
4609 PatRange(first_expr, last_expr) => {
4610 self.resolve_expr(first_expr);
4611 self.resolve_expr(last_expr);
4614 PatStruct(ref path, _, _) => {
4615 match self.resolve_path(pat_id, path, TypeNS, false) {
4616 Some((DefTy(class_id), lp))
4617 if self.structs.contains(&class_id) => {
4618 let class_def = DefStruct(class_id);
4619 self.record_def(pattern.id, (class_def, lp));
4621 Some(definition @ (DefStruct(class_id), _)) => {
4622 assert!(self.structs.contains(&class_id));
4623 self.record_def(pattern.id, definition);
4625 Some(definition @ (DefVariant(_, variant_id, _), _))
4626 if self.structs.contains(&variant_id) => {
4627 self.record_def(pattern.id, definition);
4630 debug!("(resolving pattern) didn't find struct \
4631 def: {:?}", result);
4632 let msg = format!("`{}` does not name a structure",
4633 self.path_idents_to_str(path));
4634 self.resolve_error(path.span, msg);
4647 fn resolve_bare_identifier_pattern(&mut self, name: Ident)
4649 BareIdentifierPatternResolution {
4650 match self.resolve_item_in_lexical_scope(self.current_module,
4653 SearchThroughModules) {
4654 Success((target, _)) => {
4655 debug!("(resolve bare identifier pattern) succeeded in \
4656 finding {} at {:?}",
4657 token::get_ident(name),
4658 target.bindings.value_def.get());
4659 match target.bindings.value_def.get() {
4661 fail!("resolved name in the value namespace to a \
4662 set of name bindings with no def?!");
4665 // For the two success cases, this lookup can be
4666 // considered as not having a private component because
4667 // the lookup happened only within the current module.
4669 def @ DefVariant(..) | def @ DefStruct(..) => {
4670 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
4672 def @ DefStatic(_, false) => {
4673 return FoundConst(def, LastMod(AllPublic));
4676 return BareIdentifierPatternUnresolved;
4684 fail!("unexpected indeterminate result");
4688 debug!("(resolve bare identifier pattern) failed to find {}",
4689 token::get_ident(name));
4690 return BareIdentifierPatternUnresolved;
4695 /// If `check_ribs` is true, checks the local definitions first; i.e.
4696 /// doesn't skip straight to the containing module.
4697 fn resolve_path(&mut self,
4700 namespace: Namespace,
4701 check_ribs: bool) -> Option<(Def, LastPrivate)> {
4702 // First, resolve the types.
4703 for &ty in path.segments.iter().flat_map(|s| s.types.iter()) {
4704 self.resolve_type(ty);
4708 return self.resolve_crate_relative_path(path, namespace);
4711 let unqualified_def =
4712 self.resolve_identifier(path.segments
4719 if path.segments.len() > 1 {
4720 let def = self.resolve_module_relative_path(path, namespace);
4721 match (def, unqualified_def) {
4722 (Some((d, _)), Some((ud, _))) if d == ud => {
4723 self.session.add_lint(UnnecessaryQualification,
4726 ~"unnecessary qualification");
4734 return unqualified_def;
4737 // resolve a single identifier (used as a varref)
4738 fn resolve_identifier(&mut self,
4740 namespace: Namespace,
4743 -> Option<(Def, LastPrivate)> {
4745 match self.resolve_identifier_in_local_ribs(identifier,
4749 return Some((def, LastMod(AllPublic)));
4757 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
4761 // FIXME #4952: Merge me with resolve_name_in_module?
4762 fn resolve_definition_of_name_in_module(&mut self,
4763 containing_module: @Module,
4765 namespace: Namespace)
4767 // First, search children.
4768 self.populate_module_if_necessary(containing_module);
4771 let children = containing_module.children.borrow();
4772 match children.get().find(&name.name) {
4773 Some(child_name_bindings) => {
4774 match child_name_bindings.def_for_namespace(namespace) {
4776 // Found it. Stop the search here.
4777 let p = child_name_bindings.defined_in_public_namespace(
4779 let lp = if p {LastMod(AllPublic)} else {
4780 LastMod(DependsOn(def_id_of_def(def)))
4782 return ChildNameDefinition(def, lp);
4791 // Next, search import resolutions.
4792 let import_resolutions = containing_module.import_resolutions
4794 match import_resolutions.get().find(&name.name) {
4795 Some(import_resolution) if import_resolution.is_public.get() => {
4796 match (*import_resolution).target_for_namespace(namespace) {
4798 match target.bindings.def_for_namespace(namespace) {
4801 let id = import_resolution.id(namespace);
4802 self.used_imports.insert((id, namespace));
4803 return ImportNameDefinition(def, LastMod(AllPublic));
4806 // This can happen with external impls, due to
4807 // the imperfect way we read the metadata.
4814 Some(..) | None => {} // Continue.
4817 // Finally, search through external children.
4818 if namespace == TypeNS {
4820 let external_module_children =
4821 containing_module.external_module_children.borrow();
4822 external_module_children.get().find_copy(&name.name)
4827 match module.def_id.get() {
4828 None => {} // Continue.
4830 let lp = if module.is_public {LastMod(AllPublic)} else {
4831 LastMod(DependsOn(def_id))
4833 return ChildNameDefinition(DefMod(def_id), lp);
4840 return NoNameDefinition;
4843 // resolve a "module-relative" path, e.g. a::b::c
4844 fn resolve_module_relative_path(&mut self,
4846 namespace: Namespace)
4847 -> Option<(Def, LastPrivate)> {
4848 let module_path_idents = path.segments.init().map(|ps| ps.identifier);
4850 let containing_module;
4852 match self.resolve_module_path(self.current_module,
4858 let msg = format!("use of undeclared module `{}`",
4859 self.idents_to_str(module_path_idents));
4860 self.resolve_error(path.span, msg);
4865 fail!("indeterminate unexpected");
4868 Success((resulting_module, resulting_last_private)) => {
4869 containing_module = resulting_module;
4870 last_private = resulting_last_private;
4874 let ident = path.segments.last().unwrap().identifier;
4875 let def = match self.resolve_definition_of_name_in_module(containing_module,
4878 NoNameDefinition => {
4879 // We failed to resolve the name. Report an error.
4882 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4883 (def, last_private.or(lp))
4886 match containing_module.kind.get() {
4887 TraitModuleKind | ImplModuleKind => {
4888 let method_map = self.method_map.borrow();
4889 match method_map.get().find(&ident.name) {
4891 match containing_module.def_id.get() {
4892 Some(def_id) if s.contains(&def_id) => {
4893 debug!("containing module was a trait or impl \
4894 and name was a method -> not resolved");
4908 /// Invariant: This must be called only during main resolution, not during
4909 /// import resolution.
4910 fn resolve_crate_relative_path(&mut self,
4912 namespace: Namespace)
4913 -> Option<(Def, LastPrivate)> {
4914 let module_path_idents = path.segments.init().map(|ps| ps.identifier);
4916 let root_module = self.graph_root.get_module();
4918 let containing_module;
4920 match self.resolve_module_path_from_root(root_module,
4925 LastMod(AllPublic)) {
4927 let msg = format!("use of undeclared module `::{}`",
4928 self.idents_to_str(module_path_idents));
4929 self.resolve_error(path.span, msg);
4934 fail!("indeterminate unexpected");
4937 Success((resulting_module, resulting_last_private)) => {
4938 containing_module = resulting_module;
4939 last_private = resulting_last_private;
4943 let name = path.segments.last().unwrap().identifier;
4944 match self.resolve_definition_of_name_in_module(containing_module,
4947 NoNameDefinition => {
4948 // We failed to resolve the name. Report an error.
4951 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4952 return Some((def, last_private.or(lp)));
4957 fn resolve_identifier_in_local_ribs(&mut self,
4959 namespace: Namespace,
4962 // Check the local set of ribs.
4966 let renamed = mtwt_resolve(ident);
4967 let mut value_ribs = self.value_ribs.borrow_mut();
4968 search_result = self.search_ribs(value_ribs.get(),
4973 let name = ident.name;
4974 let mut type_ribs = self.type_ribs.borrow_mut();
4975 search_result = self.search_ribs(type_ribs.get(),
4981 match search_result {
4982 Some(DlDef(def)) => {
4983 debug!("(resolving path in local ribs) resolved `{}` to \
4985 token::get_ident(ident),
4989 Some(DlField) | Some(DlImpl(_)) | None => {
4995 fn resolve_item_by_identifier_in_lexical_scope(&mut self,
4997 namespace: Namespace)
4998 -> Option<(Def, LastPrivate)> {
5000 match self.resolve_item_in_lexical_scope(self.current_module,
5003 DontSearchThroughModules) {
5004 Success((target, _)) => {
5005 match (*target.bindings).def_for_namespace(namespace) {
5007 // This can happen if we were looking for a type and
5008 // found a module instead. Modules don't have defs.
5009 debug!("(resolving item path by identifier in lexical \
5010 scope) failed to resolve {} after success...",
5011 token::get_ident(ident));
5015 debug!("(resolving item path in lexical scope) \
5016 resolved `{}` to item",
5017 token::get_ident(ident));
5018 // This lookup is "all public" because it only searched
5019 // for one identifier in the current module (couldn't
5020 // have passed through reexports or anything like that.
5021 return Some((def, LastMod(AllPublic)));
5026 fail!("unexpected indeterminate result");
5029 debug!("(resolving item path by identifier in lexical scope) \
5030 failed to resolve {}", token::get_ident(ident));
5036 fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
5037 self.emit_errors = false;
5039 self.emit_errors = true;
5043 fn resolve_error(&mut self, span: Span, s: &str) {
5044 if self.emit_errors {
5045 self.session.span_err(span, s);
5049 fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5051 let this = &mut *self;
5053 let mut maybes: ~[token::InternedString] = ~[];
5054 let mut values: ~[uint] = ~[];
5057 let value_ribs = this.value_ribs.borrow();
5058 value_ribs.get().len()
5062 let value_ribs = this.value_ribs.borrow();
5063 let bindings = value_ribs.get()[j].bindings.borrow();
5064 for (&k, _) in bindings.get().iter() {
5065 maybes.push(token::get_name(k));
5066 values.push(uint::MAX);
5070 let mut smallest = 0;
5071 for (i, other) in maybes.iter().enumerate() {
5072 values[i] = name.lev_distance(other.get());
5074 if values[i] <= values[smallest] {
5079 if values.len() > 0 &&
5080 values[smallest] != uint::MAX &&
5081 values[smallest] < name.len() + 2 &&
5082 values[smallest] <= max_distance &&
5083 name != maybes[smallest].get() {
5085 Some(maybes[smallest].get().to_str())
5092 fn resolve_expr(&mut self, expr: &Expr) {
5093 // First, record candidate traits for this expression if it could
5094 // result in the invocation of a method call.
5096 self.record_candidate_traits_for_expr_if_necessary(expr);
5098 // Next, resolve the node.
5100 // The interpretation of paths depends on whether the path has
5101 // multiple elements in it or not.
5103 ExprPath(ref path) => {
5104 // This is a local path in the value namespace. Walk through
5105 // scopes looking for it.
5107 match self.resolve_path(expr.id, path, ValueNS, true) {
5109 // Write the result into the def map.
5110 debug!("(resolving expr) resolved `{}`",
5111 self.path_idents_to_str(path));
5113 // First-class methods are not supported yet; error
5116 (DefMethod(..), _) => {
5117 self.resolve_error(expr.span,
5118 "first-class methods \
5119 are not supported");
5120 self.session.span_note(expr.span,
5128 self.record_def(expr.id, def);
5131 let wrong_name = self.path_idents_to_str(path);
5132 // Be helpful if the name refers to a struct
5133 // (The pattern matching def_tys where the id is in self.structs
5134 // matches on regular structs while excluding tuple- and enum-like
5135 // structs, which wouldn't result in this error.)
5136 match self.with_no_errors(|this|
5137 this.resolve_path(expr.id, path, TypeNS, false)) {
5138 Some((DefTy(struct_id), _))
5139 if self.structs.contains(&struct_id) => {
5140 self.resolve_error(expr.span,
5141 format!("`{}` is a structure name, but \
5143 uses it like a function name",
5146 self.session.span_note(expr.span,
5147 format!("Did you mean to write: \
5148 `{} \\{ /* fields */ \\}`?",
5153 // limit search to 5 to reduce the number
5154 // of stupid suggestions
5155 match self.find_best_match_for_name(wrong_name, 5) {
5157 self.resolve_error(expr.span,
5158 format!("unresolved name `{}`. \
5159 Did you mean `{}`?",
5163 self.resolve_error(expr.span,
5164 format!("unresolved name `{}`.",
5172 visit::walk_expr(self, expr, ());
5175 ExprFnBlock(fn_decl, block) |
5176 ExprProc(fn_decl, block) => {
5177 self.resolve_function(FunctionRibKind(expr.id, block.id),
5178 Some(fn_decl), NoTypeParameters,
5182 ExprStruct(ref path, _, _) => {
5183 // Resolve the path to the structure it goes to.
5184 match self.resolve_path(expr.id, path, TypeNS, false) {
5185 Some((DefTy(class_id), lp)) | Some((DefStruct(class_id), lp))
5186 if self.structs.contains(&class_id) => {
5187 let class_def = DefStruct(class_id);
5188 self.record_def(expr.id, (class_def, lp));
5190 Some(definition @ (DefVariant(_, class_id, _), _))
5191 if self.structs.contains(&class_id) => {
5192 self.record_def(expr.id, definition);
5195 debug!("(resolving expression) didn't find struct \
5196 def: {:?}", result);
5197 let msg = format!("`{}` does not name a structure",
5198 self.path_idents_to_str(path));
5199 self.resolve_error(path.span, msg);
5203 visit::walk_expr(self, expr, ());
5206 ExprLoop(_, Some(label)) => {
5207 self.with_label_rib(|this| {
5208 let def_like = DlDef(DefLabel(expr.id));
5210 let mut label_ribs = this.label_ribs.borrow_mut();
5211 let rib = label_ribs.get()[label_ribs.get().len() -
5213 let mut bindings = rib.bindings.borrow_mut();
5214 let renamed = mtwt_resolve(label);
5215 bindings.get().insert(renamed, def_like);
5218 visit::walk_expr(this, expr, ());
5222 ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
5224 ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5225 let mut label_ribs = self.label_ribs.borrow_mut();
5226 let renamed = mtwt_resolve(label);
5227 match self.search_ribs(label_ribs.get(), renamed, expr.span) {
5229 self.resolve_error(expr.span,
5230 format!("use of undeclared label `{}`",
5231 token::get_ident(label))),
5232 Some(DlDef(def @ DefLabel(_))) => {
5233 // Since this def is a label, it is never read.
5234 self.record_def(expr.id, (def, LastMod(AllPublic)))
5237 self.session.span_bug(expr.span,
5238 "label wasn't mapped to a \
5245 visit::walk_expr(self, expr, ());
5250 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5252 ExprField(_, ident, _) => {
5253 // FIXME(#6890): Even though you can't treat a method like a
5254 // field, we need to add any trait methods we find that match
5255 // the field name so that we can do some nice error reporting
5256 // later on in typeck.
5257 let traits = self.search_for_traits_containing_method(ident);
5258 self.trait_map.insert(expr.id, traits);
5260 ExprMethodCall(ident, _, _) => {
5261 debug!("(recording candidate traits for expr) recording \
5264 let traits = self.search_for_traits_containing_method(ident);
5265 self.trait_map.insert(expr.id, traits);
5273 fn search_for_traits_containing_method(&mut self, name: Ident) -> ~[DefId] {
5274 debug!("(searching for traits containing method) looking for '{}'",
5275 token::get_ident(name));
5277 let mut found_traits = ~[];
5278 let mut search_module = self.current_module;
5279 let method_map = self.method_map.borrow();
5280 match method_map.get().find(&name.name) {
5281 Some(candidate_traits) => loop {
5282 // Look for the current trait.
5283 match self.current_trait_refs {
5284 Some(ref trait_def_ids) => {
5285 for trait_def_id in trait_def_ids.iter() {
5286 if candidate_traits.contains(trait_def_id) {
5287 self.add_trait_info(&mut found_traits,
5298 // Look for trait children.
5299 self.populate_module_if_necessary(search_module);
5301 let children = search_module.children.borrow();
5302 for (_, &child_names) in children.get().iter() {
5303 let def = match child_names.def_for_namespace(TypeNS) {
5307 let trait_def_id = match def {
5308 DefTrait(trait_def_id) => trait_def_id,
5311 if candidate_traits.contains(&trait_def_id) {
5312 self.add_trait_info(&mut found_traits, trait_def_id,
5317 // Look for imports.
5318 let import_resolutions = search_module.import_resolutions
5320 for (_, &import) in import_resolutions.get().iter() {
5321 let target = match import.target_for_namespace(TypeNS) {
5323 Some(target) => target,
5325 let did = match target.bindings.def_for_namespace(TypeNS) {
5326 Some(DefTrait(trait_def_id)) => trait_def_id,
5327 Some(..) | None => continue,
5329 if candidate_traits.contains(&did) {
5330 self.add_trait_info(&mut found_traits, did, name);
5331 self.used_imports.insert((import.type_id.get(), TypeNS));
5335 match search_module.parent_link {
5336 NoParentLink | ModuleParentLink(..) => break,
5337 BlockParentLink(parent_module, _) => {
5338 search_module = parent_module;
5345 return found_traits;
5348 fn add_trait_info(&self,
5349 found_traits: &mut ~[DefId],
5350 trait_def_id: DefId,
5352 debug!("(adding trait info) found trait {}:{} for method '{}'",
5355 token::get_ident(name));
5356 found_traits.push(trait_def_id);
5359 fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
5360 debug!("(recording def) recording {:?} for {:?}, last private {:?}",
5362 assert!(match lp {LastImport{..} => false, _ => true},
5363 "Import should only be used for `use` directives");
5364 self.last_private.insert(node_id, lp);
5365 let mut def_map = self.def_map.borrow_mut();
5366 def_map.get().insert_or_update_with(node_id, def, |_, old_value| {
5367 // Resolve appears to "resolve" the same ID multiple
5368 // times, so here is a sanity check it at least comes to
5369 // the same conclusion! - nmatsakis
5370 if def != *old_value {
5371 self.session.bug(format!("node_id {:?} resolved first to {:?} \
5372 and then {:?}", node_id, *old_value, def));
5377 fn enforce_default_binding_mode(&mut self,
5379 pat_binding_mode: BindingMode,
5381 match pat_binding_mode {
5382 BindByValue(_) => {}
5386 format!("cannot use `ref` binding mode with {}",
5393 // Unused import checking
5395 // Although this is mostly a lint pass, it lives in here because it depends on
5396 // resolve data structures and because it finalises the privacy information for
5397 // `use` directives.
5400 fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
5401 let mut visitor = UnusedImportCheckVisitor{ resolver: self };
5402 visit::walk_crate(&mut visitor, krate, ());
5405 fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
5406 // Ignore is_public import statements because there's no way to be sure
5407 // whether they're used or not. Also ignore imports with a dummy span
5408 // because this means that they were generated in some fashion by the
5409 // compiler and we don't need to consider them.
5410 if vi.vis == Public { return }
5411 if vi.span == DUMMY_SP { return }
5414 ViewItemExternMod(..) => {} // ignore
5415 ViewItemUse(ref path) => {
5416 for p in path.iter() {
5418 ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
5419 ViewPathList(_, ref list, _) => {
5420 for i in list.iter() {
5421 self.finalize_import(i.node.id, i.span);
5424 ViewPathGlob(_, id) => {
5425 if !self.used_imports.contains(&(id, TypeNS)) &&
5426 !self.used_imports.contains(&(id, ValueNS)) {
5427 self.session.add_lint(UnusedImports, id, p.span, ~"unused import");
5436 // We have information about whether `use` (import) directives are actually used now.
5437 // If an import is not used at all, we signal a lint error. If an import is only used
5438 // for a single namespace, we remove the other namespace from the recorded privacy
5439 // information. That means in privacy.rs, we will only check imports and namespaces
5440 // which are used. In particular, this means that if an import could name either a
5441 // public or private item, we will check the correct thing, dependent on how the import
5443 fn finalize_import(&mut self, id: NodeId, span: Span) {
5444 debug!("finalizing import uses for {}", self.session.codemap.span_to_snippet(span));
5446 if !self.used_imports.contains(&(id, TypeNS)) &&
5447 !self.used_imports.contains(&(id, ValueNS)) {
5448 self.session.add_lint(UnusedImports, id, span, ~"unused import");
5451 let (v_priv, t_priv) = match self.last_private.find(&id) {
5452 Some(&LastImport{value_priv: v,
5455 type_used: _}) => (v, t),
5456 Some(_) => fail!("We should only have LastImport for `use` directives"),
5460 let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
5465 let t_used = if self.used_imports.contains(&(id, TypeNS)) {
5471 match (v_priv, t_priv) {
5472 // Since some items may be both in the value _and_ type namespaces (e.g., structs)
5473 // we might have two LastPrivates pointing at the same thing. There is no point
5474 // checking both, so lets not check the value one.
5475 (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
5479 self.last_private.insert(id, LastImport{value_priv: v_priv,
5482 type_used: t_used});
5488 // Diagnostics are not particularly efficient, because they're rarely
5492 /// A somewhat inefficient routine to obtain the name of a module.
5493 fn module_to_str(&mut self, module_: @Module) -> ~str {
5494 let mut idents = ~[];
5495 let mut current_module = module_;
5497 match current_module.parent_link {
5501 ModuleParentLink(module_, name) => {
5503 current_module = module_;
5505 BlockParentLink(module_, _) => {
5506 idents.push(special_idents::opaque);
5507 current_module = module_;
5512 if idents.len() == 0 {
5515 return self.idents_to_str(idents.move_rev_iter().collect::<~[ast::Ident]>());
5518 #[allow(dead_code)] // useful for debugging
5519 fn dump_module(&mut self, module_: @Module) {
5520 debug!("Dump of module `{}`:", self.module_to_str(module_));
5522 debug!("Children:");
5523 self.populate_module_if_necessary(module_);
5524 let children = module_.children.borrow();
5525 for (&name, _) in children.get().iter() {
5526 debug!("* {}", token::get_name(name));
5529 debug!("Import resolutions:");
5530 let import_resolutions = module_.import_resolutions.borrow();
5531 for (&name, import_resolution) in import_resolutions.get().iter() {
5533 match import_resolution.target_for_namespace(ValueNS) {
5534 None => { value_repr = ~""; }
5536 value_repr = ~" value:?";
5542 match import_resolution.target_for_namespace(TypeNS) {
5543 None => { type_repr = ~""; }
5545 type_repr = ~" type:?";
5550 debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
5555 pub struct CrateMap {
5557 exp_map2: ExportMap2,
5558 trait_map: TraitMap,
5559 external_exports: ExternalExports,
5560 last_private_map: LastPrivateMap,
5563 /// Entry point to crate resolution.
5564 pub fn resolve_crate(session: Session,
5565 lang_items: @LanguageItems,
5568 let mut resolver = Resolver(session, lang_items, krate.span);
5569 resolver.resolve(krate);
5570 let Resolver { def_map, export_map2, trait_map, last_private,
5571 external_exports, .. } = resolver;
5574 exp_map2: export_map2,
5575 trait_map: trait_map,
5576 external_exports: external_exports,
5577 last_private_map: last_private,