1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 #[allow(non_camel_case_types)];
13 use driver::session::Session;
14 use metadata::csearch;
15 use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
16 use middle::lang_items::LanguageItems;
17 use middle::lint::{UnnecessaryQualification, UnusedImports};
18 use middle::pat_util::pat_bindings;
19 use util::nodemap::{NodeMap, DefIdSet};
23 use syntax::ast_util::{def_id_of_def, local_def};
24 use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
25 use syntax::ext::mtwt;
26 use syntax::parse::token::special_idents;
27 use syntax::parse::token;
28 use syntax::print::pprust::path_to_str;
29 use syntax::codemap::{Span, DUMMY_SP, Pos};
30 use syntax::opt_vec::OptVec;
32 use syntax::visit::Visitor;
34 use std::cell::{Cell, RefCell};
36 use std::mem::replace;
38 use collections::{HashMap, HashSet};
41 pub type DefMap = @RefCell<NodeMap<Def>>;
45 binding_mode: BindingMode,
48 // Map from the name in a pattern to its binding mode.
49 type BindingMap = HashMap<Name,binding_info>;
51 // Trait method resolution
52 pub type TraitMap = NodeMap<Vec<DefId> >;
54 // This is the replacement export map. It maps a module to all of the exports
56 pub type ExportMap2 = @RefCell<NodeMap<Vec<Export2> >>;
59 name: ~str, // The name of the target.
60 def_id: DefId, // The definition of the target.
63 // This set contains all exported definitions from external crates. The set does
64 // not contain any entries from local crates.
65 pub type ExternalExports = DefIdSet;
68 pub type LastPrivateMap = NodeMap<LastPrivate>;
70 pub enum LastPrivate {
72 // `use` directives (imports) can refer to two separate definitions in the
73 // type and value namespaces. We record here the last private node for each
74 // and whether the import is in fact used for each.
75 // If the Option<PrivateDep> fields are None, it means there is no defintion
77 LastImport{value_priv: Option<PrivateDep>,
78 value_used: ImportUse,
79 type_priv: Option<PrivateDep>,
80 type_used: ImportUse},
88 // How an import is used.
91 Unused, // The import is not used.
92 Used, // The import is used.
96 fn or(self, other: LastPrivate) -> LastPrivate {
98 (me, LastMod(AllPublic)) => me,
105 enum PatternBindingMode {
107 LocalIrrefutableMode,
108 ArgumentIrrefutableMode,
111 #[deriving(Eq, Hash)]
118 enum NamespaceError {
125 /// A NamespaceResult represents the result of resolving an import in
126 /// a particular namespace. The result is either definitely-resolved,
127 /// definitely- unresolved, or unknown.
128 enum NamespaceResult {
129 /// Means that resolve hasn't gathered enough information yet to determine
130 /// whether the name is bound in this namespace. (That is, it hasn't
131 /// resolved all `use` directives yet.)
133 /// Means that resolve has determined that the name is definitely
134 /// not bound in the namespace.
136 /// Means that resolve has determined that the name is bound in the Module
137 /// argument, and specified by the NameBindings argument.
138 BoundResult(@Module, @NameBindings)
141 impl NamespaceResult {
142 fn is_unknown(&self) -> bool {
144 UnknownResult => true,
150 enum NameDefinition {
151 NoNameDefinition, //< The name was unbound.
152 ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
153 ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
156 impl<'a> Visitor<()> for Resolver<'a> {
157 fn visit_item(&mut self, item: &Item, _: ()) {
158 self.resolve_item(item);
160 fn visit_arm(&mut self, arm: &Arm, _: ()) {
161 self.resolve_arm(arm);
163 fn visit_block(&mut self, block: &Block, _: ()) {
164 self.resolve_block(block);
166 fn visit_expr(&mut self, expr: &Expr, _: ()) {
167 self.resolve_expr(expr);
169 fn visit_local(&mut self, local: &Local, _: ()) {
170 self.resolve_local(local);
172 fn visit_ty(&mut self, ty: &Ty, _: ()) {
173 self.resolve_type(ty);
177 /// Contains data for specific types of import directives.
178 enum ImportDirectiveSubclass {
179 SingleImport(Ident /* target */, Ident /* source */),
183 /// The context that we thread through while building the reduced graph.
185 enum ReducedGraphParent {
186 ModuleReducedGraphParent(@Module)
189 impl ReducedGraphParent {
190 fn module(&self) -> @Module {
192 ModuleReducedGraphParent(m) => {
199 enum ResolveResult<T> {
200 Failed, // Failed to resolve the name.
201 Indeterminate, // Couldn't determine due to unresolved globs.
202 Success(T) // Successfully resolved the import.
205 impl<T> ResolveResult<T> {
206 fn indeterminate(&self) -> bool {
207 match *self { Indeterminate => true, _ => false }
211 enum TypeParameters<'a> {
212 NoTypeParameters, //< No type parameters.
213 HasTypeParameters(&'a Generics, //< Type parameters.
214 NodeId, //< ID of the enclosing item
216 // The index to start numbering the type parameters at.
217 // This is zero if this is the outermost set of type
218 // parameters, or equal to the number of outer type
219 // parameters. For example, if we have:
222 // fn method<U>() { ... }
225 // The index at the method site will be 1, because the
226 // outer T had index 0.
229 // The kind of the rib used for type parameters.
233 // The rib kind controls the translation of argument or local definitions
234 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
237 // No translation needs to be applied.
240 // We passed through a function scope at the given node ID. Translate
241 // upvars as appropriate.
242 FunctionRibKind(NodeId /* func id */, NodeId /* body id */),
244 // We passed through an impl or trait and are now in one of its
245 // methods. Allow references to ty params that impl or trait
246 // binds. Disallow any other upvars (including other ty params that are
248 // parent; method itself
249 MethodRibKind(NodeId, MethodSort),
251 // We passed through a function *item* scope. Disallow upvars.
252 OpaqueFunctionRibKind,
254 // We're in a constant item. Can't refer to dynamic stuff.
258 // Methods can be required or provided. Required methods only occur in traits.
264 enum UseLexicalScopeFlag {
269 enum SearchThroughModulesFlag {
270 DontSearchThroughModules,
274 enum ModulePrefixResult {
276 PrefixFound(@Module, uint)
280 enum NameSearchType {
281 /// We're doing a name search in order to resolve a `use` directive.
284 /// We're doing a name search in order to resolve a path type, a path
285 /// expression, or a path pattern.
289 enum BareIdentifierPatternResolution {
290 FoundStructOrEnumVariant(Def, LastPrivate),
291 FoundConst(Def, LastPrivate),
292 BareIdentifierPatternUnresolved
295 // Specifies how duplicates should be handled when adding a child item if
296 // another item exists with the same name in some namespace.
298 enum DuplicateCheckingMode {
299 ForbidDuplicateModules,
300 ForbidDuplicateTypes,
301 ForbidDuplicateValues,
302 ForbidDuplicateTypesAndValues,
308 bindings: RefCell<HashMap<Name, DefLike>>,
313 fn new(kind: RibKind) -> Rib {
315 bindings: RefCell::new(HashMap::new()),
321 /// One import directive.
322 struct ImportDirective {
323 module_path: Vec<Ident> ,
324 subclass: @ImportDirectiveSubclass,
327 is_public: bool, // see note in ImportResolution about how to use this
330 impl ImportDirective {
331 fn new(module_path: Vec<Ident> ,
332 subclass: @ImportDirectiveSubclass,
338 module_path: module_path,
342 is_public: is_public,
347 /// The item that an import resolves to.
350 target_module: @Module,
351 bindings: @NameBindings,
355 fn new(target_module: @Module, bindings: @NameBindings) -> Target {
357 target_module: target_module,
363 /// An ImportResolution represents a particular `use` directive.
364 struct ImportResolution {
365 /// Whether this resolution came from a `use` or a `pub use`. Note that this
366 /// should *not* be used whenever resolution is being performed, this is
367 /// only looked at for glob imports statements currently. Privacy testing
368 /// occurs during a later phase of compilation.
369 is_public: Cell<bool>,
371 // The number of outstanding references to this name. When this reaches
372 // zero, outside modules can count on the targets being correct. Before
373 // then, all bets are off; future imports could override this name.
374 outstanding_references: Cell<uint>,
376 /// The value that this `use` directive names, if there is one.
377 value_target: RefCell<Option<Target>>,
378 /// The source node of the `use` directive leading to the value target
380 value_id: Cell<NodeId>,
382 /// The type that this `use` directive names, if there is one.
383 type_target: RefCell<Option<Target>>,
384 /// The source node of the `use` directive leading to the type target
386 type_id: Cell<NodeId>,
389 impl ImportResolution {
390 fn new(id: NodeId, is_public: bool) -> ImportResolution {
392 type_id: Cell::new(id),
393 value_id: Cell::new(id),
394 outstanding_references: Cell::new(0),
395 value_target: RefCell::new(None),
396 type_target: RefCell::new(None),
397 is_public: Cell::new(is_public),
401 fn target_for_namespace(&self, namespace: Namespace)
404 TypeNS => return self.type_target.get(),
405 ValueNS => return self.value_target.get(),
409 fn id(&self, namespace: Namespace) -> NodeId {
411 TypeNS => self.type_id.get(),
412 ValueNS => self.value_id.get(),
417 /// The link from a module up to its nearest parent node.
420 ModuleParentLink(@Module, Ident),
421 BlockParentLink(@Module, NodeId)
424 /// The type of module this is.
434 /// One node in the tree of modules.
436 parent_link: ParentLink,
437 def_id: Cell<Option<DefId>>,
438 kind: Cell<ModuleKind>,
441 children: RefCell<HashMap<Name, @NameBindings>>,
442 imports: RefCell<Vec<@ImportDirective> >,
444 // The external module children of this node that were declared with
446 external_module_children: RefCell<HashMap<Name, @Module>>,
448 // The anonymous children of this node. Anonymous children are pseudo-
449 // modules that are implicitly created around items contained within
452 // For example, if we have this:
460 // There will be an anonymous module created around `g` with the ID of the
461 // entry block for `f`.
462 anonymous_children: RefCell<NodeMap<@Module>>,
464 // The status of resolving each import in this module.
465 import_resolutions: RefCell<HashMap<Name, @ImportResolution>>,
467 // The number of unresolved globs that this module exports.
468 glob_count: Cell<uint>,
470 // The index of the import we're resolving.
471 resolved_import_count: Cell<uint>,
473 // Whether this module is populated. If not populated, any attempt to
474 // access the children must be preceded with a
475 // `populate_module_if_necessary` call.
476 populated: Cell<bool>,
480 fn new(parent_link: ParentLink,
481 def_id: Option<DefId>,
487 parent_link: parent_link,
488 def_id: Cell::new(def_id),
489 kind: Cell::new(kind),
490 is_public: is_public,
491 children: RefCell::new(HashMap::new()),
492 imports: RefCell::new(Vec::new()),
493 external_module_children: RefCell::new(HashMap::new()),
494 anonymous_children: RefCell::new(NodeMap::new()),
495 import_resolutions: RefCell::new(HashMap::new()),
496 glob_count: Cell::new(0),
497 resolved_import_count: Cell::new(0),
498 populated: Cell::new(!external),
502 fn all_imports_resolved(&self) -> bool {
503 let mut imports = self.imports.borrow_mut();
504 return imports.get().len() == self.resolved_import_count.get();
508 // Records a possibly-private type definition.
511 is_public: bool, // see note in ImportResolution about how to use this
512 module_def: Option<@Module>,
513 type_def: Option<Def>,
514 type_span: Option<Span>
517 // Records a possibly-private value definition.
520 is_public: bool, // see note in ImportResolution about how to use this
522 value_span: Option<Span>,
525 // Records the definitions (at most one for each namespace) that a name is
527 struct NameBindings {
528 type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
529 value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
532 /// Ways in which a trait can be referenced
533 enum TraitReferenceType {
534 TraitImplementation, // impl SomeTrait for T { ... }
535 TraitDerivation, // trait T : SomeTrait { ... }
536 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
540 /// Creates a new module in this set of name bindings.
541 fn define_module(&self,
542 parent_link: ParentLink,
543 def_id: Option<DefId>,
548 // Merges the module with the existing type def or creates a new one.
549 let module_ = @Module::new(parent_link, def_id, kind, external,
551 match self.type_def.get() {
553 self.type_def.set(Some(TypeNsDef {
554 is_public: is_public,
555 module_def: Some(module_),
561 self.type_def.set(Some(TypeNsDef {
562 is_public: is_public,
563 module_def: Some(module_),
565 type_def: type_def.type_def
571 /// Sets the kind of the module, creating a new one if necessary.
572 fn set_module_kind(&self,
573 parent_link: ParentLink,
574 def_id: Option<DefId>,
579 match self.type_def.get() {
581 let module = @Module::new(parent_link, def_id, kind,
582 external, is_public);
583 self.type_def.set(Some(TypeNsDef {
584 is_public: is_public,
585 module_def: Some(module),
591 match type_def.module_def {
593 let module = @Module::new(parent_link,
598 self.type_def.set(Some(TypeNsDef {
599 is_public: is_public,
600 module_def: Some(module),
601 type_def: type_def.type_def,
605 Some(module_def) => module_def.kind.set(kind),
611 /// Records a type definition.
612 fn define_type(&self, def: Def, sp: Span, is_public: bool) {
613 // Merges the type with the existing type def or creates a new one.
614 match self.type_def.get() {
616 self.type_def.set(Some(TypeNsDef {
620 is_public: is_public,
624 self.type_def.set(Some(TypeNsDef {
627 module_def: type_def.module_def,
628 is_public: is_public,
634 /// Records a value definition.
635 fn define_value(&self, def: Def, sp: Span, is_public: bool) {
636 self.value_def.set(Some(ValueNsDef {
638 value_span: Some(sp),
639 is_public: is_public,
643 /// Returns the module node if applicable.
644 fn get_module_if_available(&self) -> Option<@Module> {
645 let type_def = self.type_def.borrow();
646 match *type_def.get() {
647 Some(ref type_def) => (*type_def).module_def,
653 * Returns the module node. Fails if this node does not have a module
656 fn get_module(&self) -> @Module {
657 match self.get_module_if_available() {
659 fail!("get_module called on a node with no module \
662 Some(module_def) => module_def
666 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
668 TypeNS => return self.type_def.get().is_some(),
669 ValueNS => return self.value_def.get().is_some()
673 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
675 TypeNS => match self.type_def.get() {
676 Some(def) => def.is_public, None => false
678 ValueNS => match self.value_def.get() {
679 Some(def) => def.is_public, None => false
684 fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
687 match self.type_def.get() {
690 match type_def.type_def {
691 Some(type_def) => Some(type_def),
693 match type_def.module_def {
695 match module.def_id.get() {
696 Some(did) => Some(DefMod(did)),
708 match self.value_def.get() {
710 Some(value_def) => Some(value_def.def)
716 fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
717 if self.defined_in_namespace(namespace) {
720 match self.type_def.get() {
722 Some(type_def) => type_def.type_span
726 match self.value_def.get() {
728 Some(value_def) => value_def.value_span
738 fn NameBindings() -> NameBindings {
740 type_def: RefCell::new(None),
741 value_def: RefCell::new(None),
745 /// Interns the names of the primitive types.
746 struct PrimitiveTypeTable {
747 primitive_types: HashMap<Name, PrimTy>,
750 impl PrimitiveTypeTable {
751 fn intern(&mut self, string: &str, primitive_type: PrimTy) {
752 self.primitive_types.insert(token::intern(string), primitive_type);
756 fn PrimitiveTypeTable() -> PrimitiveTypeTable {
757 let mut table = PrimitiveTypeTable {
758 primitive_types: HashMap::new()
761 table.intern("bool", TyBool);
762 table.intern("char", TyChar);
763 table.intern("f32", TyFloat(TyF32));
764 table.intern("f64", TyFloat(TyF64));
765 table.intern("int", TyInt(TyI));
766 table.intern("i8", TyInt(TyI8));
767 table.intern("i16", TyInt(TyI16));
768 table.intern("i32", TyInt(TyI32));
769 table.intern("i64", TyInt(TyI64));
770 table.intern("str", TyStr);
771 table.intern("uint", TyUint(TyU));
772 table.intern("u8", TyUint(TyU8));
773 table.intern("u16", TyUint(TyU16));
774 table.intern("u32", TyUint(TyU32));
775 table.intern("u64", TyUint(TyU64));
781 fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
784 ModuleError => "module",
786 ValueError => "value",
790 fn Resolver<'a>(session: &'a Session,
791 lang_items: @LanguageItems,
792 crate_span: Span) -> Resolver<'a> {
793 let graph_root = @NameBindings();
795 graph_root.define_module(NoParentLink,
796 Some(DefId { krate: 0, node: 0 }),
802 let current_module = graph_root.get_module();
804 let this = Resolver {
806 lang_items: lang_items,
808 // The outermost module has def ID 0; this is not reflected in the
811 graph_root: graph_root,
813 method_map: @RefCell::new(HashMap::new()),
814 structs: HashSet::new(),
816 unresolved_imports: 0,
818 current_module: current_module,
819 value_ribs: @RefCell::new(Vec::new()),
820 type_ribs: @RefCell::new(Vec::new()),
821 label_ribs: @RefCell::new(Vec::new()),
823 current_trait_refs: None,
825 self_ident: special_idents::self_,
826 type_self_ident: special_idents::type_self,
828 primitive_type_table: @PrimitiveTypeTable(),
830 namespaces: vec!(TypeNS, ValueNS),
832 def_map: @RefCell::new(NodeMap::new()),
833 export_map2: @RefCell::new(NodeMap::new()),
834 trait_map: NodeMap::new(),
835 used_imports: HashSet::new(),
836 external_exports: DefIdSet::new(),
837 last_private: NodeMap::new(),
845 /// The main resolver class.
846 struct Resolver<'a> {
847 session: &'a Session,
848 lang_items: @LanguageItems,
850 graph_root: @NameBindings,
852 method_map: @RefCell<HashMap<Name, HashSet<DefId>>>,
853 structs: HashSet<DefId>,
855 // The number of imports that are currently unresolved.
856 unresolved_imports: uint,
858 // The module that represents the current item scope.
859 current_module: @Module,
861 // The current set of local scopes, for values.
862 // FIXME #4948: Reuse ribs to avoid allocation.
863 value_ribs: @RefCell<Vec<@Rib> >,
865 // The current set of local scopes, for types.
866 type_ribs: @RefCell<Vec<@Rib> >,
868 // The current set of local scopes, for labels.
869 label_ribs: @RefCell<Vec<@Rib> >,
871 // The trait that the current context can refer to.
872 current_trait_refs: Option<Vec<DefId> >,
874 // The ident for the keyword "self".
876 // The ident for the non-keyword "Self".
877 type_self_ident: Ident,
879 // The idents for the primitive types.
880 primitive_type_table: @PrimitiveTypeTable,
882 // The four namespaces.
883 namespaces: Vec<Namespace> ,
886 export_map2: ExportMap2,
888 external_exports: ExternalExports,
889 last_private: LastPrivateMap,
891 // Whether or not to print error messages. Can be set to true
892 // when getting additional info for error message suggestions,
893 // so as to avoid printing duplicate errors
896 used_imports: HashSet<(NodeId, Namespace)>,
899 struct BuildReducedGraphVisitor<'a, 'b> {
900 resolver: &'a mut Resolver<'b>,
903 impl<'a, 'b> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a, 'b> {
905 fn visit_item(&mut self, item: &Item, context: ReducedGraphParent) {
906 let p = self.resolver.build_reduced_graph_for_item(item, context);
907 visit::walk_item(self, item, p);
910 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem,
911 context: ReducedGraphParent) {
912 self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
915 let mut v = BuildReducedGraphVisitor{ resolver: r };
916 visit::walk_foreign_item(&mut v, foreign_item, c);
920 fn visit_view_item(&mut self, view_item: &ViewItem, context: ReducedGraphParent) {
921 self.resolver.build_reduced_graph_for_view_item(view_item, context);
924 fn visit_block(&mut self, block: &Block, context: ReducedGraphParent) {
925 let np = self.resolver.build_reduced_graph_for_block(block, context);
926 visit::walk_block(self, block, np);
931 struct UnusedImportCheckVisitor<'a, 'b> { resolver: &'a mut Resolver<'b> }
933 impl<'a, 'b> Visitor<()> for UnusedImportCheckVisitor<'a, 'b> {
934 fn visit_view_item(&mut self, vi: &ViewItem, _: ()) {
935 self.resolver.check_for_item_unused_imports(vi);
936 visit::walk_view_item(self, vi, ());
940 impl<'a> Resolver<'a> {
941 /// The main name resolution procedure.
942 fn resolve(&mut self, krate: &ast::Crate) {
943 self.build_reduced_graph(krate);
944 self.session.abort_if_errors();
946 self.resolve_imports();
947 self.session.abort_if_errors();
949 self.record_exports();
950 self.session.abort_if_errors();
952 self.resolve_crate(krate);
953 self.session.abort_if_errors();
955 self.check_for_unused_imports(krate);
959 // Reduced graph building
961 // Here we build the "reduced graph": the graph of the module tree without
962 // any imports resolved.
965 /// Constructs the reduced graph for the entire crate.
966 fn build_reduced_graph(&mut self, krate: &ast::Crate) {
968 ModuleReducedGraphParent(self.graph_root.get_module());
970 let mut visitor = BuildReducedGraphVisitor { resolver: self, };
971 visit::walk_crate(&mut visitor, krate, initial_parent);
974 /// Returns the current module tracked by the reduced graph parent.
975 fn get_module_from_parent(&mut self,
976 reduced_graph_parent: ReducedGraphParent)
978 match reduced_graph_parent {
979 ModuleReducedGraphParent(module_) => {
986 * Adds a new child item to the module definition of the parent node and
987 * returns its corresponding name bindings as well as the current parent.
988 * Or, if we're inside a block, creates (or reuses) an anonymous module
989 * corresponding to the innermost block ID and returns the name bindings
990 * as well as the newly-created parent.
992 * If this node does not have a module definition and we are not inside
995 fn add_child(&mut self,
997 reduced_graph_parent: ReducedGraphParent,
998 duplicate_checking_mode: DuplicateCheckingMode,
999 // For printing errors
1001 -> (@NameBindings, ReducedGraphParent) {
1002 // If this is the immediate descendant of a module, then we add the
1003 // child name directly. Otherwise, we create or reuse an anonymous
1004 // module and add the child to that.
1007 match reduced_graph_parent {
1008 ModuleReducedGraphParent(parent_module) => {
1009 module_ = parent_module;
1013 // Add or reuse the child.
1014 let new_parent = ModuleReducedGraphParent(module_);
1016 let children = module_.children.borrow();
1017 children.get().find_copy(&name.name)
1021 let child = @NameBindings();
1022 let mut children = module_.children.borrow_mut();
1023 children.get().insert(name.name, child);
1024 return (child, new_parent);
1027 // Enforce the duplicate checking mode:
1029 // * If we're requesting duplicate module checking, check that
1030 // there isn't a module in the module with the same name.
1032 // * If we're requesting duplicate type checking, check that
1033 // there isn't a type in the module with the same name.
1035 // * If we're requesting duplicate value checking, check that
1036 // there isn't a value in the module with the same name.
1038 // * If we're requesting duplicate type checking and duplicate
1039 // value checking, check that there isn't a duplicate type
1040 // and a duplicate value with the same name.
1042 // * If no duplicate checking was requested at all, do
1045 let mut duplicate_type = NoError;
1046 let ns = match duplicate_checking_mode {
1047 ForbidDuplicateModules => {
1048 if child.get_module_if_available().is_some() {
1049 duplicate_type = ModuleError;
1053 ForbidDuplicateTypes => {
1054 match child.def_for_namespace(TypeNS) {
1055 Some(DefMod(_)) | None => {}
1056 Some(_) => duplicate_type = TypeError
1060 ForbidDuplicateValues => {
1061 if child.defined_in_namespace(ValueNS) {
1062 duplicate_type = ValueError;
1066 ForbidDuplicateTypesAndValues => {
1068 match child.def_for_namespace(TypeNS) {
1069 Some(DefMod(_)) | None => {}
1072 duplicate_type = TypeError;
1075 if child.defined_in_namespace(ValueNS) {
1076 duplicate_type = ValueError;
1081 OverwriteDuplicates => None
1083 if duplicate_type != NoError {
1084 // Return an error here by looking up the namespace that
1085 // had the duplicate.
1086 let ns = ns.unwrap();
1087 self.resolve_error(sp,
1088 format!("duplicate definition of {} `{}`",
1089 namespace_error_to_str(duplicate_type),
1090 token::get_ident(name)));
1092 let r = child.span_for_namespace(ns);
1093 for sp in r.iter() {
1094 self.session.span_note(*sp,
1095 format!("first definition of {} `{}` here",
1096 namespace_error_to_str(duplicate_type),
1097 token::get_ident(name)));
1101 return (child, new_parent);
1106 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1107 // If the block has view items, we need an anonymous module.
1108 if block.view_items.len() > 0 {
1112 // Check each statement.
1113 for statement in block.stmts.iter() {
1114 match statement.node {
1115 StmtDecl(declaration, _) => {
1116 match declaration.node {
1131 // If we found neither view items nor items, we don't need to create
1132 // an anonymous module.
1137 fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Ident)
1140 ModuleReducedGraphParent(module_) => {
1141 return ModuleParentLink(module_, name);
1146 /// Constructs the reduced graph for one item.
1147 fn build_reduced_graph_for_item(&mut self,
1149 parent: ReducedGraphParent)
1150 -> ReducedGraphParent
1152 let ident = item.ident;
1154 let is_public = item.vis == ast::Public;
1158 let (name_bindings, new_parent) =
1159 self.add_child(ident, parent, ForbidDuplicateModules, sp);
1161 let parent_link = self.get_parent_link(new_parent, ident);
1162 let def_id = DefId { krate: 0, node: item.id };
1163 name_bindings.define_module(parent_link,
1167 item.vis == ast::Public,
1170 ModuleReducedGraphParent(name_bindings.get_module())
1173 ItemForeignMod(..) => parent,
1175 // These items live in the value namespace.
1176 ItemStatic(_, m, _) => {
1177 let (name_bindings, _) =
1178 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1179 let mutbl = m == ast::MutMutable;
1181 name_bindings.define_value
1182 (DefStatic(local_def(item.id), mutbl), sp, is_public);
1185 ItemFn(_, purity, _, _, _) => {
1186 let (name_bindings, new_parent) =
1187 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1189 let def = DefFn(local_def(item.id), purity);
1190 name_bindings.define_value(def, sp, is_public);
1194 // These items live in the type namespace.
1196 let (name_bindings, _) =
1197 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1199 name_bindings.define_type
1200 (DefTy(local_def(item.id)), sp, is_public);
1204 ItemEnum(ref enum_definition, _) => {
1205 let (name_bindings, new_parent) =
1206 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1208 name_bindings.define_type
1209 (DefTy(local_def(item.id)), sp, is_public);
1211 for &variant in (*enum_definition).variants.iter() {
1212 self.build_reduced_graph_for_variant(
1221 // These items live in both the type and value namespaces.
1222 ItemStruct(struct_def, _) => {
1223 // Adding to both Type and Value namespaces or just Type?
1224 let (forbid, ctor_id) = match struct_def.ctor_id {
1225 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1226 None => (ForbidDuplicateTypes, None)
1229 let (name_bindings, new_parent) = self.add_child(ident, parent, forbid, sp);
1231 // Define a name in the type namespace.
1232 name_bindings.define_type(DefTy(local_def(item.id)), sp, is_public);
1234 // If this is a newtype or unit-like struct, define a name
1235 // in the value namespace as well
1236 ctor_id.while_some(|cid| {
1237 name_bindings.define_value(DefStruct(local_def(cid)), sp,
1242 // Record the def ID of this struct.
1243 self.structs.insert(local_def(item.id));
1248 ItemImpl(_, None, ty, ref methods) => {
1249 // If this implements an anonymous trait, then add all the
1250 // methods within to a new module, if the type was defined
1251 // within this module.
1253 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1254 // should modify anonymous traits to only be implementable in
1255 // the same module that declared the type.
1257 // Create the module and add all methods.
1259 TyPath(ref path, _, _) if path.segments.len() == 1 => {
1260 let name = path_to_ident(path);
1262 let existing_parent_opt = {
1263 let children = parent.module().children.borrow();
1264 children.get().find_copy(&name.name)
1266 let new_parent = match existing_parent_opt {
1267 // It already exists
1268 Some(child) if child.get_module_if_available()
1270 child.get_module().kind.get() ==
1272 ModuleReducedGraphParent(child.get_module())
1274 // Create the module
1276 let (name_bindings, new_parent) =
1277 self.add_child(name,
1279 ForbidDuplicateModules,
1283 self.get_parent_link(new_parent, ident);
1284 let def_id = local_def(item.id);
1287 !name_bindings.defined_in_namespace(ns) ||
1288 name_bindings.defined_in_public_namespace(ns);
1290 name_bindings.define_module(parent_link,
1297 ModuleReducedGraphParent(
1298 name_bindings.get_module())
1302 // For each method...
1303 for method in methods.iter() {
1304 // Add the method to the module.
1305 let ident = method.ident;
1306 let (method_name_bindings, _) =
1307 self.add_child(ident,
1309 ForbidDuplicateValues,
1311 let def = match method.explicit_self.node {
1313 // Static methods become
1314 // `def_static_method`s.
1315 DefStaticMethod(local_def(method.id),
1321 // Non-static methods become
1323 DefMethod(local_def(method.id), None)
1327 let is_public = method.vis == ast::Public;
1328 method_name_bindings.define_value(def,
1339 ItemImpl(_, Some(_), _, _) => parent,
1341 ItemTrait(_, _, ref methods) => {
1342 let (name_bindings, new_parent) =
1343 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1345 // Add all the methods within to a new module.
1346 let parent_link = self.get_parent_link(parent, ident);
1347 name_bindings.define_module(parent_link,
1348 Some(local_def(item.id)),
1351 item.vis == ast::Public,
1353 let module_parent = ModuleReducedGraphParent(name_bindings.
1356 // Add the names of all the methods to the trait info.
1357 let mut method_names = HashMap::new();
1358 for method in methods.iter() {
1359 let ty_m = trait_method_to_ty_method(method);
1361 let ident = ty_m.ident;
1363 // Add it as a name in the trait module.
1364 let def = match ty_m.explicit_self.node {
1366 // Static methods become `def_static_method`s.
1367 DefStaticMethod(local_def(ty_m.id),
1368 FromTrait(local_def(item.id)),
1372 // Non-static methods become `def_method`s.
1373 DefMethod(local_def(ty_m.id),
1374 Some(local_def(item.id)))
1378 let (method_name_bindings, _) =
1379 self.add_child(ident,
1381 ForbidDuplicateValues,
1383 method_name_bindings.define_value(def, ty_m.span, true);
1385 // Add it to the trait info if not static.
1386 match ty_m.explicit_self.node {
1389 method_names.insert(ident.name, ());
1394 let def_id = local_def(item.id);
1395 for (name, _) in method_names.iter() {
1396 let mut method_map = self.method_map.borrow_mut();
1397 if !method_map.get().contains_key(name) {
1398 method_map.get().insert(*name, HashSet::new());
1400 match method_map.get().find_mut(name) {
1401 Some(s) => { s.insert(def_id); },
1402 _ => fail!("can't happen"),
1406 name_bindings.define_type(DefTrait(def_id), sp, is_public);
1409 ItemMac(..) => parent
1413 // Constructs the reduced graph for one variant. Variants exist in the
1414 // type and/or value namespaces.
1415 fn build_reduced_graph_for_variant(&mut self,
1418 parent: ReducedGraphParent,
1419 parent_public: bool) {
1420 let ident = variant.node.name;
1421 // FIXME: this is unfortunate to have to do this privacy calculation
1422 // here. This should be living in middle::privacy, but it's
1423 // necessary to keep around in some form becaues of glob imports...
1424 let is_public = parent_public && variant.node.vis != ast::Private;
1426 match variant.node.kind {
1427 TupleVariantKind(_) => {
1428 let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues,
1430 child.define_value(DefVariant(item_id,
1431 local_def(variant.node.id), false),
1432 variant.span, is_public);
1434 StructVariantKind(_) => {
1435 let (child, _) = self.add_child(ident, parent, ForbidDuplicateTypesAndValues,
1437 child.define_type(DefVariant(item_id,
1438 local_def(variant.node.id), true),
1439 variant.span, is_public);
1440 self.structs.insert(local_def(variant.node.id));
1445 /// Constructs the reduced graph for one 'view item'. View items consist
1446 /// of imports and use directives.
1447 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1448 parent: ReducedGraphParent) {
1449 match view_item.node {
1450 ViewItemUse(ref view_paths) => {
1451 for view_path in view_paths.iter() {
1452 // Extract and intern the module part of the path. For
1453 // globs and lists, the path is found directly in the AST;
1454 // for simple paths we have to munge the path a little.
1456 let mut module_path = Vec::new();
1457 match view_path.node {
1458 ViewPathSimple(_, ref full_path, _) => {
1459 let path_len = full_path.segments.len();
1460 assert!(path_len != 0);
1462 for (i, segment) in full_path.segments
1465 if i != path_len - 1 {
1466 module_path.push(segment.identifier)
1471 ViewPathGlob(ref module_ident_path, _) |
1472 ViewPathList(ref module_ident_path, _, _) => {
1473 for segment in module_ident_path.segments.iter() {
1474 module_path.push(segment.identifier)
1479 // Build up the import directives.
1480 let module_ = self.get_module_from_parent(parent);
1481 let is_public = view_item.vis == ast::Public;
1482 match view_path.node {
1483 ViewPathSimple(binding, ref full_path, id) => {
1485 full_path.segments.last().unwrap().identifier;
1486 let subclass = @SingleImport(binding,
1488 self.build_import_directive(module_,
1495 ViewPathList(_, ref source_idents, _) => {
1496 for source_ident in source_idents.iter() {
1497 let name = source_ident.node.name;
1498 let subclass = @SingleImport(name, name);
1499 self.build_import_directive(
1501 module_path.clone(),
1504 source_ident.node.id,
1508 ViewPathGlob(_, id) => {
1509 self.build_import_directive(module_,
1520 ViewItemExternCrate(name, _, node_id) => {
1521 // n.b. we don't need to look at the path option here, because cstore already did
1522 match self.session.cstore.find_extern_mod_stmt_cnum(node_id) {
1524 let def_id = DefId { krate: crate_id, node: 0 };
1525 self.external_exports.insert(def_id);
1526 let parent_link = ModuleParentLink
1527 (self.get_module_from_parent(parent), name);
1528 let external_module = @Module::new(parent_link,
1535 let mut external_module_children =
1536 parent.module().external_module_children.borrow_mut();
1537 external_module_children.get().insert(
1542 self.build_reduced_graph_for_external_crate(
1545 None => {} // Ignore.
1551 /// Constructs the reduced graph for one foreign item.
1552 fn build_reduced_graph_for_foreign_item(&mut self,
1553 foreign_item: &ForeignItem,
1554 parent: ReducedGraphParent,
1556 ReducedGraphParent|) {
1557 let name = foreign_item.ident;
1558 let is_public = foreign_item.vis == ast::Public;
1559 let (name_bindings, new_parent) =
1560 self.add_child(name, parent, ForbidDuplicateValues,
1563 match foreign_item.node {
1564 ForeignItemFn(_, ref generics) => {
1565 let def = DefFn(local_def(foreign_item.id), UnsafeFn);
1566 name_bindings.define_value(def, foreign_item.span, is_public);
1568 self.with_type_parameter_rib(
1569 HasTypeParameters(generics,
1573 |this| f(this, new_parent));
1575 ForeignItemStatic(_, m) => {
1576 let def = DefStatic(local_def(foreign_item.id), m);
1577 name_bindings.define_value(def, foreign_item.span, is_public);
1584 fn build_reduced_graph_for_block(&mut self,
1586 parent: ReducedGraphParent)
1587 -> ReducedGraphParent
1589 if self.block_needs_anonymous_module(block) {
1590 let block_id = block.id;
1592 debug!("(building reduced graph for block) creating a new \
1593 anonymous module for block {}",
1596 let parent_module = self.get_module_from_parent(parent);
1597 let new_module = @Module::new(
1598 BlockParentLink(parent_module, block_id),
1600 AnonymousModuleKind,
1604 let mut anonymous_children = parent_module.anonymous_children
1606 anonymous_children.get().insert(block_id, new_module);
1607 ModuleReducedGraphParent(new_module)
1614 fn handle_external_def(&mut self,
1617 child_name_bindings: @NameBindings,
1620 new_parent: ReducedGraphParent) {
1621 debug!("(building reduced graph for \
1622 external crate) building external def, priv {:?}",
1624 let is_public = vis == ast::Public;
1625 let is_exported = is_public && match new_parent {
1626 ModuleReducedGraphParent(module) => {
1627 match module.def_id.get() {
1629 Some(did) => self.external_exports.contains(&did)
1634 self.external_exports.insert(def_id_of_def(def));
1637 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1639 match child_name_bindings.type_def.get() {
1640 Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1641 debug!("(building reduced graph for external crate) \
1642 already created module");
1643 module_def.def_id.set(Some(def_id));
1646 debug!("(building reduced graph for \
1647 external crate) building module \
1649 let parent_link = self.get_parent_link(new_parent, ident);
1651 child_name_bindings.define_module(parent_link,
1664 DefMod(_) | DefForeignMod(_) => {}
1665 DefVariant(_, variant_id, is_struct) => {
1666 debug!("(building reduced graph for external crate) building \
1669 // We assume the parent is visible, or else we wouldn't have seen
1670 // it. Also variants are public-by-default if the parent was also
1672 let is_public = vis != ast::Private;
1674 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1675 self.structs.insert(variant_id);
1677 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1680 DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
1681 debug!("(building reduced graph for external \
1682 crate) building value (fn/static) {}", final_ident);
1683 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1685 DefTrait(def_id) => {
1686 debug!("(building reduced graph for external \
1687 crate) building type {}", final_ident);
1689 // If this is a trait, add all the method names
1690 // to the trait info.
1692 let method_def_ids =
1693 csearch::get_trait_method_def_ids(&self.session.cstore, def_id);
1694 let mut interned_method_names = HashSet::new();
1695 for &method_def_id in method_def_ids.iter() {
1696 let (method_name, explicit_self) =
1697 csearch::get_method_name_and_explicit_self(&self.session.cstore,
1700 debug!("(building reduced graph for \
1701 external crate) ... adding \
1703 token::get_ident(method_name));
1705 // Add it to the trait info if not static.
1706 if explicit_self != SelfStatic {
1707 interned_method_names.insert(method_name.name);
1710 self.external_exports.insert(method_def_id);
1713 for name in interned_method_names.iter() {
1714 let mut method_map = self.method_map.borrow_mut();
1715 if !method_map.get().contains_key(name) {
1716 method_map.get().insert(*name, HashSet::new());
1718 match method_map.get().find_mut(name) {
1719 Some(s) => { s.insert(def_id); },
1720 _ => fail!("can't happen"),
1724 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1726 // Define a module if necessary.
1727 let parent_link = self.get_parent_link(new_parent, ident);
1728 child_name_bindings.set_module_kind(parent_link,
1736 debug!("(building reduced graph for external \
1737 crate) building type {}", final_ident);
1739 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1741 DefStruct(def_id) => {
1742 debug!("(building reduced graph for external \
1743 crate) building type and value for {}",
1745 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1746 if csearch::get_struct_fields(&self.session.cstore, def_id).len() == 0 {
1747 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1749 self.structs.insert(def_id);
1752 debug!("(building reduced graph for external crate) \
1753 ignoring {:?}", def);
1754 // Ignored; handled elsewhere.
1756 DefArg(..) | DefLocal(..) | DefPrimTy(..) |
1757 DefTyParam(..) | DefBinding(..) |
1758 DefUse(..) | DefUpvar(..) | DefRegion(..) |
1759 DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
1760 fail!("didn't expect `{:?}`", def);
1765 /// Builds the reduced graph for a single item in an external crate.
1766 fn build_reduced_graph_for_external_crate_def(&mut self,
1770 visibility: Visibility) {
1773 // Add the new child item, if necessary.
1775 DefForeignMod(def_id) => {
1776 // Foreign modules have no names. Recur and populate
1778 csearch::each_child_of_item(&self.session.cstore,
1783 self.build_reduced_graph_for_external_crate_def(
1791 let (child_name_bindings, new_parent) =
1792 self.add_child(ident,
1793 ModuleReducedGraphParent(root),
1794 OverwriteDuplicates,
1797 self.handle_external_def(def,
1799 child_name_bindings,
1800 token::get_ident(ident).get(),
1807 // We only process static methods of impls here.
1808 match csearch::get_type_name_if_impl(&self.session.cstore, def) {
1810 Some(final_ident) => {
1811 let static_methods_opt =
1812 csearch::get_static_methods_if_impl(&self.session.cstore, def);
1813 match static_methods_opt {
1814 Some(ref static_methods) if
1815 static_methods.len() >= 1 => {
1816 debug!("(building reduced graph for \
1817 external crate) processing \
1818 static methods for type name {}",
1819 token::get_ident(final_ident));
1821 let (child_name_bindings, new_parent) =
1824 ModuleReducedGraphParent(root),
1825 OverwriteDuplicates,
1828 // Process the static methods. First,
1829 // create the module.
1831 match child_name_bindings.type_def.get() {
1833 module_def: Some(module_def),
1836 // We already have a module. This
1838 type_module = module_def;
1840 // Mark it as an impl module if
1842 type_module.kind.set(ImplModuleKind);
1846 self.get_parent_link(new_parent,
1848 child_name_bindings.define_module(
1856 child_name_bindings.
1861 // Add each static method to the module.
1863 ModuleReducedGraphParent(type_module);
1864 for static_method_info in
1865 static_methods.iter() {
1866 let ident = static_method_info.ident;
1867 debug!("(building reduced graph for \
1868 external crate) creating \
1869 static method '{}'",
1870 token::get_ident(ident));
1872 let (method_name_bindings, _) =
1873 self.add_child(ident,
1875 OverwriteDuplicates,
1878 static_method_info.def_id,
1879 static_method_info.purity);
1881 method_name_bindings.define_value(
1883 visibility == ast::Public);
1887 // Otherwise, do nothing.
1888 Some(_) | None => {}
1894 debug!("(building reduced graph for external crate) \
1900 /// Builds the reduced graph rooted at the given external module.
1901 fn populate_external_module(&mut self, module: @Module) {
1902 debug!("(populating external module) attempting to populate {}",
1903 self.module_to_str(module));
1905 let def_id = match module.def_id.get() {
1907 debug!("(populating external module) ... no def ID!");
1910 Some(def_id) => def_id,
1913 csearch::each_child_of_item(&self.session.cstore,
1915 |def_like, child_ident, visibility| {
1916 debug!("(populating external module) ... found ident: {}",
1917 token::get_ident(child_ident));
1918 self.build_reduced_graph_for_external_crate_def(module,
1923 module.populated.set(true)
1926 /// Ensures that the reduced graph rooted at the given external module
1927 /// is built, building it if it is not.
1928 fn populate_module_if_necessary(&mut self, module: @Module) {
1929 if !module.populated.get() {
1930 self.populate_external_module(module)
1932 assert!(module.populated.get())
1935 /// Builds the reduced graph rooted at the 'use' directive for an external
1937 fn build_reduced_graph_for_external_crate(&mut self,
1939 csearch::each_top_level_item_of_crate(&self.session.cstore,
1944 |def_like, ident, visibility| {
1945 self.build_reduced_graph_for_external_crate_def(root,
1952 /// Creates and adds an import directive to the given module.
1953 fn build_import_directive(&mut self,
1955 module_path: Vec<Ident> ,
1956 subclass: @ImportDirectiveSubclass,
1960 let directive = @ImportDirective::new(module_path,
1965 let mut imports = module_.imports.borrow_mut();
1966 imports.get().push(directive);
1969 // Bump the reference count on the name. Or, if this is a glob, set
1970 // the appropriate flag.
1973 SingleImport(target, _) => {
1974 debug!("(building import directive) building import \
1976 self.idents_to_str(directive.module_path.as_slice()),
1977 token::get_ident(target));
1979 let mut import_resolutions = module_.import_resolutions
1981 match import_resolutions.get().find(&target.name) {
1982 Some(&resolution) => {
1983 debug!("(building import directive) bumping \
1985 resolution.outstanding_references.set(
1986 resolution.outstanding_references.get() + 1);
1988 // the source of this name is different now
1989 resolution.type_id.set(id);
1990 resolution.value_id.set(id);
1993 debug!("(building import directive) creating new");
1994 let resolution = @ImportResolution::new(id, is_public);
1995 resolution.outstanding_references.set(1);
1996 import_resolutions.get().insert(target.name,
2002 // Set the glob flag. This tells us that we don't know the
2003 // module's exports ahead of time.
2005 module_.glob_count.set(module_.glob_count.get() + 1);
2009 self.unresolved_imports += 1;
2012 // Import resolution
2014 // This is a fixed-point algorithm. We resolve imports until our efforts
2015 // are stymied by an unresolved import; then we bail out of the current
2016 // module and continue. We terminate successfully once no more imports
2017 // remain or unsuccessfully when no forward progress in resolving imports
2020 /// Resolves all imports for the crate. This method performs the fixed-
2021 /// point iteration.
2022 fn resolve_imports(&mut self) {
2024 let mut prev_unresolved_imports = 0;
2026 debug!("(resolving imports) iteration {}, {} imports left",
2027 i, self.unresolved_imports);
2029 let module_root = self.graph_root.get_module();
2030 self.resolve_imports_for_module_subtree(module_root);
2032 if self.unresolved_imports == 0 {
2033 debug!("(resolving imports) success");
2037 if self.unresolved_imports == prev_unresolved_imports {
2038 self.report_unresolved_imports(module_root);
2043 prev_unresolved_imports = self.unresolved_imports;
2047 /// Attempts to resolve imports for the given module and all of its
2049 fn resolve_imports_for_module_subtree(&mut self,
2051 debug!("(resolving imports for module subtree) resolving {}",
2052 self.module_to_str(module_));
2053 self.resolve_imports_for_module(module_);
2055 self.populate_module_if_necessary(module_);
2057 let children = module_.children.borrow();
2058 for (_, &child_node) in children.get().iter() {
2059 match child_node.get_module_if_available() {
2063 Some(child_module) => {
2064 self.resolve_imports_for_module_subtree(child_module);
2070 let anonymous_children = module_.anonymous_children.borrow();
2071 for (_, &child_module) in anonymous_children.get().iter() {
2072 self.resolve_imports_for_module_subtree(child_module);
2076 /// Attempts to resolve imports for the given module only.
2077 fn resolve_imports_for_module(&mut self, module: @Module) {
2078 if module.all_imports_resolved() {
2079 debug!("(resolving imports for module) all imports resolved for \
2081 self.module_to_str(module));
2085 let mut imports = module.imports.borrow_mut();
2086 let import_count = imports.get().len();
2087 while module.resolved_import_count.get() < import_count {
2088 let import_index = module.resolved_import_count.get();
2089 let import_directive = *imports.get().get(import_index);
2090 match self.resolve_import_for_module(module, import_directive) {
2092 // We presumably emitted an error. Continue.
2093 let msg = format!("failed to resolve import `{}`",
2094 self.import_path_to_str(
2095 import_directive.module_path
2097 *import_directive.subclass));
2098 self.resolve_error(import_directive.span, msg);
2101 // Bail out. We'll come around next time.
2109 module.resolved_import_count
2110 .set(module.resolved_import_count.get() + 1);
2114 fn idents_to_str(&mut self, idents: &[Ident]) -> ~str {
2115 let mut first = true;
2116 let mut result = ~"";
2117 for ident in idents.iter() {
2121 result.push_str("::")
2123 result.push_str(token::get_ident(*ident).get());
2128 fn path_idents_to_str(&mut self, path: &Path) -> ~str {
2129 let identifiers: Vec<ast::Ident> = path.segments
2131 .map(|seg| seg.identifier)
2133 self.idents_to_str(identifiers.as_slice())
2136 fn import_directive_subclass_to_str(&mut self,
2137 subclass: ImportDirectiveSubclass)
2140 SingleImport(_, source) => {
2141 token::get_ident(source).get().to_str()
2147 fn import_path_to_str(&mut self,
2149 subclass: ImportDirectiveSubclass)
2151 if idents.is_empty() {
2152 self.import_directive_subclass_to_str(subclass)
2155 self.idents_to_str(idents),
2156 self.import_directive_subclass_to_str(subclass)))
2160 /// Attempts to resolve the given import. The return value indicates
2161 /// failure if we're certain the name does not exist, indeterminate if we
2162 /// don't know whether the name exists at the moment due to other
2163 /// currently-unresolved imports, or success if we know the name exists.
2164 /// If successful, the resolved bindings are written into the module.
2165 fn resolve_import_for_module(&mut self,
2167 import_directive: @ImportDirective)
2168 -> ResolveResult<()> {
2169 let mut resolution_result = Failed;
2170 let module_path = &import_directive.module_path;
2172 debug!("(resolving import for module) resolving import `{}::...` in \
2174 self.idents_to_str(module_path.as_slice()),
2175 self.module_to_str(module_));
2177 // First, resolve the module path for the directive, if necessary.
2178 let container = if module_path.len() == 0 {
2179 // Use the crate root.
2180 Some((self.graph_root.get_module(), LastMod(AllPublic)))
2182 match self.resolve_module_path(module_,
2183 module_path.as_slice(),
2184 DontUseLexicalScope,
2185 import_directive.span,
2190 resolution_result = Indeterminate;
2193 Success(container) => Some(container),
2199 Some((containing_module, lp)) => {
2200 // We found the module that the target is contained
2201 // within. Attempt to resolve the import within it.
2203 match *import_directive.subclass {
2204 SingleImport(target, source) => {
2206 self.resolve_single_import(module_,
2215 self.resolve_glob_import(module_,
2217 import_directive.id,
2218 import_directive.is_public,
2225 // Decrement the count of unresolved imports.
2226 match resolution_result {
2228 assert!(self.unresolved_imports >= 1);
2229 self.unresolved_imports -= 1;
2232 // Nothing to do here; just return the error.
2236 // Decrement the count of unresolved globs if necessary. But only if
2237 // the resolution result is indeterminate -- otherwise we'll stop
2238 // processing imports here. (See the loop in
2239 // resolve_imports_for_module.)
2241 if !resolution_result.indeterminate() {
2242 match *import_directive.subclass {
2244 assert!(module_.glob_count.get() >= 1);
2245 module_.glob_count.set(module_.glob_count.get() - 1);
2247 SingleImport(..) => {
2253 return resolution_result;
2256 fn create_name_bindings_from_module(module: @Module) -> NameBindings {
2258 type_def: RefCell::new(Some(TypeNsDef {
2260 module_def: Some(module),
2264 value_def: RefCell::new(None),
2268 fn resolve_single_import(&mut self,
2270 containing_module: @Module,
2273 directive: &ImportDirective,
2275 -> ResolveResult<()> {
2276 debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2277 `{}` id {}, last private {:?}",
2278 token::get_ident(target),
2279 self.module_to_str(containing_module),
2280 token::get_ident(source),
2281 self.module_to_str(module_),
2287 LastImport{..} => self.session.span_bug(directive.span,
2288 "Not expecting Import here, must be LastMod"),
2291 // We need to resolve both namespaces for this to succeed.
2294 let mut value_result = UnknownResult;
2295 let mut type_result = UnknownResult;
2297 // Search for direct children of the containing module.
2298 self.populate_module_if_necessary(containing_module);
2301 let children = containing_module.children.borrow();
2302 match children.get().find(&source.name) {
2306 Some(child_name_bindings) => {
2307 if child_name_bindings.defined_in_namespace(ValueNS) {
2308 value_result = BoundResult(containing_module,
2309 *child_name_bindings);
2311 if child_name_bindings.defined_in_namespace(TypeNS) {
2312 type_result = BoundResult(containing_module,
2313 *child_name_bindings);
2319 // Unless we managed to find a result in both namespaces (unlikely),
2320 // search imports as well.
2321 let mut value_used_reexport = false;
2322 let mut type_used_reexport = false;
2323 match (value_result, type_result) {
2324 (BoundResult(..), BoundResult(..)) => {} // Continue.
2326 // If there is an unresolved glob at this point in the
2327 // containing module, bail out. We don't know enough to be
2328 // able to resolve this import.
2330 if containing_module.glob_count.get() > 0 {
2331 debug!("(resolving single import) unresolved glob; \
2333 return Indeterminate;
2336 // Now search the exported imports within the containing
2339 let import_resolutions = containing_module.import_resolutions
2341 match import_resolutions.get().find(&source.name) {
2343 // The containing module definitely doesn't have an
2344 // exported import with the name in question. We can
2345 // therefore accurately report that the names are
2348 if value_result.is_unknown() {
2349 value_result = UnboundResult;
2351 if type_result.is_unknown() {
2352 type_result = UnboundResult;
2355 Some(import_resolution)
2356 if import_resolution.outstanding_references.get()
2359 fn get_binding(this: &mut Resolver,
2360 import_resolution: @ImportResolution,
2361 namespace: Namespace)
2362 -> NamespaceResult {
2364 // Import resolutions must be declared with "pub"
2365 // in order to be exported.
2366 if !import_resolution.is_public.get() {
2367 return UnboundResult;
2370 match (*import_resolution).
2371 target_for_namespace(namespace) {
2373 return UnboundResult;
2376 let id = import_resolution.id(namespace);
2377 this.used_imports.insert((id, namespace));
2378 return BoundResult(target.target_module,
2384 // The name is an import which has been fully
2385 // resolved. We can, therefore, just follow it.
2386 if value_result.is_unknown() {
2387 value_result = get_binding(self, *import_resolution,
2389 value_used_reexport = import_resolution.is_public.get();
2391 if type_result.is_unknown() {
2392 type_result = get_binding(self, *import_resolution,
2394 type_used_reexport = import_resolution.is_public.get();
2399 // The import is unresolved. Bail out.
2400 debug!("(resolving single import) unresolved import; \
2402 return Indeterminate;
2408 // If we didn't find a result in the type namespace, search the
2409 // external modules.
2410 let mut value_used_public = false;
2411 let mut type_used_public = false;
2413 BoundResult(..) => {}
2416 let mut external_module_children =
2417 containing_module.external_module_children
2419 external_module_children.get().find_copy(&source.name)
2422 None => {} // Continue.
2425 @Resolver::create_name_bindings_from_module(
2427 type_result = BoundResult(containing_module,
2429 type_used_public = true;
2435 // We've successfully resolved the import. Write the results in.
2436 let import_resolution = {
2437 let import_resolutions = module_.import_resolutions.borrow();
2438 assert!(import_resolutions.get().contains_key(&target.name));
2439 import_resolutions.get().get_copy(&target.name)
2442 match value_result {
2443 BoundResult(target_module, name_bindings) => {
2444 debug!("(resolving single import) found value target");
2445 import_resolution.value_target.set(
2446 Some(Target::new(target_module, name_bindings)));
2447 import_resolution.value_id.set(directive.id);
2448 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2450 UnboundResult => { /* Continue. */ }
2452 fail!("value result should be known at this point");
2456 BoundResult(target_module, name_bindings) => {
2457 debug!("(resolving single import) found type target: {:?}",
2458 {name_bindings.type_def.get().unwrap().type_def});
2459 import_resolution.type_target.set(
2460 Some(Target::new(target_module, name_bindings)));
2461 import_resolution.type_id.set(directive.id);
2462 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2464 UnboundResult => { /* Continue. */ }
2466 fail!("type result should be known at this point");
2470 if import_resolution.value_target.get().is_none() &&
2471 import_resolution.type_target.get().is_none() {
2472 let msg = format!("unresolved import: there is no \
2474 token::get_ident(source),
2475 self.module_to_str(containing_module));
2476 self.resolve_error(directive.span, msg);
2479 let value_used_public = value_used_reexport || value_used_public;
2480 let type_used_public = type_used_reexport || type_used_public;
2482 assert!(import_resolution.outstanding_references.get() >= 1);
2483 import_resolution.outstanding_references.set(
2484 import_resolution.outstanding_references.get() - 1);
2486 // record what this import resolves to for later uses in documentation,
2487 // this may resolve to either a value or a type, but for documentation
2488 // purposes it's good enough to just favor one over the other.
2489 let value_private = match import_resolution.value_target.get() {
2491 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2492 let mut def_map = self.def_map.borrow_mut();
2493 def_map.get().insert(directive.id, def);
2494 let did = def_id_of_def(def);
2495 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2497 // AllPublic here and below is a dummy value, it should never be used because
2498 // _exists is false.
2501 let type_private = match import_resolution.type_target.get() {
2503 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2504 let mut def_map = self.def_map.borrow_mut();
2505 def_map.get().insert(directive.id, def);
2506 let did = def_id_of_def(def);
2507 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2512 self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2514 type_priv: type_private,
2517 debug!("(resolving single import) successfully resolved import");
2521 // Resolves a glob import. Note that this function cannot fail; it either
2522 // succeeds or bails out (as importing * from an empty module or a module
2523 // that exports nothing is valid).
2524 fn resolve_glob_import(&mut self,
2526 containing_module: @Module,
2530 -> ResolveResult<()> {
2531 // This function works in a highly imperative manner; it eagerly adds
2532 // everything it can to the list of import resolutions of the module
2534 debug!("(resolving glob import) resolving glob import {}", id);
2536 // We must bail out if the node has unresolved imports of any kind
2537 // (including globs).
2538 if !(*containing_module).all_imports_resolved() {
2539 debug!("(resolving glob import) target module has unresolved \
2540 imports; bailing out");
2541 return Indeterminate;
2544 assert_eq!(containing_module.glob_count.get(), 0);
2546 // Add all resolved imports from the containing module.
2547 let import_resolutions = containing_module.import_resolutions
2549 for (ident, target_import_resolution) in import_resolutions.get()
2551 debug!("(resolving glob import) writing module resolution \
2553 target_import_resolution.type_target.get().is_none(),
2554 self.module_to_str(module_));
2556 if !target_import_resolution.is_public.get() {
2557 debug!("(resolving glob import) nevermind, just kidding");
2561 // Here we merge two import resolutions.
2562 let mut import_resolutions = module_.import_resolutions
2564 match import_resolutions.get().find(ident) {
2566 // Simple: just copy the old import resolution.
2567 let new_import_resolution =
2568 @ImportResolution::new(id, is_public);
2569 new_import_resolution.value_target.set(
2570 target_import_resolution.value_target.get());
2571 new_import_resolution.type_target.set(
2572 target_import_resolution.type_target.get());
2574 import_resolutions.get().insert
2575 (*ident, new_import_resolution);
2577 Some(&dest_import_resolution) => {
2578 // Merge the two import resolutions at a finer-grained
2581 match target_import_resolution.value_target.get() {
2585 Some(value_target) => {
2586 dest_import_resolution.value_target.set(
2587 Some(value_target));
2590 match target_import_resolution.type_target.get() {
2594 Some(type_target) => {
2595 dest_import_resolution.type_target.set(
2599 dest_import_resolution.is_public.set(is_public);
2604 // Add all children from the containing module.
2605 self.populate_module_if_necessary(containing_module);
2608 let children = containing_module.children.borrow();
2609 for (&name, name_bindings) in children.get().iter() {
2610 self.merge_import_resolution(module_, containing_module,
2612 name, *name_bindings);
2616 // Add external module children from the containing module.
2618 let external_module_children =
2619 containing_module.external_module_children.borrow();
2620 for (&name, module) in external_module_children.get().iter() {
2622 @Resolver::create_name_bindings_from_module(*module);
2623 self.merge_import_resolution(module_, containing_module,
2625 name, name_bindings);
2629 // Record the destination of this import
2630 match containing_module.def_id.get() {
2632 let mut def_map = self.def_map.borrow_mut();
2633 def_map.get().insert(id, DefMod(did));
2634 self.last_private.insert(id, lp);
2639 debug!("(resolving glob import) successfully resolved import");
2643 fn merge_import_resolution(&mut self,
2645 containing_module: @Module,
2649 name_bindings: @NameBindings) {
2650 let dest_import_resolution;
2651 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2652 match import_resolutions.get().find(&name) {
2654 // Create a new import resolution from this child.
2655 dest_import_resolution =
2656 @ImportResolution::new(id, is_public);
2657 import_resolutions.get().insert(name,
2658 dest_import_resolution);
2660 Some(&existing_import_resolution) => {
2661 dest_import_resolution = existing_import_resolution;
2665 debug!("(resolving glob import) writing resolution `{}` in `{}` \
2667 token::get_name(name).get().to_str(),
2668 self.module_to_str(containing_module),
2669 self.module_to_str(module_));
2671 // Merge the child item into the import resolution.
2672 if name_bindings.defined_in_public_namespace(ValueNS) {
2673 debug!("(resolving glob import) ... for value target");
2674 dest_import_resolution.value_target.set(
2675 Some(Target::new(containing_module, name_bindings)));
2676 dest_import_resolution.value_id.set(id);
2678 if name_bindings.defined_in_public_namespace(TypeNS) {
2679 debug!("(resolving glob import) ... for type target");
2680 dest_import_resolution.type_target.set(
2681 Some(Target::new(containing_module, name_bindings)));
2682 dest_import_resolution.type_id.set(id);
2684 dest_import_resolution.is_public.set(is_public);
2687 /// Resolves the given module path from the given root `module_`.
2688 fn resolve_module_path_from_root(&mut self,
2690 module_path: &[Ident],
2693 name_search_type: NameSearchType,
2695 -> ResolveResult<(@Module, LastPrivate)> {
2696 let mut search_module = module_;
2697 let mut index = index;
2698 let module_path_len = module_path.len();
2699 let mut closest_private = lp;
2701 // Resolve the module part of the path. This does not involve looking
2702 // upward though scope chains; we simply resolve names directly in
2703 // modules as we go.
2704 while index < module_path_len {
2705 let name = module_path[index];
2706 match self.resolve_name_in_module(search_module,
2711 let segment_name = token::get_ident(name);
2712 let module_name = self.module_to_str(search_module);
2713 if "???" == module_name {
2716 hi: span.lo + Pos::from_uint(segment_name.get().len()),
2717 expn_info: span.expn_info,
2719 self.resolve_error(span,
2720 format!("unresolved import. maybe \
2721 a missing `extern crate \
2726 self.resolve_error(span, format!("unresolved import: could not find `{}` in \
2727 `{}`.", segment_name, module_name));
2731 debug!("(resolving module path for import) module \
2732 resolution is indeterminate: {}",
2733 token::get_ident(name));
2734 return Indeterminate;
2736 Success((target, used_proxy)) => {
2737 // Check to see whether there are type bindings, and, if
2738 // so, whether there is a module within.
2739 match target.bindings.type_def.get() {
2741 match type_def.module_def {
2744 self.resolve_error(span, format!("not a module `{}`",
2745 token::get_ident(name)));
2748 Some(module_def) => {
2749 // If we're doing the search for an
2750 // import, do not allow traits and impls
2752 match (name_search_type,
2753 module_def.kind.get()) {
2754 (ImportSearch, TraitModuleKind) |
2755 (ImportSearch, ImplModuleKind) => {
2758 "cannot import from a trait \
2759 or type implementation");
2763 search_module = module_def;
2765 // Keep track of the closest
2766 // private module used when
2767 // resolving this import chain.
2769 !search_module.is_public {
2770 match search_module.def_id
2774 LastMod(DependsOn(did));
2785 // There are no type bindings at all.
2786 self.resolve_error(span,
2787 format!("not a module `{}`",
2788 token::get_ident(name)));
2798 return Success((search_module, closest_private));
2801 /// Attempts to resolve the module part of an import directive or path
2802 /// rooted at the given module.
2804 /// On success, returns the resolved module, and the closest *private*
2805 /// module found to the destination when resolving this path.
2806 fn resolve_module_path(&mut self,
2808 module_path: &[Ident],
2809 use_lexical_scope: UseLexicalScopeFlag,
2811 name_search_type: NameSearchType)
2812 -> ResolveResult<(@Module, LastPrivate)> {
2813 let module_path_len = module_path.len();
2814 assert!(module_path_len > 0);
2816 debug!("(resolving module path for import) processing `{}` rooted at \
2818 self.idents_to_str(module_path),
2819 self.module_to_str(module_));
2821 // Resolve the module prefix, if any.
2822 let module_prefix_result = self.resolve_module_prefix(module_,
2828 match module_prefix_result {
2830 let mpath = self.idents_to_str(module_path);
2831 match mpath.rfind(':') {
2833 self.resolve_error(span, format!("unresolved import: could not find `{}` \
2835 // idx +- 1 to account for the colons
2837 mpath.slice_from(idx + 1),
2838 mpath.slice_to(idx - 1)));
2845 debug!("(resolving module path for import) indeterminate; \
2847 return Indeterminate;
2849 Success(NoPrefixFound) => {
2850 // There was no prefix, so we're considering the first element
2851 // of the path. How we handle this depends on whether we were
2852 // instructed to use lexical scope or not.
2853 match use_lexical_scope {
2854 DontUseLexicalScope => {
2855 // This is a crate-relative path. We will start the
2856 // resolution process at index zero.
2857 search_module = self.graph_root.get_module();
2859 last_private = LastMod(AllPublic);
2861 UseLexicalScope => {
2862 // This is not a crate-relative path. We resolve the
2863 // first component of the path in the current lexical
2864 // scope and then proceed to resolve below that.
2865 let result = self.resolve_module_in_lexical_scope(
2870 self.resolve_error(span, "unresolved name");
2874 debug!("(resolving module path for import) \
2875 indeterminate; bailing");
2876 return Indeterminate;
2878 Success(containing_module) => {
2879 search_module = containing_module;
2881 last_private = LastMod(AllPublic);
2887 Success(PrefixFound(containing_module, index)) => {
2888 search_module = containing_module;
2889 start_index = index;
2890 last_private = LastMod(DependsOn(containing_module.def_id
2896 self.resolve_module_path_from_root(search_module,
2904 /// Invariant: This must only be called during main resolution, not during
2905 /// import resolution.
2906 fn resolve_item_in_lexical_scope(&mut self,
2909 namespace: Namespace,
2910 search_through_modules:
2911 SearchThroughModulesFlag)
2912 -> ResolveResult<(Target, bool)> {
2913 debug!("(resolving item in lexical scope) resolving `{}` in \
2914 namespace {:?} in `{}`",
2915 token::get_ident(name),
2917 self.module_to_str(module_));
2919 // The current module node is handled specially. First, check for
2920 // its immediate children.
2921 self.populate_module_if_necessary(module_);
2924 let children = module_.children.borrow();
2925 match children.get().find(&name.name) {
2927 if name_bindings.defined_in_namespace(namespace) => {
2928 debug!("top name bindings succeeded");
2929 return Success((Target::new(module_, *name_bindings),
2932 Some(_) | None => { /* Not found; continue. */ }
2936 // Now check for its import directives. We don't have to have resolved
2937 // all its imports in the usual way; this is because chains of
2938 // adjacent import statements are processed as though they mutated the
2940 let import_resolutions = module_.import_resolutions.borrow();
2941 match import_resolutions.get().find(&name.name) {
2943 // Not found; continue.
2945 Some(import_resolution) => {
2946 match (*import_resolution).target_for_namespace(namespace) {
2948 // Not found; continue.
2949 debug!("(resolving item in lexical scope) found \
2950 import resolution, but not in namespace {:?}",
2954 debug!("(resolving item in lexical scope) using \
2955 import resolution");
2956 self.used_imports.insert((import_resolution.id(namespace), namespace));
2957 return Success((target, false));
2963 // Search for external modules.
2964 if namespace == TypeNS {
2966 let external_module_children =
2967 module_.external_module_children.borrow();
2968 external_module_children.get().find_copy(&name.name)
2974 @Resolver::create_name_bindings_from_module(module);
2975 debug!("lower name bindings succeeded");
2976 return Success((Target::new(module_, name_bindings), false));
2981 // Finally, proceed up the scope chain looking for parent modules.
2982 let mut search_module = module_;
2984 // Go to the next parent.
2985 match search_module.parent_link {
2987 // No more parents. This module was unresolved.
2988 debug!("(resolving item in lexical scope) unresolved \
2992 ModuleParentLink(parent_module_node, _) => {
2993 match search_through_modules {
2994 DontSearchThroughModules => {
2995 match search_module.kind.get() {
2996 NormalModuleKind => {
2997 // We stop the search here.
2998 debug!("(resolving item in lexical \
2999 scope) unresolved module: not \
3000 searching through module \
3007 AnonymousModuleKind => {
3008 search_module = parent_module_node;
3012 SearchThroughModules => {
3013 search_module = parent_module_node;
3017 BlockParentLink(parent_module_node, _) => {
3018 search_module = parent_module_node;
3022 // Resolve the name in the parent module.
3023 match self.resolve_name_in_module(search_module,
3028 // Continue up the search chain.
3031 // We couldn't see through the higher scope because of an
3032 // unresolved import higher up. Bail.
3034 debug!("(resolving item in lexical scope) indeterminate \
3035 higher scope; bailing");
3036 return Indeterminate;
3038 Success((target, used_reexport)) => {
3039 // We found the module.
3040 debug!("(resolving item in lexical scope) found name \
3042 return Success((target, used_reexport));
3048 /// Resolves a module name in the current lexical scope.
3049 fn resolve_module_in_lexical_scope(&mut self,
3052 -> ResolveResult<@Module> {
3053 // If this module is an anonymous module, resolve the item in the
3054 // lexical scope. Otherwise, resolve the item from the crate root.
3055 let resolve_result = self.resolve_item_in_lexical_scope(
3056 module_, name, TypeNS, DontSearchThroughModules);
3057 match resolve_result {
3058 Success((target, _)) => {
3059 let bindings = &*target.bindings;
3060 match bindings.type_def.get() {
3062 match type_def.module_def {
3064 error!("!!! (resolving module in lexical \
3065 scope) module wasn't actually a \
3069 Some(module_def) => {
3070 return Success(module_def);
3075 error!("!!! (resolving module in lexical scope) module
3076 wasn't actually a module!");
3082 debug!("(resolving module in lexical scope) indeterminate; \
3084 return Indeterminate;
3087 debug!("(resolving module in lexical scope) failed to \
3094 /// Returns the nearest normal module parent of the given module.
3095 fn get_nearest_normal_module_parent(&mut self, module_: @Module)
3096 -> Option<@Module> {
3097 let mut module_ = module_;
3099 match module_.parent_link {
3100 NoParentLink => return None,
3101 ModuleParentLink(new_module, _) |
3102 BlockParentLink(new_module, _) => {
3103 match new_module.kind.get() {
3104 NormalModuleKind => return Some(new_module),
3108 AnonymousModuleKind => module_ = new_module,
3115 /// Returns the nearest normal module parent of the given module, or the
3116 /// module itself if it is a normal module.
3117 fn get_nearest_normal_module_parent_or_self(&mut self, module_: @Module)
3119 match module_.kind.get() {
3120 NormalModuleKind => return module_,
3124 AnonymousModuleKind => {
3125 match self.get_nearest_normal_module_parent(module_) {
3127 Some(new_module) => new_module
3133 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3134 /// (b) some chain of `super::`.
3135 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3136 fn resolve_module_prefix(&mut self,
3138 module_path: &[Ident])
3139 -> ResolveResult<ModulePrefixResult> {
3140 // Start at the current module if we see `self` or `super`, or at the
3141 // top of the crate otherwise.
3142 let mut containing_module;
3144 let first_module_path_string = token::get_ident(module_path[0]);
3145 if "self" == first_module_path_string.get() {
3147 self.get_nearest_normal_module_parent_or_self(module_);
3149 } else if "super" == first_module_path_string.get() {
3151 self.get_nearest_normal_module_parent_or_self(module_);
3152 i = 0; // We'll handle `super` below.
3154 return Success(NoPrefixFound);
3157 // Now loop through all the `super`s we find.
3158 while i < module_path.len() {
3159 let string = token::get_ident(module_path[i]);
3160 if "super" != string.get() {
3163 debug!("(resolving module prefix) resolving `super` at {}",
3164 self.module_to_str(containing_module));
3165 match self.get_nearest_normal_module_parent(containing_module) {
3166 None => return Failed,
3167 Some(new_module) => {
3168 containing_module = new_module;
3174 debug!("(resolving module prefix) finished resolving prefix at {}",
3175 self.module_to_str(containing_module));
3177 return Success(PrefixFound(containing_module, i));
3180 /// Attempts to resolve the supplied name in the given module for the
3181 /// given namespace. If successful, returns the target corresponding to
3184 /// The boolean returned on success is an indicator of whether this lookup
3185 /// passed through a public re-export proxy.
3186 fn resolve_name_in_module(&mut self,
3189 namespace: Namespace,
3190 name_search_type: NameSearchType)
3191 -> ResolveResult<(Target, bool)> {
3192 debug!("(resolving name in module) resolving `{}` in `{}`",
3193 token::get_ident(name),
3194 self.module_to_str(module_));
3196 // First, check the direct children of the module.
3197 self.populate_module_if_necessary(module_);
3200 let children = module_.children.borrow();
3201 match children.get().find(&name.name) {
3203 if name_bindings.defined_in_namespace(namespace) => {
3204 debug!("(resolving name in module) found node as child");
3205 return Success((Target::new(module_, *name_bindings),
3214 // Next, check the module's imports if necessary.
3216 // If this is a search of all imports, we should be done with glob
3217 // resolution at this point.
3218 if name_search_type == PathSearch {
3219 assert_eq!(module_.glob_count.get(), 0);
3222 // Check the list of resolved imports.
3223 let import_resolutions = module_.import_resolutions.borrow();
3224 match import_resolutions.get().find(&name.name) {
3225 Some(import_resolution) => {
3226 if import_resolution.is_public.get() &&
3227 import_resolution.outstanding_references.get() != 0 {
3228 debug!("(resolving name in module) import \
3229 unresolved; bailing out");
3230 return Indeterminate;
3232 match import_resolution.target_for_namespace(namespace) {
3234 debug!("(resolving name in module) name found, \
3235 but not in namespace {:?}",
3239 debug!("(resolving name in module) resolved to \
3241 self.used_imports.insert((import_resolution.id(namespace), namespace));
3242 return Success((target, true));
3246 None => {} // Continue.
3249 // Finally, search through external children.
3250 if namespace == TypeNS {
3252 let external_module_children =
3253 module_.external_module_children.borrow();
3254 external_module_children.get().find_copy(&name.name)
3260 @Resolver::create_name_bindings_from_module(module);
3261 return Success((Target::new(module_, name_bindings), false));
3266 // We're out of luck.
3267 debug!("(resolving name in module) failed to resolve `{}`",
3268 token::get_ident(name));
3272 fn report_unresolved_imports(&mut self, module_: @Module) {
3273 let index = module_.resolved_import_count.get();
3274 let mut imports = module_.imports.borrow_mut();
3275 let import_count = imports.get().len();
3276 if index != import_count {
3277 let sn = self.session
3279 .span_to_snippet(imports.get().get(index).span)
3281 if sn.contains("::") {
3282 self.resolve_error(imports.get().get(index).span,
3283 "unresolved import");
3285 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3286 sn.slice(0, sn.len()));
3287 self.resolve_error(imports.get().get(index).span, err);
3291 // Descend into children and anonymous children.
3292 self.populate_module_if_necessary(module_);
3295 let children = module_.children.borrow();
3296 for (_, &child_node) in children.get().iter() {
3297 match child_node.get_module_if_available() {
3301 Some(child_module) => {
3302 self.report_unresolved_imports(child_module);
3308 let anonymous_children = module_.anonymous_children.borrow();
3309 for (_, &module_) in anonymous_children.get().iter() {
3310 self.report_unresolved_imports(module_);
3316 // This pass simply determines what all "export" keywords refer to and
3317 // writes the results into the export map.
3319 // FIXME #4953 This pass will be removed once exports change to per-item.
3320 // Then this operation can simply be performed as part of item (or import)
3323 fn record_exports(&mut self) {
3324 let root_module = self.graph_root.get_module();
3325 self.record_exports_for_module_subtree(root_module);
3328 fn record_exports_for_module_subtree(&mut self,
3330 // If this isn't a local krate, then bail out. We don't need to record
3331 // exports for nonlocal crates.
3333 match module_.def_id.get() {
3334 Some(def_id) if def_id.krate == LOCAL_CRATE => {
3336 debug!("(recording exports for module subtree) recording \
3337 exports for local module `{}`",
3338 self.module_to_str(module_));
3341 // Record exports for the root module.
3342 debug!("(recording exports for module subtree) recording \
3343 exports for root module `{}`",
3344 self.module_to_str(module_));
3348 debug!("(recording exports for module subtree) not recording \
3350 self.module_to_str(module_));
3355 self.record_exports_for_module(module_);
3356 self.populate_module_if_necessary(module_);
3359 let children = module_.children.borrow();
3360 for (_, &child_name_bindings) in children.get().iter() {
3361 match child_name_bindings.get_module_if_available() {
3365 Some(child_module) => {
3366 self.record_exports_for_module_subtree(child_module);
3372 let anonymous_children = module_.anonymous_children.borrow();
3373 for (_, &child_module) in anonymous_children.get().iter() {
3374 self.record_exports_for_module_subtree(child_module);
3378 fn record_exports_for_module(&mut self, module_: @Module) {
3379 let mut exports2 = Vec::new();
3381 self.add_exports_for_module(&mut exports2, module_);
3382 match module_.def_id.get() {
3384 let mut export_map2 = self.export_map2.borrow_mut();
3385 export_map2.get().insert(def_id.node, exports2);
3386 debug!("(computing exports) writing exports for {} (some)",
3393 fn add_exports_of_namebindings(&mut self,
3394 exports2: &mut Vec<Export2> ,
3396 namebindings: @NameBindings,
3398 match namebindings.def_for_namespace(ns) {
3400 let name = token::get_name(name);
3401 debug!("(computing exports) YES: export '{}' => {:?}",
3402 name, def_id_of_def(d));
3403 exports2.push(Export2 {
3404 name: name.get().to_str(),
3405 def_id: def_id_of_def(d)
3409 debug!("(computing exports) NO: {:?}", d_opt);
3414 fn add_exports_for_module(&mut self,
3415 exports2: &mut Vec<Export2> ,
3417 let import_resolutions = module_.import_resolutions.borrow();
3418 for (name, importresolution) in import_resolutions.get().iter() {
3419 if !importresolution.is_public.get() {
3422 let xs = [TypeNS, ValueNS];
3423 for &ns in xs.iter() {
3424 match importresolution.target_for_namespace(ns) {
3426 debug!("(computing exports) maybe export '{}'",
3427 token::get_name(*name));
3428 self.add_exports_of_namebindings(exports2,
3441 // We maintain a list of value ribs and type ribs.
3443 // Simultaneously, we keep track of the current position in the module
3444 // graph in the `current_module` pointer. When we go to resolve a name in
3445 // the value or type namespaces, we first look through all the ribs and
3446 // then query the module graph. When we resolve a name in the module
3447 // namespace, we can skip all the ribs (since nested modules are not
3448 // allowed within blocks in Rust) and jump straight to the current module
3451 // Named implementations are handled separately. When we find a method
3452 // call, we consult the module node to find all of the implementations in
3453 // scope. This information is lazily cached in the module node. We then
3454 // generate a fake "implementation scope" containing all the
3455 // implementations thus found, for compatibility with old resolve pass.
3457 fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
3458 let orig_module = self.current_module;
3460 // Move down in the graph.
3466 self.populate_module_if_necessary(orig_module);
3468 let children = orig_module.children.borrow();
3469 match children.get().find(&name.name) {
3471 debug!("!!! (with scope) didn't find `{}` in `{}`",
3472 token::get_ident(name),
3473 self.module_to_str(orig_module));
3475 Some(name_bindings) => {
3476 match (*name_bindings).get_module_if_available() {
3478 debug!("!!! (with scope) didn't find module \
3480 token::get_ident(name),
3481 self.module_to_str(orig_module));
3484 self.current_module = module_;
3494 self.current_module = orig_module;
3497 /// Wraps the given definition in the appropriate number of `def_upvar`
3499 fn upvarify(&mut self,
3500 ribs: &mut Vec<@Rib> ,
3504 -> Option<DefLike> {
3509 DlDef(d @ DefLocal(..)) | DlDef(d @ DefUpvar(..)) |
3510 DlDef(d @ DefArg(..)) | DlDef(d @ DefBinding(..)) => {
3512 is_ty_param = false;
3514 DlDef(d @ DefTyParam(..)) => {
3519 return Some(def_like);
3523 let mut rib_index = rib_index + 1;
3524 while rib_index < ribs.len() {
3525 match ribs.get(rib_index).kind {
3527 // Nothing to do. Continue.
3529 FunctionRibKind(function_id, body_id) => {
3531 def = DefUpvar(def_id_of_def(def).node,
3537 MethodRibKind(item_id, _) => {
3538 // If the def is a ty param, and came from the parent
3541 DefTyParam(did, _) if {
3542 let def_map = self.def_map.borrow();
3543 def_map.get().find(&did.node).map(|x| *x)
3544 == Some(DefTyParamBinder(item_id))
3550 // This was an attempt to access an upvar inside a
3551 // named function item. This is not allowed, so we
3556 "can't capture dynamic environment in a fn item; \
3557 use the || { ... } closure form instead");
3559 // This was an attempt to use a type parameter outside
3562 self.resolve_error(span,
3563 "attempt to use a type \
3564 argument out of scope");
3571 OpaqueFunctionRibKind => {
3573 // This was an attempt to access an upvar inside a
3574 // named function item. This is not allowed, so we
3579 "can't capture dynamic environment in a fn item; \
3580 use the || { ... } closure form instead");
3582 // This was an attempt to use a type parameter outside
3585 self.resolve_error(span,
3586 "attempt to use a type \
3587 argument out of scope");
3592 ConstantItemRibKind => {
3595 self.resolve_error(span,
3596 "cannot use an outer type \
3597 parameter in this context");
3599 // Still doesn't deal with upvars
3600 self.resolve_error(span,
3601 "attempt to use a non-constant \
3602 value in a constant");
3611 return Some(DlDef(def));
3614 fn search_ribs(&mut self,
3615 ribs: &mut Vec<@Rib> ,
3618 -> Option<DefLike> {
3619 // FIXME #4950: This should not use a while loop.
3620 // FIXME #4950: Try caching?
3622 let mut i = ribs.len();
3626 let bindings = ribs.get(i).bindings.borrow();
3627 bindings.get().find_copy(&name)
3631 return self.upvarify(ribs, i, def_like, span);
3642 fn resolve_crate(&mut self, krate: &ast::Crate) {
3643 debug!("(resolving crate) starting");
3645 visit::walk_crate(self, krate, ());
3648 fn resolve_item(&mut self, item: &Item) {
3649 debug!("(resolving item) resolving {}",
3650 token::get_ident(item.ident));
3654 // enum item: resolve all the variants' discrs,
3655 // then resolve the ty params
3656 ItemEnum(ref enum_def, ref generics) => {
3657 for variant in (*enum_def).variants.iter() {
3658 for dis_expr in variant.node.disr_expr.iter() {
3659 // resolve the discriminator expr
3661 self.with_constant_rib(|this| {
3662 this.resolve_expr(*dis_expr);
3667 // n.b. the discr expr gets visted twice.
3668 // but maybe it's okay since the first time will signal an
3669 // error if there is one? -- tjc
3670 self.with_type_parameter_rib(HasTypeParameters(generics,
3675 visit::walk_item(this, item, ());
3679 ItemTy(_, ref generics) => {
3680 self.with_type_parameter_rib(HasTypeParameters(generics,
3685 visit::walk_item(this, item, ());
3689 ItemImpl(ref generics,
3690 ref implemented_traits,
3693 self.resolve_implementation(item.id,
3697 methods.as_slice());
3700 ItemTrait(ref generics, ref traits, ref methods) => {
3701 // Create a new rib for the self type.
3702 let self_type_rib = @Rib::new(NormalRibKind);
3704 let mut type_ribs = self.type_ribs.borrow_mut();
3705 type_ribs.get().push(self_type_rib);
3707 // plain insert (no renaming)
3708 let name = self.type_self_ident.name;
3710 let mut bindings = self_type_rib.bindings.borrow_mut();
3711 bindings.get().insert(name, DlDef(DefSelfTy(item.id)));
3714 // Create a new rib for the trait-wide type parameters.
3715 self.with_type_parameter_rib(HasTypeParameters(generics,
3720 this.resolve_type_parameters(&generics.ty_params);
3722 // Resolve derived traits.
3723 for trt in traits.iter() {
3724 this.resolve_trait_reference(item.id, trt, TraitDerivation);
3727 for method in (*methods).iter() {
3728 // Create a new rib for the method-specific type
3731 // FIXME #4951: Do we need a node ID here?
3734 ast::Required(ref ty_m) => {
3735 this.with_type_parameter_rib
3736 (HasTypeParameters(&ty_m.generics,
3738 generics.ty_params.len(),
3739 MethodRibKind(item.id, Required)),
3742 // Resolve the method-specific type
3744 this.resolve_type_parameters(
3745 &ty_m.generics.ty_params);
3747 for argument in ty_m.decl.inputs.iter() {
3748 this.resolve_type(argument.ty);
3751 this.resolve_type(ty_m.decl.output);
3754 ast::Provided(m) => {
3755 this.resolve_method(MethodRibKind(item.id,
3758 generics.ty_params.len())
3764 let mut type_ribs = self.type_ribs.borrow_mut();
3765 type_ribs.get().pop();
3768 ItemStruct(ref struct_def, ref generics) => {
3769 self.resolve_struct(item.id,
3771 struct_def.fields.as_slice());
3774 ItemMod(ref module_) => {
3775 self.with_scope(Some(item.ident), |this| {
3776 this.resolve_module(module_, item.span, item.ident,
3781 ItemForeignMod(ref foreign_module) => {
3782 self.with_scope(Some(item.ident), |this| {
3783 for foreign_item in foreign_module.items.iter() {
3784 match foreign_item.node {
3785 ForeignItemFn(_, ref generics) => {
3786 this.with_type_parameter_rib(
3788 generics, foreign_item.id, 0,
3790 |this| visit::walk_foreign_item(this,
3794 ForeignItemStatic(..) => {
3795 visit::walk_foreign_item(this,
3804 ItemFn(fn_decl, _, _, ref generics, block) => {
3805 self.resolve_function(OpaqueFunctionRibKind,
3811 OpaqueFunctionRibKind),
3816 self.with_constant_rib(|this| {
3817 visit::walk_item(this, item, ());
3822 // do nothing, these are just around to be encoded
3827 fn with_type_parameter_rib(&mut self,
3828 type_parameters: TypeParameters,
3829 f: |&mut Resolver|) {
3830 match type_parameters {
3831 HasTypeParameters(generics, node_id, initial_index,
3834 let function_type_rib = @Rib::new(rib_kind);
3836 let mut type_ribs = self.type_ribs.borrow_mut();
3837 type_ribs.get().push(function_type_rib);
3840 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
3841 let ident = type_parameter.ident;
3842 debug!("with_type_parameter_rib: {} {}", node_id,
3844 let def_like = DlDef(DefTyParam
3845 (local_def(type_parameter.id),
3846 index + initial_index));
3847 // Associate this type parameter with
3848 // the item that bound it
3849 self.record_def(type_parameter.id,
3850 (DefTyParamBinder(node_id), LastMod(AllPublic)));
3851 // plain insert (no renaming)
3852 let mut bindings = function_type_rib.bindings
3854 bindings.get().insert(ident.name, def_like);
3858 NoTypeParameters => {
3865 match type_parameters {
3866 HasTypeParameters(..) => {
3867 let mut type_ribs = self.type_ribs.borrow_mut();
3868 type_ribs.get().pop();
3871 NoTypeParameters => {
3877 fn with_label_rib(&mut self, f: |&mut Resolver|) {
3879 let mut label_ribs = self.label_ribs.borrow_mut();
3880 label_ribs.get().push(@Rib::new(NormalRibKind));
3886 let mut label_ribs = self.label_ribs.borrow_mut();
3887 label_ribs.get().pop();
3891 fn with_constant_rib(&mut self, f: |&mut Resolver|) {
3893 let mut value_ribs = self.value_ribs.borrow_mut();
3894 let mut type_ribs = self.type_ribs.borrow_mut();
3895 value_ribs.get().push(@Rib::new(ConstantItemRibKind));
3896 type_ribs.get().push(@Rib::new(ConstantItemRibKind));
3900 let mut value_ribs = self.value_ribs.borrow_mut();
3901 let mut type_ribs = self.type_ribs.borrow_mut();
3902 type_ribs.get().pop();
3903 value_ribs.get().pop();
3907 fn resolve_function(&mut self,
3909 optional_declaration: Option<P<FnDecl>>,
3910 type_parameters: TypeParameters,
3912 // Create a value rib for the function.
3913 let function_value_rib = @Rib::new(rib_kind);
3915 let mut value_ribs = self.value_ribs.borrow_mut();
3916 value_ribs.get().push(function_value_rib);
3919 // Create a label rib for the function.
3921 let mut label_ribs = self.label_ribs.borrow_mut();
3922 let function_label_rib = @Rib::new(rib_kind);
3923 label_ribs.get().push(function_label_rib);
3926 // If this function has type parameters, add them now.
3927 self.with_type_parameter_rib(type_parameters, |this| {
3928 // Resolve the type parameters.
3929 match type_parameters {
3930 NoTypeParameters => {
3933 HasTypeParameters(ref generics, _, _, _) => {
3934 this.resolve_type_parameters(&generics.ty_params);
3938 // Add each argument to the rib.
3939 match optional_declaration {
3943 Some(declaration) => {
3944 for argument in declaration.inputs.iter() {
3945 let binding_mode = ArgumentIrrefutableMode;
3946 this.resolve_pattern(argument.pat,
3950 this.resolve_type(argument.ty);
3952 debug!("(resolving function) recorded argument");
3955 this.resolve_type(declaration.output);
3959 // Resolve the function body.
3960 this.resolve_block(block);
3962 debug!("(resolving function) leaving function");
3965 let mut label_ribs = self.label_ribs.borrow_mut();
3966 label_ribs.get().pop();
3968 let mut value_ribs = self.value_ribs.borrow_mut();
3969 value_ribs.get().pop();
3972 fn resolve_type_parameters(&mut self,
3973 type_parameters: &OptVec<TyParam>) {
3974 for type_parameter in type_parameters.iter() {
3975 for bound in type_parameter.bounds.iter() {
3976 self.resolve_type_parameter_bound(type_parameter.id, bound);
3978 match type_parameter.default {
3979 Some(ty) => self.resolve_type(ty),
3985 fn resolve_type_parameter_bound(&mut self,
3987 type_parameter_bound: &TyParamBound) {
3988 match *type_parameter_bound {
3989 TraitTyParamBound(ref tref) => {
3990 self.resolve_trait_reference(id, tref, TraitBoundingTypeParameter)
3992 RegionTyParamBound => {}
3996 fn resolve_trait_reference(&mut self,
3998 trait_reference: &TraitRef,
3999 reference_type: TraitReferenceType) {
4000 match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
4002 let path_str = self.path_idents_to_str(&trait_reference.path);
4003 let usage_str = match reference_type {
4004 TraitBoundingTypeParameter => "bound type parameter with",
4005 TraitImplementation => "implement",
4006 TraitDerivation => "derive"
4009 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
4010 self.resolve_error(trait_reference.path.span, msg);
4013 debug!("(resolving trait) found trait def: {:?}", def);
4014 self.record_def(trait_reference.ref_id, def);
4019 fn resolve_struct(&mut self,
4021 generics: &Generics,
4022 fields: &[StructField]) {
4023 let mut ident_map: HashMap<ast::Ident, &StructField> = HashMap::new();
4024 for field in fields.iter() {
4025 match field.node.kind {
4026 NamedField(ident, _) => {
4027 match ident_map.find(&ident) {
4028 Some(&prev_field) => {
4029 let ident_str = token::get_ident(ident);
4030 self.resolve_error(field.span,
4031 format!("field `{}` is already declared", ident_str));
4032 self.session.span_note(prev_field.span,
4033 "previously declared here");
4036 ident_map.insert(ident, field);
4044 // If applicable, create a rib for the type parameters.
4045 self.with_type_parameter_rib(HasTypeParameters(generics,
4048 OpaqueFunctionRibKind),
4050 // Resolve the type parameters.
4051 this.resolve_type_parameters(&generics.ty_params);
4054 for field in fields.iter() {
4055 this.resolve_type(field.node.ty);
4060 // Does this really need to take a RibKind or is it always going
4061 // to be NormalRibKind?
4062 fn resolve_method(&mut self,
4065 outer_type_parameter_count: uint) {
4066 let method_generics = &method.generics;
4067 let type_parameters =
4068 HasTypeParameters(method_generics,
4070 outer_type_parameter_count,
4073 self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
4076 fn resolve_implementation(&mut self,
4078 generics: &Generics,
4079 opt_trait_reference: &Option<TraitRef>,
4081 methods: &[@Method]) {
4082 // If applicable, create a rib for the type parameters.
4083 let outer_type_parameter_count = generics.ty_params.len();
4084 self.with_type_parameter_rib(HasTypeParameters(generics,
4089 // Resolve the type parameters.
4090 this.resolve_type_parameters(&generics.ty_params);
4092 // Resolve the trait reference, if necessary.
4093 let original_trait_refs;
4094 match opt_trait_reference {
4095 &Some(ref trait_reference) => {
4096 this.resolve_trait_reference(id, trait_reference,
4097 TraitImplementation);
4099 // Record the current set of trait references.
4100 let mut new_trait_refs = Vec::new();
4102 let def_map = this.def_map.borrow();
4103 let r = def_map.get().find(&trait_reference.ref_id);
4104 for &def in r.iter() {
4105 new_trait_refs.push(def_id_of_def(*def));
4108 original_trait_refs = Some(replace(
4109 &mut this.current_trait_refs,
4110 Some(new_trait_refs)));
4113 original_trait_refs = None;
4117 // Resolve the self type.
4118 this.resolve_type(self_type);
4120 for method in methods.iter() {
4121 // We also need a new scope for the method-specific
4123 this.resolve_method(MethodRibKind(
4125 Provided(method.id)),
4127 outer_type_parameter_count);
4129 let borrowed_type_parameters = &method.tps;
4130 self.resolve_function(MethodRibKind(
4132 Provided(method.id)),
4135 (borrowed_type_parameters,
4137 outer_type_parameter_count,
4143 // Restore the original trait references.
4144 match original_trait_refs {
4145 Some(r) => { this.current_trait_refs = r; }
4151 fn resolve_module(&mut self, module: &Mod, _span: Span,
4152 _name: Ident, id: NodeId) {
4153 // Write the implementations in scope into the module metadata.
4154 debug!("(resolving module) resolving module ID {}", id);
4155 visit::walk_mod(self, module, ());
4158 fn resolve_local(&mut self, local: &Local) {
4159 // Resolve the type.
4160 self.resolve_type(local.ty);
4162 // Resolve the initializer, if necessary.
4167 Some(initializer) => {
4168 self.resolve_expr(initializer);
4172 // Resolve the pattern.
4173 self.resolve_pattern(local.pat, LocalIrrefutableMode, None);
4176 // build a map from pattern identifiers to binding-info's.
4177 // this is done hygienically. This could arise for a macro
4178 // that expands into an or-pattern where one 'x' was from the
4179 // user and one 'x' came from the macro.
4180 fn binding_mode_map(&mut self, pat: @Pat) -> BindingMap {
4181 let mut result = HashMap::new();
4182 pat_bindings(self.def_map, pat, |binding_mode, _id, sp, path| {
4183 let name = mtwt::resolve(path_to_ident(path));
4185 binding_info {span: sp,
4186 binding_mode: binding_mode});
4191 // check that all of the arms in an or-pattern have exactly the
4192 // same set of bindings, with the same binding modes for each.
4193 fn check_consistent_bindings(&mut self, arm: &Arm) {
4194 if arm.pats.len() == 0 {
4197 let map_0 = self.binding_mode_map(*arm.pats.get(0));
4198 for (i, p) in arm.pats.iter().enumerate() {
4199 let map_i = self.binding_mode_map(*p);
4201 for (&key, &binding_0) in map_0.iter() {
4202 match map_i.find(&key) {
4206 format!("variable `{}` from pattern \\#1 is \
4207 not bound in pattern \\#{}",
4208 token::get_name(key),
4211 Some(binding_i) => {
4212 if binding_0.binding_mode != binding_i.binding_mode {
4215 format!("variable `{}` is bound with different \
4216 mode in pattern \\#{} than in pattern \\#1",
4217 token::get_name(key),
4224 for (&key, &binding) in map_i.iter() {
4225 if !map_0.contains_key(&key) {
4228 format!("variable `{}` from pattern \\#{} is \
4229 not bound in pattern \\#1",
4230 token::get_name(key),
4237 fn resolve_arm(&mut self, arm: &Arm) {
4239 let mut value_ribs = self.value_ribs.borrow_mut();
4240 value_ribs.get().push(@Rib::new(NormalRibKind));
4243 let mut bindings_list = HashMap::new();
4244 for pattern in arm.pats.iter() {
4245 self.resolve_pattern(*pattern,
4247 Some(&mut bindings_list));
4250 // This has to happen *after* we determine which
4251 // pat_idents are variants
4252 self.check_consistent_bindings(arm);
4254 visit::walk_expr_opt(self, arm.guard, ());
4255 self.resolve_expr(arm.body);
4257 let mut value_ribs = self.value_ribs.borrow_mut();
4258 value_ribs.get().pop();
4261 fn resolve_block(&mut self, block: &Block) {
4262 debug!("(resolving block) entering block");
4264 let mut value_ribs = self.value_ribs.borrow_mut();
4265 value_ribs.get().push(@Rib::new(NormalRibKind));
4268 // Move down in the graph, if there's an anonymous module rooted here.
4269 let orig_module = self.current_module;
4270 let anonymous_children = self.current_module
4273 match anonymous_children.get().find(&block.id) {
4274 None => { /* Nothing to do. */ }
4275 Some(&anonymous_module) => {
4276 debug!("(resolving block) found anonymous module, moving \
4278 self.current_module = anonymous_module;
4282 // Descend into the block.
4283 visit::walk_block(self, block, ());
4286 self.current_module = orig_module;
4288 let mut value_ribs = self.value_ribs.borrow_mut();
4289 value_ribs.get().pop();
4290 debug!("(resolving block) leaving block");
4293 fn resolve_type(&mut self, ty: &Ty) {
4295 // Like path expressions, the interpretation of path types depends
4296 // on whether the path has multiple elements in it or not.
4298 TyPath(ref path, ref bounds, path_id) => {
4299 // This is a path in the type namespace. Walk through scopes
4301 let mut result_def = None;
4303 // First, check to see whether the name is a primitive type.
4304 if path.segments.len() == 1 {
4305 let id = path.segments.last().unwrap().identifier;
4307 match self.primitive_type_table
4311 Some(&primitive_type) => {
4313 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4317 .any(|s| !s.lifetimes.is_empty()) {
4318 self.session.span_err(path.span,
4319 "lifetime parameters \
4320 are not allowed on \
4322 } else if path.segments
4324 .any(|s| s.types.len() > 0) {
4325 self.session.span_err(path.span,
4326 "type parameters are \
4327 not allowed on this \
4339 match self.resolve_path(ty.id, path, TypeNS, true) {
4341 debug!("(resolving type) resolved `{}` to \
4343 token::get_ident(path.segments
4347 result_def = Some(def);
4354 Some(_) => {} // Continue.
4359 // Write the result into the def map.
4360 debug!("(resolving type) writing resolution for `{}` \
4362 self.path_idents_to_str(path),
4364 self.record_def(path_id, def);
4367 let msg = format!("use of undeclared type name `{}`",
4368 self.path_idents_to_str(path));
4369 self.resolve_error(ty.span, msg);
4373 bounds.as_ref().map(|bound_vec| {
4374 for bound in bound_vec.iter() {
4375 self.resolve_type_parameter_bound(ty.id, bound);
4381 c.bounds.as_ref().map(|bounds| {
4382 for bound in bounds.iter() {
4383 self.resolve_type_parameter_bound(ty.id, bound);
4386 visit::walk_ty(self, ty, ());
4390 // Just resolve embedded types.
4391 visit::walk_ty(self, ty, ());
4396 fn resolve_pattern(&mut self,
4398 mode: PatternBindingMode,
4399 // Maps idents to the node ID for the (outermost)
4400 // pattern that binds them
4401 mut bindings_list: Option<&mut HashMap<Name,NodeId>>) {
4402 let pat_id = pattern.id;
4403 walk_pat(pattern, |pattern| {
4404 match pattern.node {
4405 PatIdent(binding_mode, ref path, _)
4406 if !path.global && path.segments.len() == 1 => {
4408 // The meaning of pat_ident with no type parameters
4409 // depends on whether an enum variant or unit-like struct
4410 // with that name is in scope. The probing lookup has to
4411 // be careful not to emit spurious errors. Only matching
4412 // patterns (match) can match nullary variants or
4413 // unit-like structs. For binding patterns (let), matching
4414 // such a value is simply disallowed (since it's rarely
4417 let ident = path.segments.get(0).identifier;
4418 let renamed = mtwt::resolve(ident);
4420 match self.resolve_bare_identifier_pattern(ident) {
4421 FoundStructOrEnumVariant(def, lp)
4422 if mode == RefutableMode => {
4423 debug!("(resolving pattern) resolving `{}` to \
4424 struct or enum variant",
4425 token::get_name(renamed));
4427 self.enforce_default_binding_mode(
4431 self.record_def(pattern.id, (def, lp));
4433 FoundStructOrEnumVariant(..) => {
4434 self.resolve_error(pattern.span,
4435 format!("declaration of `{}` \
4437 variant or unit-like \
4439 token::get_name(renamed)));
4441 FoundConst(def, lp) if mode == RefutableMode => {
4442 debug!("(resolving pattern) resolving `{}` to \
4444 token::get_name(renamed));
4446 self.enforce_default_binding_mode(
4450 self.record_def(pattern.id, (def, lp));
4453 self.resolve_error(pattern.span,
4454 "only irrefutable patterns \
4457 BareIdentifierPatternUnresolved => {
4458 debug!("(resolving pattern) binding `{}`",
4459 token::get_name(renamed));
4461 let def = match mode {
4463 // For pattern arms, we must use
4464 // `def_binding` definitions.
4466 DefBinding(pattern.id, binding_mode)
4468 LocalIrrefutableMode => {
4469 // But for locals, we use `def_local`.
4470 DefLocal(pattern.id, binding_mode)
4472 ArgumentIrrefutableMode => {
4473 // And for function arguments, `def_arg`.
4474 DefArg(pattern.id, binding_mode)
4478 // Record the definition so that later passes
4479 // will be able to distinguish variants from
4480 // locals in patterns.
4482 self.record_def(pattern.id, (def, LastMod(AllPublic)));
4484 // Add the binding to the local ribs, if it
4485 // doesn't already exist in the bindings list. (We
4486 // must not add it if it's in the bindings list
4487 // because that breaks the assumptions later
4488 // passes make about or-patterns.)
4490 match bindings_list {
4491 Some(ref mut bindings_list)
4492 if !bindings_list.contains_key(&renamed) => {
4493 let this = &mut *self;
4495 let mut value_ribs =
4496 this.value_ribs.borrow_mut();
4497 let length = value_ribs.get().len();
4498 let last_rib = value_ribs.get().get(
4501 last_rib.bindings.borrow_mut();
4502 bindings.get().insert(renamed,
4505 bindings_list.insert(renamed, pat_id);
4507 Some(ref mut b) => {
4508 if b.find(&renamed) == Some(&pat_id) {
4509 // Then this is a duplicate variable
4510 // in the same disjunct, which is an
4512 self.resolve_error(pattern.span,
4513 format!("identifier `{}` is bound more \
4514 than once in the same pattern",
4515 path_to_str(path)));
4517 // Not bound in the same pattern: do nothing
4520 let this = &mut *self;
4522 let mut value_ribs =
4523 this.value_ribs.borrow_mut();
4524 let length = value_ribs.get().len();
4525 let last_rib = value_ribs.get().get(
4528 last_rib.bindings.borrow_mut();
4529 bindings.get().insert(renamed,
4537 // Check the types in the path pattern.
4538 for &ty in path.segments
4540 .flat_map(|seg| seg.types.iter()) {
4541 self.resolve_type(ty);
4545 PatIdent(binding_mode, ref path, _) => {
4546 // This must be an enum variant, struct, or constant.
4547 match self.resolve_path(pat_id, path, ValueNS, false) {
4548 Some(def @ (DefVariant(..), _)) |
4549 Some(def @ (DefStruct(..), _)) => {
4550 self.record_def(pattern.id, def);
4552 Some(def @ (DefStatic(..), _)) => {
4553 self.enforce_default_binding_mode(
4557 self.record_def(pattern.id, def);
4562 format!("`{}` is not an enum variant or constant",
4564 path.segments.last().unwrap().identifier)))
4567 self.resolve_error(path.span,
4568 "unresolved enum variant");
4572 // Check the types in the path pattern.
4573 for &ty in path.segments
4575 .flat_map(|s| s.types.iter()) {
4576 self.resolve_type(ty);
4580 PatEnum(ref path, _) => {
4581 // This must be an enum variant, struct or const.
4582 match self.resolve_path(pat_id, path, ValueNS, false) {
4583 Some(def @ (DefFn(..), _)) |
4584 Some(def @ (DefVariant(..), _)) |
4585 Some(def @ (DefStruct(..), _)) |
4586 Some(def @ (DefStatic(..), _)) => {
4587 self.record_def(pattern.id, def);
4590 self.resolve_error(path.span,
4591 format!("`{}` is not an enum variant, struct or const",
4592 token::get_ident(path.segments
4597 self.resolve_error(path.span,
4598 format!("unresolved enum variant, struct or const `{}`",
4599 token::get_ident(path.segments
4605 // Check the types in the path pattern.
4606 for &ty in path.segments
4608 .flat_map(|s| s.types.iter()) {
4609 self.resolve_type(ty);
4614 self.resolve_expr(expr);
4617 PatRange(first_expr, last_expr) => {
4618 self.resolve_expr(first_expr);
4619 self.resolve_expr(last_expr);
4622 PatStruct(ref path, _, _) => {
4623 match self.resolve_path(pat_id, path, TypeNS, false) {
4624 Some((DefTy(class_id), lp))
4625 if self.structs.contains(&class_id) => {
4626 let class_def = DefStruct(class_id);
4627 self.record_def(pattern.id, (class_def, lp));
4629 Some(definition @ (DefStruct(class_id), _)) => {
4630 assert!(self.structs.contains(&class_id));
4631 self.record_def(pattern.id, definition);
4633 Some(definition @ (DefVariant(_, variant_id, _), _))
4634 if self.structs.contains(&variant_id) => {
4635 self.record_def(pattern.id, definition);
4638 debug!("(resolving pattern) didn't find struct \
4639 def: {:?}", result);
4640 let msg = format!("`{}` does not name a structure",
4641 self.path_idents_to_str(path));
4642 self.resolve_error(path.span, msg);
4655 fn resolve_bare_identifier_pattern(&mut self, name: Ident)
4657 BareIdentifierPatternResolution {
4658 match self.resolve_item_in_lexical_scope(self.current_module,
4661 SearchThroughModules) {
4662 Success((target, _)) => {
4663 debug!("(resolve bare identifier pattern) succeeded in \
4664 finding {} at {:?}",
4665 token::get_ident(name),
4666 target.bindings.value_def.get());
4667 match target.bindings.value_def.get() {
4669 fail!("resolved name in the value namespace to a \
4670 set of name bindings with no def?!");
4673 // For the two success cases, this lookup can be
4674 // considered as not having a private component because
4675 // the lookup happened only within the current module.
4677 def @ DefVariant(..) | def @ DefStruct(..) => {
4678 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
4680 def @ DefStatic(_, false) => {
4681 return FoundConst(def, LastMod(AllPublic));
4684 return BareIdentifierPatternUnresolved;
4692 fail!("unexpected indeterminate result");
4696 debug!("(resolve bare identifier pattern) failed to find {}",
4697 token::get_ident(name));
4698 return BareIdentifierPatternUnresolved;
4703 /// If `check_ribs` is true, checks the local definitions first; i.e.
4704 /// doesn't skip straight to the containing module.
4705 fn resolve_path(&mut self,
4708 namespace: Namespace,
4709 check_ribs: bool) -> Option<(Def, LastPrivate)> {
4710 // First, resolve the types.
4711 for &ty in path.segments.iter().flat_map(|s| s.types.iter()) {
4712 self.resolve_type(ty);
4716 return self.resolve_crate_relative_path(path, namespace);
4719 let unqualified_def =
4720 self.resolve_identifier(path.segments
4727 if path.segments.len() > 1 {
4728 let def = self.resolve_module_relative_path(path, namespace);
4729 match (def, unqualified_def) {
4730 (Some((d, _)), Some((ud, _))) if d == ud => {
4731 self.session.add_lint(UnnecessaryQualification,
4734 ~"unnecessary qualification");
4742 return unqualified_def;
4745 // resolve a single identifier (used as a varref)
4746 fn resolve_identifier(&mut self,
4748 namespace: Namespace,
4751 -> Option<(Def, LastPrivate)> {
4753 match self.resolve_identifier_in_local_ribs(identifier,
4757 return Some((def, LastMod(AllPublic)));
4765 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
4769 // FIXME #4952: Merge me with resolve_name_in_module?
4770 fn resolve_definition_of_name_in_module(&mut self,
4771 containing_module: @Module,
4773 namespace: Namespace)
4775 // First, search children.
4776 self.populate_module_if_necessary(containing_module);
4779 let children = containing_module.children.borrow();
4780 match children.get().find(&name.name) {
4781 Some(child_name_bindings) => {
4782 match child_name_bindings.def_for_namespace(namespace) {
4784 // Found it. Stop the search here.
4785 let p = child_name_bindings.defined_in_public_namespace(
4787 let lp = if p {LastMod(AllPublic)} else {
4788 LastMod(DependsOn(def_id_of_def(def)))
4790 return ChildNameDefinition(def, lp);
4799 // Next, search import resolutions.
4800 let import_resolutions = containing_module.import_resolutions
4802 match import_resolutions.get().find(&name.name) {
4803 Some(import_resolution) if import_resolution.is_public.get() => {
4804 match (*import_resolution).target_for_namespace(namespace) {
4806 match target.bindings.def_for_namespace(namespace) {
4809 let id = import_resolution.id(namespace);
4810 self.used_imports.insert((id, namespace));
4811 return ImportNameDefinition(def, LastMod(AllPublic));
4814 // This can happen with external impls, due to
4815 // the imperfect way we read the metadata.
4822 Some(..) | None => {} // Continue.
4825 // Finally, search through external children.
4826 if namespace == TypeNS {
4828 let external_module_children =
4829 containing_module.external_module_children.borrow();
4830 external_module_children.get().find_copy(&name.name)
4835 match module.def_id.get() {
4836 None => {} // Continue.
4838 let lp = if module.is_public {LastMod(AllPublic)} else {
4839 LastMod(DependsOn(def_id))
4841 return ChildNameDefinition(DefMod(def_id), lp);
4848 return NoNameDefinition;
4851 // resolve a "module-relative" path, e.g. a::b::c
4852 fn resolve_module_relative_path(&mut self,
4854 namespace: Namespace)
4855 -> Option<(Def, LastPrivate)> {
4856 let module_path_idents = path.segments.init().map(|ps| ps.identifier);
4858 let containing_module;
4860 match self.resolve_module_path(self.current_module,
4866 let msg = format!("use of undeclared module `{}`",
4867 self.idents_to_str(module_path_idents));
4868 self.resolve_error(path.span, msg);
4873 fail!("indeterminate unexpected");
4876 Success((resulting_module, resulting_last_private)) => {
4877 containing_module = resulting_module;
4878 last_private = resulting_last_private;
4882 let ident = path.segments.last().unwrap().identifier;
4883 let def = match self.resolve_definition_of_name_in_module(containing_module,
4886 NoNameDefinition => {
4887 // We failed to resolve the name. Report an error.
4890 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4891 (def, last_private.or(lp))
4894 match containing_module.kind.get() {
4895 TraitModuleKind | ImplModuleKind => {
4896 let method_map = self.method_map.borrow();
4897 match method_map.get().find(&ident.name) {
4899 match containing_module.def_id.get() {
4900 Some(def_id) if s.contains(&def_id) => {
4901 debug!("containing module was a trait or impl \
4902 and name was a method -> not resolved");
4916 /// Invariant: This must be called only during main resolution, not during
4917 /// import resolution.
4918 fn resolve_crate_relative_path(&mut self,
4920 namespace: Namespace)
4921 -> Option<(Def, LastPrivate)> {
4922 let module_path_idents = path.segments.init().map(|ps| ps.identifier);
4924 let root_module = self.graph_root.get_module();
4926 let containing_module;
4928 match self.resolve_module_path_from_root(root_module,
4933 LastMod(AllPublic)) {
4935 let msg = format!("use of undeclared module `::{}`",
4936 self.idents_to_str(module_path_idents));
4937 self.resolve_error(path.span, msg);
4942 fail!("indeterminate unexpected");
4945 Success((resulting_module, resulting_last_private)) => {
4946 containing_module = resulting_module;
4947 last_private = resulting_last_private;
4951 let name = path.segments.last().unwrap().identifier;
4952 match self.resolve_definition_of_name_in_module(containing_module,
4955 NoNameDefinition => {
4956 // We failed to resolve the name. Report an error.
4959 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4960 return Some((def, last_private.or(lp)));
4965 fn resolve_identifier_in_local_ribs(&mut self,
4967 namespace: Namespace,
4970 // Check the local set of ribs.
4974 let renamed = mtwt::resolve(ident);
4975 let mut value_ribs = self.value_ribs.borrow_mut();
4976 search_result = self.search_ribs(value_ribs.get(),
4981 let name = ident.name;
4982 let mut type_ribs = self.type_ribs.borrow_mut();
4983 search_result = self.search_ribs(type_ribs.get(),
4989 match search_result {
4990 Some(DlDef(def)) => {
4991 debug!("(resolving path in local ribs) resolved `{}` to \
4993 token::get_ident(ident),
4997 Some(DlField) | Some(DlImpl(_)) | None => {
5003 fn resolve_item_by_identifier_in_lexical_scope(&mut self,
5005 namespace: Namespace)
5006 -> Option<(Def, LastPrivate)> {
5008 match self.resolve_item_in_lexical_scope(self.current_module,
5011 DontSearchThroughModules) {
5012 Success((target, _)) => {
5013 match (*target.bindings).def_for_namespace(namespace) {
5015 // This can happen if we were looking for a type and
5016 // found a module instead. Modules don't have defs.
5017 debug!("(resolving item path by identifier in lexical \
5018 scope) failed to resolve {} after success...",
5019 token::get_ident(ident));
5023 debug!("(resolving item path in lexical scope) \
5024 resolved `{}` to item",
5025 token::get_ident(ident));
5026 // This lookup is "all public" because it only searched
5027 // for one identifier in the current module (couldn't
5028 // have passed through reexports or anything like that.
5029 return Some((def, LastMod(AllPublic)));
5034 fail!("unexpected indeterminate result");
5037 debug!("(resolving item path by identifier in lexical scope) \
5038 failed to resolve {}", token::get_ident(ident));
5044 fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
5045 self.emit_errors = false;
5047 self.emit_errors = true;
5051 fn resolve_error(&mut self, span: Span, s: &str) {
5052 if self.emit_errors {
5053 self.session.span_err(span, s);
5057 fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5059 let this = &mut *self;
5061 let mut maybes: Vec<token::InternedString> = Vec::new();
5062 let mut values: Vec<uint> = Vec::new();
5065 let value_ribs = this.value_ribs.borrow();
5066 value_ribs.get().len()
5070 let value_ribs = this.value_ribs.borrow();
5071 let bindings = value_ribs.get().get(j).bindings.borrow();
5072 for (&k, _) in bindings.get().iter() {
5073 maybes.push(token::get_name(k));
5074 values.push(uint::MAX);
5078 let mut smallest = 0;
5079 for (i, other) in maybes.iter().enumerate() {
5080 *values.get_mut(i) = name.lev_distance(other.get());
5082 if *values.get(i) <= *values.get(smallest) {
5087 if values.len() > 0 &&
5088 *values.get(smallest) != uint::MAX &&
5089 *values.get(smallest) < name.len() + 2 &&
5090 *values.get(smallest) <= max_distance &&
5091 name != maybes.get(smallest).get() {
5093 Some(maybes.get(smallest).get().to_str())
5100 fn resolve_expr(&mut self, expr: &Expr) {
5101 // First, record candidate traits for this expression if it could
5102 // result in the invocation of a method call.
5104 self.record_candidate_traits_for_expr_if_necessary(expr);
5106 // Next, resolve the node.
5108 // The interpretation of paths depends on whether the path has
5109 // multiple elements in it or not.
5111 ExprPath(ref path) => {
5112 // This is a local path in the value namespace. Walk through
5113 // scopes looking for it.
5115 match self.resolve_path(expr.id, path, ValueNS, true) {
5117 // Write the result into the def map.
5118 debug!("(resolving expr) resolved `{}`",
5119 self.path_idents_to_str(path));
5121 // First-class methods are not supported yet; error
5124 (DefMethod(..), _) => {
5125 self.resolve_error(expr.span,
5126 "first-class methods \
5127 are not supported");
5128 self.session.span_note(expr.span,
5136 self.record_def(expr.id, def);
5139 let wrong_name = self.path_idents_to_str(path);
5140 // Be helpful if the name refers to a struct
5141 // (The pattern matching def_tys where the id is in self.structs
5142 // matches on regular structs while excluding tuple- and enum-like
5143 // structs, which wouldn't result in this error.)
5144 match self.with_no_errors(|this|
5145 this.resolve_path(expr.id, path, TypeNS, false)) {
5146 Some((DefTy(struct_id), _))
5147 if self.structs.contains(&struct_id) => {
5148 self.resolve_error(expr.span,
5149 format!("`{}` is a structure name, but \
5151 uses it like a function name",
5154 self.session.span_note(expr.span,
5155 format!("Did you mean to write: \
5156 `{} \\{ /* fields */ \\}`?",
5161 // limit search to 5 to reduce the number
5162 // of stupid suggestions
5163 match self.find_best_match_for_name(wrong_name, 5) {
5165 self.resolve_error(expr.span,
5166 format!("unresolved name `{}`. \
5167 Did you mean `{}`?",
5171 self.resolve_error(expr.span,
5172 format!("unresolved name `{}`.",
5180 visit::walk_expr(self, expr, ());
5183 ExprFnBlock(fn_decl, block) |
5184 ExprProc(fn_decl, block) => {
5185 self.resolve_function(FunctionRibKind(expr.id, block.id),
5186 Some(fn_decl), NoTypeParameters,
5190 ExprStruct(ref path, _, _) => {
5191 // Resolve the path to the structure it goes to.
5192 match self.resolve_path(expr.id, path, TypeNS, false) {
5193 Some((DefTy(class_id), lp)) | Some((DefStruct(class_id), lp))
5194 if self.structs.contains(&class_id) => {
5195 let class_def = DefStruct(class_id);
5196 self.record_def(expr.id, (class_def, lp));
5198 Some(definition @ (DefVariant(_, class_id, _), _))
5199 if self.structs.contains(&class_id) => {
5200 self.record_def(expr.id, definition);
5203 debug!("(resolving expression) didn't find struct \
5204 def: {:?}", result);
5205 let msg = format!("`{}` does not name a structure",
5206 self.path_idents_to_str(path));
5207 self.resolve_error(path.span, msg);
5211 visit::walk_expr(self, expr, ());
5214 ExprLoop(_, Some(label)) => {
5215 self.with_label_rib(|this| {
5216 let def_like = DlDef(DefLabel(expr.id));
5218 let mut label_ribs = this.label_ribs.borrow_mut();
5219 let length = label_ribs.get().len();
5220 let rib = label_ribs.get().get(length - 1);
5221 let mut bindings = rib.bindings.borrow_mut();
5222 let renamed = mtwt::resolve(label);
5223 bindings.get().insert(renamed, def_like);
5226 visit::walk_expr(this, expr, ());
5230 ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
5232 ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5233 let mut label_ribs = self.label_ribs.borrow_mut();
5234 let renamed = mtwt::resolve(label);
5235 match self.search_ribs(label_ribs.get(), renamed, expr.span) {
5237 self.resolve_error(expr.span,
5238 format!("use of undeclared label `{}`",
5239 token::get_ident(label))),
5240 Some(DlDef(def @ DefLabel(_))) => {
5241 // Since this def is a label, it is never read.
5242 self.record_def(expr.id, (def, LastMod(AllPublic)))
5245 self.session.span_bug(expr.span,
5246 "label wasn't mapped to a \
5253 visit::walk_expr(self, expr, ());
5258 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5260 ExprField(_, ident, _) => {
5261 // FIXME(#6890): Even though you can't treat a method like a
5262 // field, we need to add any trait methods we find that match
5263 // the field name so that we can do some nice error reporting
5264 // later on in typeck.
5265 let traits = self.search_for_traits_containing_method(ident);
5266 self.trait_map.insert(expr.id, traits);
5268 ExprMethodCall(ident, _, _) => {
5269 debug!("(recording candidate traits for expr) recording \
5272 let traits = self.search_for_traits_containing_method(ident);
5273 self.trait_map.insert(expr.id, traits);
5281 fn search_for_traits_containing_method(&mut self, name: Ident) -> Vec<DefId> {
5282 debug!("(searching for traits containing method) looking for '{}'",
5283 token::get_ident(name));
5285 let mut found_traits = Vec::new();
5286 let mut search_module = self.current_module;
5287 let method_map = self.method_map.borrow();
5288 match method_map.get().find(&name.name) {
5289 Some(candidate_traits) => loop {
5290 // Look for the current trait.
5291 match self.current_trait_refs {
5292 Some(ref trait_def_ids) => {
5293 for trait_def_id in trait_def_ids.iter() {
5294 if candidate_traits.contains(trait_def_id) {
5295 self.add_trait_info(&mut found_traits,
5306 // Look for trait children.
5307 self.populate_module_if_necessary(search_module);
5309 let children = search_module.children.borrow();
5310 for (_, &child_names) in children.get().iter() {
5311 let def = match child_names.def_for_namespace(TypeNS) {
5315 let trait_def_id = match def {
5316 DefTrait(trait_def_id) => trait_def_id,
5319 if candidate_traits.contains(&trait_def_id) {
5320 self.add_trait_info(&mut found_traits, trait_def_id,
5325 // Look for imports.
5326 let import_resolutions = search_module.import_resolutions
5328 for (_, &import) in import_resolutions.get().iter() {
5329 let target = match import.target_for_namespace(TypeNS) {
5331 Some(target) => target,
5333 let did = match target.bindings.def_for_namespace(TypeNS) {
5334 Some(DefTrait(trait_def_id)) => trait_def_id,
5335 Some(..) | None => continue,
5337 if candidate_traits.contains(&did) {
5338 self.add_trait_info(&mut found_traits, did, name);
5339 self.used_imports.insert((import.type_id.get(), TypeNS));
5343 match search_module.parent_link {
5344 NoParentLink | ModuleParentLink(..) => break,
5345 BlockParentLink(parent_module, _) => {
5346 search_module = parent_module;
5353 return found_traits;
5356 fn add_trait_info(&self,
5357 found_traits: &mut Vec<DefId> ,
5358 trait_def_id: DefId,
5360 debug!("(adding trait info) found trait {}:{} for method '{}'",
5363 token::get_ident(name));
5364 found_traits.push(trait_def_id);
5367 fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
5368 debug!("(recording def) recording {:?} for {:?}, last private {:?}",
5370 assert!(match lp {LastImport{..} => false, _ => true},
5371 "Import should only be used for `use` directives");
5372 self.last_private.insert(node_id, lp);
5373 let mut def_map = self.def_map.borrow_mut();
5374 def_map.get().insert_or_update_with(node_id, def, |_, old_value| {
5375 // Resolve appears to "resolve" the same ID multiple
5376 // times, so here is a sanity check it at least comes to
5377 // the same conclusion! - nmatsakis
5378 if def != *old_value {
5379 self.session.bug(format!("node_id {:?} resolved first to {:?} \
5380 and then {:?}", node_id, *old_value, def));
5385 fn enforce_default_binding_mode(&mut self,
5387 pat_binding_mode: BindingMode,
5389 match pat_binding_mode {
5390 BindByValue(_) => {}
5394 format!("cannot use `ref` binding mode with {}",
5401 // Unused import checking
5403 // Although this is mostly a lint pass, it lives in here because it depends on
5404 // resolve data structures and because it finalises the privacy information for
5405 // `use` directives.
5408 fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
5409 let mut visitor = UnusedImportCheckVisitor{ resolver: self };
5410 visit::walk_crate(&mut visitor, krate, ());
5413 fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
5414 // Ignore is_public import statements because there's no way to be sure
5415 // whether they're used or not. Also ignore imports with a dummy span
5416 // because this means that they were generated in some fashion by the
5417 // compiler and we don't need to consider them.
5418 if vi.vis == Public { return }
5419 if vi.span == DUMMY_SP { return }
5422 ViewItemExternCrate(..) => {} // ignore
5423 ViewItemUse(ref path) => {
5424 for p in path.iter() {
5426 ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
5427 ViewPathList(_, ref list, _) => {
5428 for i in list.iter() {
5429 self.finalize_import(i.node.id, i.span);
5432 ViewPathGlob(_, id) => {
5433 if !self.used_imports.contains(&(id, TypeNS)) &&
5434 !self.used_imports.contains(&(id, ValueNS)) {
5435 self.session.add_lint(UnusedImports, id, p.span, ~"unused import");
5444 // We have information about whether `use` (import) directives are actually used now.
5445 // If an import is not used at all, we signal a lint error. If an import is only used
5446 // for a single namespace, we remove the other namespace from the recorded privacy
5447 // information. That means in privacy.rs, we will only check imports and namespaces
5448 // which are used. In particular, this means that if an import could name either a
5449 // public or private item, we will check the correct thing, dependent on how the import
5451 fn finalize_import(&mut self, id: NodeId, span: Span) {
5452 debug!("finalizing import uses for {}", self.session.codemap().span_to_snippet(span));
5454 if !self.used_imports.contains(&(id, TypeNS)) &&
5455 !self.used_imports.contains(&(id, ValueNS)) {
5456 self.session.add_lint(UnusedImports, id, span, ~"unused import");
5459 let (v_priv, t_priv) = match self.last_private.find(&id) {
5460 Some(&LastImport{value_priv: v,
5463 type_used: _}) => (v, t),
5464 Some(_) => fail!("We should only have LastImport for `use` directives"),
5468 let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
5473 let t_used = if self.used_imports.contains(&(id, TypeNS)) {
5479 match (v_priv, t_priv) {
5480 // Since some items may be both in the value _and_ type namespaces (e.g., structs)
5481 // we might have two LastPrivates pointing at the same thing. There is no point
5482 // checking both, so lets not check the value one.
5483 (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
5487 self.last_private.insert(id, LastImport{value_priv: v_priv,
5490 type_used: t_used});
5496 // Diagnostics are not particularly efficient, because they're rarely
5500 /// A somewhat inefficient routine to obtain the name of a module.
5501 fn module_to_str(&mut self, module_: @Module) -> ~str {
5502 let mut idents = Vec::new();
5503 let mut current_module = module_;
5505 match current_module.parent_link {
5509 ModuleParentLink(module_, name) => {
5511 current_module = module_;
5513 BlockParentLink(module_, _) => {
5514 idents.push(special_idents::opaque);
5515 current_module = module_;
5520 if idents.len() == 0 {
5523 return self.idents_to_str(idents.move_iter()
5525 .collect::<Vec<ast::Ident>>()
5529 #[allow(dead_code)] // useful for debugging
5530 fn dump_module(&mut self, module_: @Module) {
5531 debug!("Dump of module `{}`:", self.module_to_str(module_));
5533 debug!("Children:");
5534 self.populate_module_if_necessary(module_);
5535 let children = module_.children.borrow();
5536 for (&name, _) in children.get().iter() {
5537 debug!("* {}", token::get_name(name));
5540 debug!("Import resolutions:");
5541 let import_resolutions = module_.import_resolutions.borrow();
5542 for (&name, import_resolution) in import_resolutions.get().iter() {
5544 match import_resolution.target_for_namespace(ValueNS) {
5545 None => { value_repr = ~""; }
5547 value_repr = ~" value:?";
5553 match import_resolution.target_for_namespace(TypeNS) {
5554 None => { type_repr = ~""; }
5556 type_repr = ~" type:?";
5561 debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
5566 pub struct CrateMap {
5568 exp_map2: ExportMap2,
5569 trait_map: TraitMap,
5570 external_exports: ExternalExports,
5571 last_private_map: LastPrivateMap,
5574 /// Entry point to crate resolution.
5575 pub fn resolve_crate(session: &Session,
5576 lang_items: @LanguageItems,
5579 let mut resolver = Resolver(session, lang_items, krate.span);
5580 resolver.resolve(krate);
5581 let Resolver { def_map, export_map2, trait_map, last_private,
5582 external_exports, .. } = resolver;
5585 exp_map2: export_map2,
5586 trait_map: trait_map,
5587 external_exports: external_exports,
5588 last_private_map: last_private,