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 //! Reduced graph building
13 //! Here we build the "reduced graph": the graph of the module tree without
14 //! any imports resolved.
16 use {DefModifiers, PUBLIC, IMPORTABLE};
18 use ImportDirectiveSubclass::{self, SingleImport, GlobImport};
22 use Namespace::{TypeNS, ValueNS};
24 use ParentLink::{self, ModuleParentLink, BlockParentLink};
29 use TypeParameters::HasTypeParameters;
31 use self::DuplicateCheckingMode::*;
32 use self::NamespaceError::*;
34 use rustc::metadata::csearch;
35 use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
36 use rustc::middle::def::*;
37 use rustc::middle::subst::FnSpace;
39 use syntax::ast::{Block, Crate};
40 use syntax::ast::{DeclItem, DefId};
41 use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic};
42 use syntax::ast::{Item, ItemConst, ItemEnum, ItemFn};
43 use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
44 use syntax::ast::{ItemStruct, ItemTrait, ItemTy};
45 use syntax::ast::{MethodImplItem, Name, NamedField, NodeId};
46 use syntax::ast::{PathListIdent, PathListMod};
47 use syntax::ast::{Public, SelfStatic};
48 use syntax::ast::StmtDecl;
49 use syntax::ast::StructVariantKind;
50 use syntax::ast::TupleVariantKind;
51 use syntax::ast::TyObjectSum;
52 use syntax::ast::{TypeImplItem, UnnamedField};
53 use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
54 use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
55 use syntax::ast::{Visibility};
56 use syntax::ast::TyPath;
58 use syntax::ast_util::{self, PostExpansionMethod, local_def};
59 use syntax::attr::AttrMetaMethods;
60 use syntax::parse::token::{self, special_idents};
61 use syntax::codemap::{Span, DUMMY_SP};
62 use syntax::visit::{self, Visitor};
64 use std::mem::replace;
65 use std::ops::{Deref, DerefMut};
68 // Specifies how duplicates should be handled when adding a child item if
69 // another item exists with the same name in some namespace.
70 #[derive(Copy, PartialEq)]
71 enum DuplicateCheckingMode {
72 ForbidDuplicateModules,
73 ForbidDuplicateTypesAndModules,
74 ForbidDuplicateValues,
75 ForbidDuplicateTypesAndValues,
79 #[derive(Copy, PartialEq)]
87 fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
90 ModuleError | TypeError => "type or module",
91 ValueError => "value",
95 struct GraphBuilder<'a, 'b:'a, 'tcx:'b> {
96 resolver: &'a mut Resolver<'b, 'tcx>
99 impl<'a, 'b:'a, 'tcx:'b> Deref for GraphBuilder<'a, 'b, 'tcx> {
100 type Target = Resolver<'b, 'tcx>;
102 fn deref(&self) -> &Resolver<'b, 'tcx> {
107 impl<'a, 'b:'a, 'tcx:'b> DerefMut for GraphBuilder<'a, 'b, 'tcx> {
108 fn deref_mut(&mut self) -> &mut Resolver<'b, 'tcx> {
113 impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
114 /// Constructs the reduced graph for the entire crate.
115 fn build_reduced_graph(self, krate: &ast::Crate) {
116 let parent = self.graph_root.get_module();
117 let mut visitor = BuildReducedGraphVisitor {
121 visit::walk_crate(&mut visitor, krate);
124 /// Adds a new child item to the module definition of the parent node and
125 /// returns its corresponding name bindings as well as the current parent.
126 /// Or, if we're inside a block, creates (or reuses) an anonymous module
127 /// corresponding to the innermost block ID and returns the name bindings
128 /// as well as the newly-created parent.
132 /// Panics if this node does not have a module definition and we are not inside
137 duplicate_checking_mode: DuplicateCheckingMode,
138 // For printing errors
140 -> Rc<NameBindings> {
141 // If this is the immediate descendant of a module, then we add the
142 // child name directly. Otherwise, we create or reuse an anonymous
143 // module and add the child to that.
145 self.check_for_conflicts_between_external_crates_and_items(&**parent,
149 // Add or reuse the child.
150 let child = parent.children.borrow().get(&name).cloned();
153 let child = Rc::new(NameBindings::new());
154 parent.children.borrow_mut().insert(name, child.clone());
158 // Enforce the duplicate checking mode:
160 // * If we're requesting duplicate module checking, check that
161 // there isn't a module in the module with the same name.
163 // * If we're requesting duplicate type checking, check that
164 // there isn't a type in the module with the same name.
166 // * If we're requesting duplicate value checking, check that
167 // there isn't a value in the module with the same name.
169 // * If we're requesting duplicate type checking and duplicate
170 // value checking, check that there isn't a duplicate type
171 // and a duplicate value with the same name.
173 // * If no duplicate checking was requested at all, do
176 let mut duplicate_type = NoError;
177 let ns = match duplicate_checking_mode {
178 ForbidDuplicateModules => {
179 if child.get_module_if_available().is_some() {
180 duplicate_type = ModuleError;
184 ForbidDuplicateTypesAndModules => {
185 match child.def_for_namespace(TypeNS) {
187 Some(_) if child.get_module_if_available()
188 .map(|m| m.kind.get()) ==
189 Some(ImplModuleKind) => {}
190 Some(_) => duplicate_type = TypeError
194 ForbidDuplicateValues => {
195 if child.defined_in_namespace(ValueNS) {
196 duplicate_type = ValueError;
200 ForbidDuplicateTypesAndValues => {
202 match child.def_for_namespace(TypeNS) {
203 Some(DefMod(_)) | None => {}
206 duplicate_type = TypeError;
209 if child.defined_in_namespace(ValueNS) {
210 duplicate_type = ValueError;
215 OverwriteDuplicates => None
217 if duplicate_type != NoError {
218 // Return an error here by looking up the namespace that
219 // had the duplicate.
220 let ns = ns.unwrap();
221 self.resolve_error(sp,
222 format!("duplicate definition of {} `{}`",
223 namespace_error_to_string(duplicate_type),
224 token::get_name(name))[]);
226 let r = child.span_for_namespace(ns);
228 self.session.span_note(*sp,
229 format!("first definition of {} `{}` here",
230 namespace_error_to_string(duplicate_type),
231 token::get_name(name))[]);
240 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
241 // If the block has view items, we need an anonymous module.
242 if block.view_items.len() > 0 {
246 // Check each statement.
247 for statement in block.stmts.iter() {
248 match statement.node {
249 StmtDecl(ref declaration, _) => {
250 match declaration.node {
265 // If we found neither view items nor items, we don't need to create
266 // an anonymous module.
271 fn get_parent_link(&mut self, parent: &Rc<Module>, name: Name) -> ParentLink {
272 ModuleParentLink(parent.downgrade(), name)
275 /// Constructs the reduced graph for one item.
276 fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) -> Rc<Module> {
277 let name = item.ident.name;
279 let is_public = item.vis == ast::Public;
280 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
284 let name_bindings = self.add_child(name, parent, ForbidDuplicateModules, sp);
286 let parent_link = self.get_parent_link(parent, name);
287 let def_id = DefId { krate: 0, node: item.id };
288 name_bindings.define_module(parent_link,
292 item.vis == ast::Public,
295 name_bindings.get_module()
298 ItemForeignMod(..) => parent.clone(),
300 // These items live in the value namespace.
301 ItemStatic(_, m, _) => {
302 let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, sp);
303 let mutbl = m == ast::MutMutable;
305 name_bindings.define_value(DefStatic(local_def(item.id), mutbl), sp, modifiers);
309 self.add_child(name, parent, ForbidDuplicateValues, sp)
310 .define_value(DefConst(local_def(item.id)), sp, modifiers);
313 ItemFn(_, _, _, _, _) => {
314 let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, sp);
316 let def = DefFn(local_def(item.id), false);
317 name_bindings.define_value(def, sp, modifiers);
321 // These items live in the type namespace.
324 self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp);
326 name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
330 ItemEnum(ref enum_definition, _) => {
332 self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp);
334 name_bindings.define_type(DefTy(local_def(item.id), true), sp, modifiers);
336 let parent_link = self.get_parent_link(parent, name);
337 // We want to make sure the module type is EnumModuleKind
338 // even if there's already an ImplModuleKind module defined,
339 // since that's how we prevent duplicate enum definitions
340 name_bindings.set_module_kind(parent_link,
341 Some(local_def(item.id)),
347 let module = name_bindings.get_module();
349 for variant in (*enum_definition).variants.iter() {
350 self.build_reduced_graph_for_variant(
358 // These items live in both the type and value namespaces.
359 ItemStruct(ref struct_def, _) => {
360 // Adding to both Type and Value namespaces or just Type?
361 let (forbid, ctor_id) = match struct_def.ctor_id {
362 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
363 None => (ForbidDuplicateTypesAndModules, None)
366 let name_bindings = self.add_child(name, parent, forbid, sp);
368 // Define a name in the type namespace.
369 name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
371 // If this is a newtype or unit-like struct, define a name
372 // in the value namespace as well
373 if let Some(cid) = ctor_id {
374 name_bindings.define_value(DefStruct(local_def(cid)), sp, modifiers);
377 // Record the def ID and fields of this struct.
378 let named_fields = struct_def.fields.iter().filter_map(|f| {
380 NamedField(ident, _) => Some(ident.name),
381 UnnamedField(_) => None
384 self.structs.insert(local_def(item.id), named_fields);
389 ItemImpl(_, _, None, ref ty, ref impl_items) => {
390 // If this implements an anonymous trait, then add all the
391 // methods within to a new module, if the type was defined
392 // within this module.
394 let mod_name = match ty.node {
395 TyPath(ref path, _) if path.segments.len() == 1 => {
396 // FIXME(18446) we should distinguish between the name of
397 // a trait and the name of an impl of that trait.
398 Some(path.segments.last().unwrap().identifier.name)
400 TyObjectSum(ref lhs_ty, _) => {
402 TyPath(ref path, _) if path.segments.len() == 1 => {
403 Some(path.segments.last().unwrap().identifier.name)
417 self.resolve_error(ty.span,
418 "inherent implementations may \
419 only be implemented in the same \
420 module as the type they are \
424 // Create the module and add all methods.
425 let parent_opt = parent.children.borrow().get(&mod_name).cloned();
426 let new_parent = match parent_opt {
428 Some(ref child) if child.get_module_if_available()
430 (child.get_module().kind.get() == ImplModuleKind ||
431 child.get_module().kind.get() == TraitModuleKind) => {
434 Some(ref child) if child.get_module_if_available()
436 child.get_module().kind.get() ==
437 EnumModuleKind => child.get_module(),
441 self.add_child(mod_name, parent, ForbidDuplicateModules, sp);
443 let parent_link = self.get_parent_link(parent, name);
444 let def_id = local_def(item.id);
447 !name_bindings.defined_in_namespace(ns) ||
448 name_bindings.defined_in_public_namespace(ns);
450 name_bindings.define_module(parent_link,
457 name_bindings.get_module()
461 // For each implementation item...
462 for impl_item in impl_items.iter() {
464 MethodImplItem(ref method) => {
465 // Add the method to the module.
466 let name = method.pe_ident().name;
467 let method_name_bindings =
470 ForbidDuplicateValues,
472 let def = match method.pe_explicit_self()
475 // Static methods become
476 // `DefStaticMethod`s.
477 DefStaticMethod(local_def(method.id),
478 FromImpl(local_def(item.id)))
481 // Non-static methods become
483 DefMethod(local_def(method.id),
485 FromImpl(local_def(item.id)))
489 // NB: not IMPORTABLE
490 let modifiers = if method.pe_vis() == ast::Public {
493 DefModifiers::empty()
495 method_name_bindings.define_value(
500 TypeImplItem(ref typedef) => {
501 // Add the typedef to the module.
502 let name = typedef.ident.name;
503 let typedef_name_bindings =
507 ForbidDuplicateTypesAndModules,
509 let def = DefAssociatedTy(local_def(
511 // NB: not IMPORTABLE
512 let modifiers = if typedef.vis == ast::Public {
515 DefModifiers::empty()
517 typedef_name_bindings.define_type(
530 ItemImpl(_, _, Some(_), _, _) => parent.clone(),
532 ItemTrait(_, _, _, ref items) => {
534 self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp);
536 // Add all the items within to a new module.
537 let parent_link = self.get_parent_link(parent, name);
538 name_bindings.define_module(parent_link,
539 Some(local_def(item.id)),
542 item.vis == ast::Public,
544 let module_parent = name_bindings.get_module();
546 let def_id = local_def(item.id);
548 // Add the names of all the items to the trait info.
549 for trait_item in items.iter() {
550 let (name, kind) = match *trait_item {
551 ast::RequiredMethod(_) |
552 ast::ProvidedMethod(_) => {
553 let ty_m = ast_util::trait_item_to_ty_method(trait_item);
555 let name = ty_m.ident.name;
557 // Add it as a name in the trait module.
558 let (def, static_flag) = match ty_m.explicit_self
561 // Static methods become `DefStaticMethod`s.
564 FromTrait(local_def(item.id))),
565 StaticMethodTraitItemKind)
568 // Non-static methods become `DefMethod`s.
569 (DefMethod(local_def(ty_m.id),
570 Some(local_def(item.id)),
571 FromTrait(local_def(item.id))),
572 NonstaticMethodTraitItemKind)
576 let method_name_bindings =
579 ForbidDuplicateTypesAndValues,
581 // NB: not IMPORTABLE
582 method_name_bindings.define_value(def,
588 ast::TypeTraitItem(ref associated_type) => {
589 let def = DefAssociatedTy(local_def(
590 associated_type.ty_param.id));
593 self.add_child(associated_type.ty_param.ident.name,
595 ForbidDuplicateTypesAndValues,
596 associated_type.ty_param.span);
597 // NB: not IMPORTABLE
598 name_bindings.define_type(def,
599 associated_type.ty_param.span,
602 (associated_type.ty_param.ident.name, TypeTraitItemKind)
606 self.trait_item_map.insert((name, def_id), kind);
609 name_bindings.define_type(DefTrait(def_id), sp, modifiers);
612 ItemMac(..) => parent.clone()
616 // Constructs the reduced graph for one variant. Variants exist in the
617 // type and value namespaces.
618 fn build_reduced_graph_for_variant(&mut self,
621 parent: &Rc<Module>) {
622 let name = variant.node.name.name;
623 let is_exported = match variant.node.kind {
624 TupleVariantKind(_) => false,
625 StructVariantKind(_) => {
626 // Not adding fields for variants as they are not accessed with a self receiver
627 self.structs.insert(local_def(variant.node.id), Vec::new());
632 let child = self.add_child(name, parent,
633 ForbidDuplicateTypesAndValues,
635 // variants are always treated as importable to allow them to be glob
637 child.define_value(DefVariant(item_id,
638 local_def(variant.node.id), is_exported),
639 variant.span, PUBLIC | IMPORTABLE);
640 child.define_type(DefVariant(item_id,
641 local_def(variant.node.id), is_exported),
642 variant.span, PUBLIC | IMPORTABLE);
645 /// Constructs the reduced graph for one 'view item'. View items consist
646 /// of imports and use directives.
647 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem, parent: &Rc<Module>) {
648 match view_item.node {
649 ViewItemUse(ref view_path) => {
650 // Extract and intern the module part of the path. For
651 // globs and lists, the path is found directly in the AST;
652 // for simple paths we have to munge the path a little.
653 let module_path = match view_path.node {
654 ViewPathSimple(_, ref full_path, _) => {
657 .iter().map(|ident| ident.identifier.name)
661 ViewPathGlob(ref module_ident_path, _) |
662 ViewPathList(ref module_ident_path, _, _) => {
663 module_ident_path.segments
664 .iter().map(|ident| ident.identifier.name).collect()
668 // Build up the import directives.
669 let is_public = view_item.vis == ast::Public;
674 attr.name() == token::get_name(
675 special_idents::prelude_import.name)
677 let shadowable = if shadowable {
683 match view_path.node {
684 ViewPathSimple(binding, ref full_path, id) => {
686 full_path.segments.last().unwrap().identifier.name;
687 if token::get_name(source_name).get() == "mod" ||
688 token::get_name(source_name).get() == "self" {
689 self.resolve_error(view_path.span,
690 "`self` imports are only allowed within a { } list");
693 let subclass = SingleImport(binding.name,
695 self.build_import_directive(&**parent,
703 ViewPathList(_, ref source_items, _) => {
704 // Make sure there's at most one `mod` import in the list.
705 let mod_spans = source_items.iter().filter_map(|item| match item.node {
706 PathListMod { .. } => Some(item.span),
708 }).collect::<Vec<Span>>();
709 if mod_spans.len() > 1 {
710 self.resolve_error(mod_spans[0],
711 "`self` import can only appear once in the list");
712 for other_span in mod_spans.iter().skip(1) {
713 self.session.span_note(*other_span,
714 "another `self` import appears here");
718 for source_item in source_items.iter() {
719 let (module_path, name) = match source_item.node {
720 PathListIdent { name, .. } =>
721 (module_path.clone(), name.name),
722 PathListMod { .. } => {
723 let name = match module_path.last() {
726 self.resolve_error(source_item.span,
727 "`self` import can only appear in an import list \
728 with a non-empty prefix");
732 let module_path = module_path.init();
733 (module_path.to_vec(), name)
736 self.build_import_directive(
739 SingleImport(name, name),
741 source_item.node.id(),
746 ViewPathGlob(_, id) => {
747 self.build_import_directive(&**parent,
758 ViewItemExternCrate(name, _, node_id) => {
759 // n.b. we don't need to look at the path option here, because cstore already did
760 for &crate_id in self.session.cstore
761 .find_extern_mod_stmt_cnum(node_id).iter() {
762 let def_id = DefId { krate: crate_id, node: 0 };
763 self.external_exports.insert(def_id);
764 let parent_link = ModuleParentLink(parent.downgrade(), name.name);
765 let external_module = Rc::new(Module::new(parent_link,
770 debug!("(build reduced graph for item) found extern `{}`",
771 self.module_to_string(&*external_module));
772 self.check_for_conflicts_between_external_crates(
776 parent.external_module_children.borrow_mut()
777 .insert(name.name, external_module.clone());
778 self.build_reduced_graph_for_external_crate(&external_module);
784 /// Constructs the reduced graph for one foreign item.
785 fn build_reduced_graph_for_foreign_item<F>(&mut self,
786 foreign_item: &ForeignItem,
789 F: FnOnce(&mut Resolver),
791 let name = foreign_item.ident.name;
792 let is_public = foreign_item.vis == ast::Public;
793 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
795 self.add_child(name, parent, ForbidDuplicateValues,
798 match foreign_item.node {
799 ForeignItemFn(_, ref generics) => {
800 let def = DefFn(local_def(foreign_item.id), false);
801 name_bindings.define_value(def, foreign_item.span, modifiers);
803 self.with_type_parameter_rib(
804 HasTypeParameters(generics,
810 ForeignItemStatic(_, m) => {
811 let def = DefStatic(local_def(foreign_item.id), m);
812 name_bindings.define_value(def, foreign_item.span, modifiers);
819 fn build_reduced_graph_for_block(&mut self, block: &Block, parent: &Rc<Module>) -> Rc<Module> {
820 if self.block_needs_anonymous_module(block) {
821 let block_id = block.id;
823 debug!("(building reduced graph for block) creating a new \
824 anonymous module for block {}",
827 let new_module = Rc::new(Module::new(
828 BlockParentLink(parent.downgrade(), block_id),
833 parent.anonymous_children.borrow_mut().insert(block_id, new_module.clone());
840 fn handle_external_def(&mut self,
843 child_name_bindings: &NameBindings,
846 new_parent: &Rc<Module>) {
847 debug!("(building reduced graph for \
848 external crate) building external def, priv {}",
850 let is_public = vis == ast::Public;
851 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
852 let is_exported = is_public && match new_parent.def_id.get() {
854 Some(did) => self.external_exports.contains(&did)
857 self.external_exports.insert(def.def_id());
860 let kind = match def {
861 DefTy(_, true) => EnumModuleKind,
862 DefStruct(..) | DefTy(..) => ImplModuleKind,
863 _ => NormalModuleKind
867 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
868 DefTy(def_id, _) => {
869 let type_def = child_name_bindings.type_def.borrow().clone();
871 Some(TypeNsDef { module_def: Some(module_def), .. }) => {
872 debug!("(building reduced graph for external crate) \
873 already created module");
874 module_def.def_id.set(Some(def_id));
877 debug!("(building reduced graph for \
878 external crate) building module \
880 let parent_link = self.get_parent_link(new_parent, name);
882 child_name_bindings.define_module(parent_link,
895 DefMod(_) | DefForeignMod(_) => {}
896 DefVariant(_, variant_id, is_struct) => {
897 debug!("(building reduced graph for external crate) building \
900 // variants are always treated as importable to allow them to be
902 let modifiers = PUBLIC | IMPORTABLE;
904 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
905 // Not adding fields for variants as they are not accessed with a self receiver
906 self.structs.insert(variant_id, Vec::new());
908 child_name_bindings.define_value(def, DUMMY_SP, modifiers);
911 DefFn(ctor_id, true) => {
912 child_name_bindings.define_value(
913 csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
914 .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
916 DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
917 debug!("(building reduced graph for external \
918 crate) building value (fn/static) {}", final_ident);
919 // impl methods have already been defined with the correct importability modifier
920 let mut modifiers = match *child_name_bindings.value_def.borrow() {
921 Some(ref def) => (modifiers & !IMPORTABLE) | (def.modifiers & IMPORTABLE),
924 if new_parent.kind.get() != NormalModuleKind {
925 modifiers = modifiers & !IMPORTABLE;
927 child_name_bindings.define_value(def, DUMMY_SP, modifiers);
929 DefTrait(def_id) => {
930 debug!("(building reduced graph for external \
931 crate) building type {}", final_ident);
933 // If this is a trait, add all the trait item names to the trait
936 let trait_item_def_ids =
937 csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
938 for trait_item_def_id in trait_item_def_ids.iter() {
939 let (trait_item_name, trait_item_kind) =
940 csearch::get_trait_item_name_and_kind(
941 &self.session.cstore,
942 trait_item_def_id.def_id());
944 debug!("(building reduced graph for external crate) ... \
945 adding trait item '{}'",
946 token::get_name(trait_item_name));
948 self.trait_item_map.insert((trait_item_name, def_id), trait_item_kind);
951 self.external_exports
952 .insert(trait_item_def_id.def_id());
956 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
958 // Define a module if necessary.
959 let parent_link = self.get_parent_link(new_parent, name);
960 child_name_bindings.set_module_kind(parent_link,
967 DefTy(..) | DefAssociatedTy(..) | DefAssociatedPath(..) => {
968 debug!("(building reduced graph for external \
969 crate) building type {}", final_ident);
971 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
973 DefStruct(def_id) => {
974 debug!("(building reduced graph for external \
975 crate) building type and value for {}",
977 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
978 let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
980 }).collect::<Vec<_>>();
982 if fields.len() == 0 {
983 child_name_bindings.define_value(def, DUMMY_SP, modifiers);
986 // Record the def ID and fields of this struct.
987 self.structs.insert(def_id, fields);
989 DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
990 DefUse(..) | DefUpvar(..) | DefRegion(..) |
991 DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
992 panic!("didn't expect `{}`", def);
997 /// Builds the reduced graph for a single item in an external crate.
998 fn build_reduced_graph_for_external_crate_def(&mut self,
1002 visibility: Visibility) {
1005 // Add the new child item, if necessary.
1007 DefForeignMod(def_id) => {
1008 // Foreign modules have no names. Recur and populate
1010 csearch::each_child_of_item(&self.session.cstore,
1015 self.build_reduced_graph_for_external_crate_def(
1023 let child_name_bindings =
1024 self.add_child(name,
1026 OverwriteDuplicates,
1029 self.handle_external_def(def,
1031 &*child_name_bindings,
1032 token::get_name(name).get(),
1039 match csearch::get_type_name_if_impl(&self.session.cstore, def) {
1041 Some(final_name) => {
1043 csearch::get_methods_if_impl(&self.session.cstore, def);
1045 Some(ref methods) if
1046 methods.len() >= 1 => {
1047 debug!("(building reduced graph for \
1048 external crate) processing \
1049 static methods for type name {}",
1050 token::get_name(final_name));
1052 let child_name_bindings =
1056 OverwriteDuplicates,
1059 // Process the static methods. First,
1060 // create the module.
1062 let type_def = child_name_bindings.type_def.borrow().clone();
1065 module_def: Some(module_def),
1068 // We already have a module. This
1070 type_module = module_def;
1072 // Mark it as an impl module if
1074 type_module.kind.set(ImplModuleKind);
1078 self.get_parent_link(root, final_name);
1079 child_name_bindings.define_module(
1087 child_name_bindings.
1092 // Add each static method to the module.
1093 let new_parent = type_module;
1094 for method_info in methods.iter() {
1095 let name = method_info.name;
1096 debug!("(building reduced graph for \
1097 external crate) creating \
1098 static method '{}'",
1099 token::get_name(name));
1101 let method_name_bindings =
1102 self.add_child(name,
1104 OverwriteDuplicates,
1106 let def = DefFn(method_info.def_id, false);
1108 // NB: not IMPORTABLE
1109 let modifiers = if visibility == ast::Public {
1112 DefModifiers::empty()
1114 method_name_bindings.define_value(
1115 def, DUMMY_SP, modifiers);
1119 // Otherwise, do nothing.
1120 Some(_) | None => {}
1126 debug!("(building reduced graph for external crate) \
1132 /// Builds the reduced graph rooted at the given external module.
1133 fn populate_external_module(&mut self, module: &Rc<Module>) {
1134 debug!("(populating external module) attempting to populate {}",
1135 self.module_to_string(&**module));
1137 let def_id = match module.def_id.get() {
1139 debug!("(populating external module) ... no def ID!");
1142 Some(def_id) => def_id,
1145 csearch::each_child_of_item(&self.session.cstore,
1147 |def_like, child_name, visibility| {
1148 debug!("(populating external module) ... found ident: {}",
1149 token::get_name(child_name));
1150 self.build_reduced_graph_for_external_crate_def(module,
1155 module.populated.set(true)
1158 /// Ensures that the reduced graph rooted at the given external module
1159 /// is built, building it if it is not.
1160 fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
1161 if !module.populated.get() {
1162 self.populate_external_module(module)
1164 assert!(module.populated.get())
1167 /// Builds the reduced graph rooted at the 'use' directive for an external
1169 fn build_reduced_graph_for_external_crate(&mut self, root: &Rc<Module>) {
1170 csearch::each_top_level_item_of_crate(&self.session.cstore,
1175 |def_like, name, visibility| {
1176 self.build_reduced_graph_for_external_crate_def(root, def_like, name, visibility)
1180 /// Creates and adds an import directive to the given module.
1181 fn build_import_directive(&mut self,
1183 module_path: Vec<Name>,
1184 subclass: ImportDirectiveSubclass,
1188 shadowable: Shadowable) {
1189 module_.imports.borrow_mut().push(ImportDirective::new(module_path,
1195 self.unresolved_imports += 1;
1196 // Bump the reference count on the name. Or, if this is a glob, set
1197 // the appropriate flag.
1200 SingleImport(target, _) => {
1201 debug!("(building import directive) building import \
1203 self.names_to_string(module_.imports.borrow().last().unwrap()
1205 token::get_name(target));
1207 let mut import_resolutions = module_.import_resolutions
1209 match import_resolutions.get_mut(&target) {
1210 Some(resolution) => {
1211 debug!("(building import directive) bumping \
1213 resolution.outstanding_references += 1;
1215 // the source of this name is different now
1216 resolution.type_id = id;
1217 resolution.value_id = id;
1218 resolution.is_public = is_public;
1223 debug!("(building import directive) creating new");
1224 let mut resolution = ImportResolution::new(id, is_public);
1225 resolution.outstanding_references = 1;
1226 import_resolutions.insert(target, resolution);
1229 // Set the glob flag. This tells us that we don't know the
1230 // module's exports ahead of time.
1232 module_.glob_count.set(module_.glob_count.get() + 1);
1238 struct BuildReducedGraphVisitor<'a, 'b:'a, 'tcx:'b> {
1239 builder: GraphBuilder<'a, 'b, 'tcx>,
1243 impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
1244 fn visit_item(&mut self, item: &Item) {
1245 let p = self.builder.build_reduced_graph_for_item(item, &self.parent);
1246 let old_parent = replace(&mut self.parent, p);
1247 visit::walk_item(self, item);
1248 self.parent = old_parent;
1251 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
1252 let parent = &self.parent;
1253 self.builder.build_reduced_graph_for_foreign_item(foreign_item,
1256 let mut v = BuildReducedGraphVisitor {
1257 builder: GraphBuilder { resolver: r },
1258 parent: parent.clone()
1260 visit::walk_foreign_item(&mut v, foreign_item);
1264 fn visit_view_item(&mut self, view_item: &ViewItem) {
1265 self.builder.build_reduced_graph_for_view_item(view_item, &self.parent);
1268 fn visit_block(&mut self, block: &Block) {
1269 let np = self.builder.build_reduced_graph_for_block(block, &self.parent);
1270 let old_parent = replace(&mut self.parent, np);
1271 visit::walk_block(self, block);
1272 self.parent = old_parent;
1276 pub fn build_reduced_graph(resolver: &mut Resolver, krate: &ast::Crate) {
1279 }.build_reduced_graph(krate);
1282 pub fn populate_module_if_necessary(resolver: &mut Resolver, module: &Rc<Module>) {
1285 }.populate_module_if_necessary(module);