]> git.proxmox.com Git - rustc.git/blame - src/librustc_resolve/build_reduced_graph.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / librustc_resolve / build_reduced_graph.rs
CommitLineData
1a4d82fc
JJ
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.
4//
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.
10
11//! Reduced graph building
12//!
13//! Here we build the "reduced graph": the graph of the module tree without
14//! any imports resolved.
15
d9579d0f 16use DefModifiers;
54a0048b 17use resolve_imports::ImportDirectiveSubclass::{self, GlobImport};
1a4d82fc 18use Module;
7453a54e
SL
19use Namespace::{self, TypeNS, ValueNS};
20use {NameBinding, NameBindingKind};
9cc50fc6 21use ParentLink::{ModuleParentLink, BlockParentLink};
1a4d82fc 22use Resolver;
9cc50fc6 23use {resolve_error, resolve_struct_error, ResolutionError};
1a4d82fc 24
54a0048b
SL
25use rustc::middle::cstore::{CrateStore, ChildItem, DlDef};
26use rustc::lint;
27use rustc::hir::def::*;
28use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
29use rustc::ty::{self, VariantKind};
1a4d82fc 30
54a0048b 31use syntax::ast::Name;
b039eaaf 32use syntax::attr::AttrMetaMethods;
54a0048b 33use syntax::parse::token::{special_idents, SELF_KEYWORD_NAME, SUPER_KEYWORD_NAME};
1a4d82fc 34use syntax::codemap::{Span, DUMMY_SP};
e9174d1e 35
54a0048b
SL
36use rustc::hir;
37use rustc::hir::{Block, DeclItem};
38use rustc::hir::{ForeignItem, ForeignItemFn, ForeignItemStatic};
39use rustc::hir::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn};
40use rustc::hir::{ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl};
41use rustc::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse};
42use rustc::hir::{PathListIdent, PathListMod, StmtDecl};
43use rustc::hir::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
44use rustc::hir::intravisit::{self, Visitor};
1a4d82fc 45
7453a54e
SL
46trait ToNameBinding<'a> {
47 fn to_name_binding(self) -> NameBinding<'a>;
48}
49
50impl<'a> ToNameBinding<'a> for (Module<'a>, Span) {
51 fn to_name_binding(self) -> NameBinding<'a> {
52 NameBinding::create_from_module(self.0, Some(self.1))
53 }
54}
55
56impl<'a> ToNameBinding<'a> for (Def, Span, DefModifiers) {
57 fn to_name_binding(self) -> NameBinding<'a> {
58 let kind = NameBindingKind::Def(self.0);
59 NameBinding { modifiers: self.2, kind: kind, span: Some(self.1) }
60 }
61}
62
54a0048b 63impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
1a4d82fc 64 /// Constructs the reduced graph for the entire crate.
54a0048b 65 pub fn build_reduced_graph(&mut self, krate: &hir::Crate) {
1a4d82fc 66 let mut visitor = BuildReducedGraphVisitor {
9cc50fc6 67 parent: self.graph_root,
54a0048b 68 resolver: self,
1a4d82fc 69 };
92a42be0 70 intravisit::walk_crate(&mut visitor, krate);
1a4d82fc
JJ
71 }
72
7453a54e
SL
73 /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined.
74 fn try_define<T>(&self, parent: Module<'b>, name: Name, ns: Namespace, def: T)
75 where T: ToNameBinding<'b>
76 {
54a0048b 77 let _ = parent.try_define_child(name, ns, def.to_name_binding());
7453a54e
SL
78 }
79
80 /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
81 /// otherwise, reports an error.
82 fn define<T: ToNameBinding<'b>>(&self, parent: Module<'b>, name: Name, ns: Namespace, def: T) {
54a0048b
SL
83 let binding = def.to_name_binding();
84 if let Err(old_binding) = parent.try_define_child(name, ns, binding.clone()) {
85 self.report_conflict(parent, name, ns, old_binding, &binding);
1a4d82fc
JJ
86 }
87 }
88
89 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
7453a54e
SL
90 fn is_item(statement: &hir::Stmt) -> bool {
91 if let StmtDecl(ref declaration, _) = statement.node {
92 if let DeclItem(_) = declaration.node {
93 return true;
1a4d82fc
JJ
94 }
95 }
7453a54e 96 false
1a4d82fc
JJ
97 }
98
7453a54e
SL
99 // If any statements are items, we need to create an anonymous module
100 block.stmts.iter().any(is_item)
1a4d82fc
JJ
101 }
102
1a4d82fc 103 /// Constructs the reduced graph for one item.
54a0048b
SL
104 fn build_reduced_graph_for_item(&mut self, item: &Item, parent_ref: &mut Module<'b>) {
105 let parent = *parent_ref;
b039eaaf 106 let name = item.name;
1a4d82fc 107 let sp = item.span;
e9174d1e 108 let is_public = item.vis == hir::Public;
d9579d0f
AL
109 let modifiers = if is_public {
110 DefModifiers::PUBLIC
111 } else {
112 DefModifiers::empty()
113 } | DefModifiers::IMPORTABLE;
1a4d82fc
JJ
114
115 match item.node {
85aaf69f
SL
116 ItemUse(ref view_path) => {
117 // Extract and intern the module part of the path. For
118 // globs and lists, the path is found directly in the AST;
119 // for simple paths we have to munge the path a little.
54a0048b
SL
120 let is_global;
121 let module_path: Vec<Name> = match view_path.node {
85aaf69f 122 ViewPathSimple(_, ref full_path) => {
54a0048b 123 is_global = full_path.global;
85aaf69f 124 full_path.segments
92a42be0
SL
125 .split_last()
126 .unwrap()
127 .1
128 .iter()
129 .map(|seg| seg.identifier.name)
130 .collect()
85aaf69f
SL
131 }
132
133 ViewPathGlob(ref module_ident_path) |
134 ViewPathList(ref module_ident_path, _) => {
54a0048b 135 is_global = module_ident_path.global;
85aaf69f 136 module_ident_path.segments
92a42be0
SL
137 .iter()
138 .map(|seg| seg.identifier.name)
139 .collect()
85aaf69f
SL
140 }
141 };
142
54a0048b
SL
143 // Checking for special identifiers in path
144 // prevent `self` or `super` at beginning of global path
145 if is_global && (module_path.first() == Some(&SELF_KEYWORD_NAME) ||
146 module_path.first() == Some(&SUPER_KEYWORD_NAME)) {
147 self.session.add_lint(
148 lint::builtin::SUPER_OR_SELF_IN_GLOBAL_PATH,
149 item.id,
150 item.span,
151 format!("expected identifier, found keyword `{}`",
152 module_path.first().unwrap().as_str()));
153 }
154
85aaf69f 155 // Build up the import directives.
54a0048b 156 let is_prelude = item.attrs.iter().any(|attr| {
c1a9b12d 157 attr.name() == special_idents::prelude_import.name.as_str()
85aaf69f 158 });
85aaf69f
SL
159
160 match view_path.node {
161 ViewPathSimple(binding, ref full_path) => {
92a42be0 162 let source_name = full_path.segments.last().unwrap().identifier.name;
c1a9b12d
SL
163 if source_name.as_str() == "mod" || source_name.as_str() == "self" {
164 resolve_error(self,
165 view_path.span,
166 ResolutionError::SelfImportsOnlyAllowedWithin);
85aaf69f
SL
167 }
168
54a0048b
SL
169 let subclass = ImportDirectiveSubclass::single(binding, source_name);
170 self.unresolved_imports += 1;
171 parent.add_import_directive(module_path,
85aaf69f
SL
172 subclass,
173 view_path.span,
174 item.id,
175 is_public,
54a0048b 176 is_prelude);
85aaf69f
SL
177 }
178 ViewPathList(_, ref source_items) => {
179 // Make sure there's at most one `mod` import in the list.
92a42be0
SL
180 let mod_spans = source_items.iter()
181 .filter_map(|item| {
182 match item.node {
183 PathListMod { .. } => Some(item.span),
184 _ => None,
185 }
186 })
187 .collect::<Vec<Span>>();
85aaf69f 188 if mod_spans.len() > 1 {
9cc50fc6 189 let mut e = resolve_struct_error(self,
92a42be0
SL
190 mod_spans[0],
191 ResolutionError::SelfImportCanOnlyAppearOnceInTheList);
85aaf69f 192 for other_span in mod_spans.iter().skip(1) {
9cc50fc6 193 e.span_note(*other_span, "another `self` import appears here");
85aaf69f 194 }
9cc50fc6 195 e.emit();
85aaf69f
SL
196 }
197
198 for source_item in source_items {
e9174d1e
SL
199 let (module_path, name, rename) = match source_item.node {
200 PathListIdent { name, rename, .. } =>
b039eaaf 201 (module_path.clone(), name, rename.unwrap_or(name)),
e9174d1e 202 PathListMod { rename, .. } => {
85aaf69f
SL
203 let name = match module_path.last() {
204 Some(name) => *name,
205 None => {
c1a9b12d
SL
206 resolve_error(
207 self,
208 source_item.span,
209 ResolutionError::
210 SelfImportOnlyInImportListWithNonEmptyPrefix
211 );
85aaf69f
SL
212 continue;
213 }
214 };
c1a9b12d 215 let module_path = module_path.split_last().unwrap().1;
b039eaaf 216 let rename = rename.unwrap_or(name);
e9174d1e 217 (module_path.to_vec(), name, rename)
85aaf69f
SL
218 }
219 };
54a0048b
SL
220 let subclass = ImportDirectiveSubclass::single(rename, name);
221 self.unresolved_imports += 1;
222 parent.add_import_directive(module_path,
223 subclass,
92a42be0
SL
224 source_item.span,
225 source_item.node.id(),
226 is_public,
54a0048b 227 is_prelude);
85aaf69f
SL
228 }
229 }
230 ViewPathGlob(_) => {
54a0048b
SL
231 self.unresolved_imports += 1;
232 parent.add_import_directive(module_path,
85aaf69f
SL
233 GlobImport,
234 view_path.span,
235 item.id,
236 is_public,
54a0048b 237 is_prelude);
85aaf69f
SL
238 }
239 }
85aaf69f
SL
240 }
241
242 ItemExternCrate(_) => {
92a42be0
SL
243 // n.b. we don't need to look at the path option here, because cstore already
244 // did
245 if let Some(crate_id) = self.session.cstore.extern_mod_stmt_cnum(item.id) {
246 let def_id = DefId {
247 krate: crate_id,
248 index: CRATE_DEF_INDEX,
249 };
9cc50fc6 250 let parent_link = ModuleParentLink(parent, name);
7453a54e 251 let def = Def::Mod(def_id);
54a0048b
SL
252 let module = self.new_extern_crate_module(parent_link, def, is_public, item.id);
253 self.define(parent, name, TypeNS, (module, sp));
7453a54e 254
54a0048b 255 self.build_reduced_graph_for_external_crate(module);
85aaf69f 256 }
85aaf69f
SL
257 }
258
1a4d82fc 259 ItemMod(..) => {
9cc50fc6 260 let parent_link = ModuleParentLink(parent, name);
7453a54e 261 let def = Def::Mod(self.ast_map.local_def_id(item.id));
9cc50fc6 262 let module = self.new_module(parent_link, Some(def), false, is_public);
7453a54e
SL
263 self.define(parent, name, TypeNS, (module, sp));
264 parent.module_children.borrow_mut().insert(item.id, module);
54a0048b 265 *parent_ref = module;
1a4d82fc
JJ
266 }
267
54a0048b 268 ItemForeignMod(..) => {}
1a4d82fc
JJ
269
270 // These items live in the value namespace.
271 ItemStatic(_, m, _) => {
e9174d1e 272 let mutbl = m == hir::MutMutable;
7453a54e
SL
273 let def = Def::Static(self.ast_map.local_def_id(item.id), mutbl);
274 self.define(parent, name, ValueNS, (def, sp, modifiers));
1a4d82fc
JJ
275 }
276 ItemConst(_, _) => {
7453a54e
SL
277 let def = Def::Const(self.ast_map.local_def_id(item.id));
278 self.define(parent, name, ValueNS, (def, sp, modifiers));
1a4d82fc 279 }
62682a34 280 ItemFn(_, _, _, _, _, _) => {
7453a54e
SL
281 let def = Def::Fn(self.ast_map.local_def_id(item.id));
282 self.define(parent, name, ValueNS, (def, sp, modifiers));
1a4d82fc
JJ
283 }
284
285 // These items live in the type namespace.
286 ItemTy(..) => {
7453a54e 287 let def = Def::TyAlias(self.ast_map.local_def_id(item.id));
54a0048b 288 self.define(parent, name, TypeNS, (def, sp, modifiers));
1a4d82fc
JJ
289 }
290
291 ItemEnum(ref enum_definition, _) => {
9cc50fc6 292 let parent_link = ModuleParentLink(parent, name);
7453a54e 293 let def = Def::Enum(self.ast_map.local_def_id(item.id));
9cc50fc6 294 let module = self.new_module(parent_link, Some(def), false, is_public);
7453a54e 295 self.define(parent, name, TypeNS, (module, sp));
1a4d82fc 296
9cc50fc6
SL
297 let variant_modifiers = if is_public {
298 DefModifiers::empty()
299 } else {
300 DefModifiers::PRIVATE_VARIANT
301 };
85aaf69f 302 for variant in &(*enum_definition).variants {
b039eaaf 303 let item_def_id = self.ast_map.local_def_id(item.id);
9cc50fc6 304 self.build_reduced_graph_for_variant(variant, item_def_id,
7453a54e 305 module, variant_modifiers);
1a4d82fc 306 }
1a4d82fc
JJ
307 }
308
309 // These items live in both the type and value namespaces.
310 ItemStruct(ref struct_def, _) => {
1a4d82fc 311 // Define a name in the type namespace.
7453a54e
SL
312 let def = Def::Struct(self.ast_map.local_def_id(item.id));
313 self.define(parent, name, TypeNS, (def, sp, modifiers));
1a4d82fc
JJ
314
315 // If this is a newtype or unit-like struct, define a name
316 // in the value namespace as well
7453a54e
SL
317 if !struct_def.is_struct() {
318 let def = Def::Struct(self.ast_map.local_def_id(struct_def.id()));
319 self.define(parent, name, ValueNS, (def, sp, modifiers));
1a4d82fc
JJ
320 }
321
322 // Record the def ID and fields of this struct.
54a0048b
SL
323 let field_names = struct_def.fields()
324 .iter()
325 .map(|f| f.name)
326 .collect();
b039eaaf 327 let item_def_id = self.ast_map.local_def_id(item.id);
54a0048b 328 self.structs.insert(item_def_id, field_names);
1a4d82fc
JJ
329 }
330
54a0048b 331 ItemDefaultImpl(_, _) | ItemImpl(..) => {}
1a4d82fc
JJ
332
333 ItemTrait(_, _, _, ref items) => {
92a42be0 334 let def_id = self.ast_map.local_def_id(item.id);
1a4d82fc
JJ
335
336 // Add all the items within to a new module.
9cc50fc6 337 let parent_link = ModuleParentLink(parent, name);
7453a54e 338 let def = Def::Trait(def_id);
9cc50fc6 339 let module_parent = self.new_module(parent_link, Some(def), false, is_public);
7453a54e 340 self.define(parent, name, TypeNS, (module_parent, sp));
1a4d82fc
JJ
341
342 // Add the names of all the items to the trait info.
7453a54e
SL
343 for item in items {
344 let item_def_id = self.ast_map.local_def_id(item.id);
345 let (def, ns) = match item.node {
346 hir::ConstTraitItem(..) => (Def::AssociatedConst(item_def_id), ValueNS),
347 hir::MethodTraitItem(..) => (Def::Method(item_def_id), ValueNS),
348 hir::TypeTraitItem(..) => (Def::AssociatedTy(def_id, item_def_id), TypeNS),
349 };
1a4d82fc 350
7453a54e
SL
351 let modifiers = DefModifiers::PUBLIC; // NB: not DefModifiers::IMPORTABLE
352 self.define(module_parent, item.name, ns, (def, item.span, modifiers));
353
354 self.trait_item_map.insert((item.name, def_id), item_def_id);
1a4d82fc 355 }
1a4d82fc 356 }
1a4d82fc
JJ
357 }
358 }
359
360 // Constructs the reduced graph for one variant. Variants exist in the
361 // type and value namespaces.
362 fn build_reduced_graph_for_variant(&mut self,
363 variant: &Variant,
364 item_id: DefId,
9cc50fc6
SL
365 parent: Module<'b>,
366 variant_modifiers: DefModifiers) {
b039eaaf 367 let name = variant.node.name;
7453a54e 368 if variant.node.data.is_struct() {
b039eaaf
SL
369 // Not adding fields for variants as they are not accessed with a self receiver
370 let variant_def_id = self.ast_map.local_def_id(variant.node.data.id());
371 self.structs.insert(variant_def_id, Vec::new());
7453a54e
SL
372 }
373
374 // Variants are always treated as importable to allow them to be glob used.
375 // All variants are defined in both type and value namespaces as future-proofing.
376 let modifiers = DefModifiers::PUBLIC | DefModifiers::IMPORTABLE | variant_modifiers;
377 let def = Def::Variant(item_id, self.ast_map.local_def_id(variant.node.data.id()));
1a4d82fc 378
7453a54e
SL
379 self.define(parent, name, ValueNS, (def, variant.span, modifiers));
380 self.define(parent, name, TypeNS, (def, variant.span, modifiers));
1a4d82fc
JJ
381 }
382
1a4d82fc 383 /// Constructs the reduced graph for one foreign item.
c34b1796
AL
384 fn build_reduced_graph_for_foreign_item(&mut self,
385 foreign_item: &ForeignItem,
9cc50fc6 386 parent: Module<'b>) {
b039eaaf 387 let name = foreign_item.name;
e9174d1e 388 let is_public = foreign_item.vis == hir::Public;
d9579d0f
AL
389 let modifiers = if is_public {
390 DefModifiers::PUBLIC
391 } else {
392 DefModifiers::empty()
393 } | DefModifiers::IMPORTABLE;
1a4d82fc 394
c34b1796
AL
395 let def = match foreign_item.node {
396 ForeignItemFn(..) => {
7453a54e 397 Def::Fn(self.ast_map.local_def_id(foreign_item.id))
1a4d82fc
JJ
398 }
399 ForeignItemStatic(_, m) => {
7453a54e 400 Def::Static(self.ast_map.local_def_id(foreign_item.id), m)
1a4d82fc 401 }
c34b1796 402 };
7453a54e 403 self.define(parent, name, ValueNS, (def, foreign_item.span, modifiers));
1a4d82fc
JJ
404 }
405
54a0048b 406 fn build_reduced_graph_for_block(&mut self, block: &Block, parent: &mut Module<'b>) {
1a4d82fc
JJ
407 if self.block_needs_anonymous_module(block) {
408 let block_id = block.id;
409
92a42be0
SL
410 debug!("(building reduced graph for block) creating a new anonymous module for block \
411 {}",
1a4d82fc
JJ
412 block_id);
413
9cc50fc6
SL
414 let parent_link = BlockParentLink(parent, block_id);
415 let new_module = self.new_module(parent_link, None, false, false);
7453a54e 416 parent.module_children.borrow_mut().insert(block_id, new_module);
54a0048b 417 *parent = new_module;
1a4d82fc
JJ
418 }
419 }
420
54a0048b
SL
421 /// Builds the reduced graph for a single item in an external crate.
422 fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, xcdef: ChildItem) {
423 let def = match xcdef.def {
424 DlDef(def) => def,
425 _ => return,
426 };
427
428 if let Def::ForeignMod(def_id) = def {
429 // Foreign modules have no names. Recur and populate eagerly.
430 for child in self.session.cstore.item_children(def_id) {
431 self.build_reduced_graph_for_external_crate_def(parent, child);
432 }
433 return;
434 }
435
436 let name = xcdef.name;
437 let is_public = xcdef.vis == ty::Visibility::Public || parent.is_trait();
7453a54e
SL
438
439 let mut modifiers = DefModifiers::empty();
440 if is_public {
441 modifiers = modifiers | DefModifiers::PUBLIC;
442 }
54a0048b 443 if parent.is_normal() {
7453a54e
SL
444 modifiers = modifiers | DefModifiers::IMPORTABLE;
445 }
446
1a4d82fc 447 match def {
54a0048b 448 Def::Mod(_) | Def::ForeignMod(_) | Def::Enum(..) => {
7453a54e 449 debug!("(building reduced graph for external crate) building module {} {}",
54a0048b 450 name,
7453a54e 451 is_public);
54a0048b 452 let parent_link = ModuleParentLink(parent, name);
7453a54e 453 let module = self.new_module(parent_link, Some(def), true, is_public);
54a0048b 454 self.try_define(parent, name, TypeNS, (module, DUMMY_SP));
1a4d82fc 455 }
7453a54e 456 Def::Variant(_, variant_id) => {
54a0048b 457 debug!("(building reduced graph for external crate) building variant {}", name);
7453a54e
SL
458 // Variants are always treated as importable to allow them to be glob used.
459 // All variants are defined in both type and value namespaces as future-proofing.
92a42be0 460 let modifiers = DefModifiers::PUBLIC | DefModifiers::IMPORTABLE;
54a0048b
SL
461 self.try_define(parent, name, TypeNS, (def, DUMMY_SP, modifiers));
462 self.try_define(parent, name, ValueNS, (def, DUMMY_SP, modifiers));
7453a54e 463 if self.session.cstore.variant_kind(variant_id) == Some(VariantKind::Struct) {
92a42be0
SL
464 // Not adding fields for variants as they are not accessed with a self receiver
465 self.structs.insert(variant_id, Vec::new());
92a42be0
SL
466 }
467 }
7453a54e
SL
468 Def::Fn(..) |
469 Def::Static(..) |
470 Def::Const(..) |
471 Def::AssociatedConst(..) |
472 Def::Method(..) => {
92a42be0 473 debug!("(building reduced graph for external crate) building value (fn/static) {}",
54a0048b
SL
474 name);
475 self.try_define(parent, name, ValueNS, (def, DUMMY_SP, modifiers));
1a4d82fc 476 }
7453a54e 477 Def::Trait(def_id) => {
54a0048b 478 debug!("(building reduced graph for external crate) building type {}", name);
92a42be0
SL
479
480 // If this is a trait, add all the trait item names to the trait
481 // info.
1a4d82fc 482
92a42be0
SL
483 let trait_item_def_ids = self.session.cstore.trait_item_def_ids(def_id);
484 for trait_item_def in &trait_item_def_ids {
485 let trait_item_name =
486 self.session.cstore.item_name(trait_item_def.def_id());
487
488 debug!("(building reduced graph for external crate) ... adding trait item \
489 '{}'",
490 trait_item_name);
491
492 self.trait_item_map.insert((trait_item_name, def_id), trait_item_def.def_id());
92a42be0
SL
493 }
494
54a0048b 495 let parent_link = ModuleParentLink(parent, name);
9cc50fc6 496 let module = self.new_module(parent_link, Some(def), true, is_public);
54a0048b 497 self.try_define(parent, name, TypeNS, (module, DUMMY_SP));
92a42be0 498 }
54a0048b
SL
499 Def::TyAlias(..) | Def::AssociatedTy(..) => {
500 debug!("(building reduced graph for external crate) building type {}", name);
501 self.try_define(parent, name, TypeNS, (def, DUMMY_SP, modifiers));
92a42be0 502 }
7453a54e
SL
503 Def::Struct(def_id)
504 if self.session.cstore.tuple_struct_definition_if_ctor(def_id).is_none() => {
54a0048b
SL
505 debug!("(building reduced graph for external crate) building type and value for {}",
506 name);
507 self.try_define(parent, name, TypeNS, (def, DUMMY_SP, modifiers));
7453a54e
SL
508 if let Some(ctor_def_id) = self.session.cstore.struct_ctor_def_id(def_id) {
509 let def = Def::Struct(ctor_def_id);
54a0048b 510 self.try_define(parent, name, ValueNS, (def, DUMMY_SP, modifiers));
92a42be0
SL
511 }
512
513 // Record the def ID and fields of this struct.
7453a54e 514 let fields = self.session.cstore.struct_field_names(def_id);
92a42be0
SL
515 self.structs.insert(def_id, fields);
516 }
7453a54e
SL
517 Def::Struct(..) => {}
518 Def::Local(..) |
519 Def::PrimTy(..) |
520 Def::TyParam(..) |
521 Def::Upvar(..) |
522 Def::Label(..) |
523 Def::SelfTy(..) |
524 Def::Err => {
54a0048b 525 bug!("didn't expect `{:?}`", def);
92a42be0 526 }
1a4d82fc
JJ
527 }
528 }
529
1a4d82fc
JJ
530 /// Builds the reduced graph rooted at the 'use' directive for an external
531 /// crate.
9cc50fc6 532 fn build_reduced_graph_for_external_crate(&mut self, root: Module<'b>) {
92a42be0
SL
533 let root_cnum = root.def_id().unwrap().krate;
534 for child in self.session.cstore.crate_top_level_items(root_cnum) {
535 self.build_reduced_graph_for_external_crate_def(root, child);
536 }
1a4d82fc
JJ
537 }
538
54a0048b
SL
539 /// Ensures that the reduced graph rooted at the given external module
540 /// is built, building it if it is not.
541 pub fn populate_module_if_necessary(&mut self, module: Module<'b>) {
542 if module.populated.get() { return }
543 for child in self.session.cstore.item_children(module.def_id().unwrap()) {
544 self.build_reduced_graph_for_external_crate_def(module, child);
1a4d82fc 545 }
54a0048b 546 module.populated.set(true)
1a4d82fc
JJ
547 }
548}
549
92a42be0 550struct BuildReducedGraphVisitor<'a, 'b: 'a, 'tcx: 'b> {
54a0048b 551 resolver: &'a mut Resolver<'b, 'tcx>,
9cc50fc6 552 parent: Module<'b>,
1a4d82fc
JJ
553}
554
555impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
92a42be0 556 fn visit_nested_item(&mut self, item: hir::ItemId) {
54a0048b 557 self.visit_item(self.resolver.ast_map.expect_item(item.id))
92a42be0
SL
558 }
559
1a4d82fc 560 fn visit_item(&mut self, item: &Item) {
54a0048b
SL
561 let old_parent = self.parent;
562 self.resolver.build_reduced_graph_for_item(item, &mut self.parent);
92a42be0 563 intravisit::walk_item(self, item);
1a4d82fc
JJ
564 self.parent = old_parent;
565 }
566
567 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
54a0048b 568 self.resolver.build_reduced_graph_for_foreign_item(foreign_item, &self.parent);
1a4d82fc
JJ
569 }
570
1a4d82fc 571 fn visit_block(&mut self, block: &Block) {
54a0048b
SL
572 let old_parent = self.parent;
573 self.resolver.build_reduced_graph_for_block(block, &mut self.parent);
92a42be0 574 intravisit::walk_block(self, block);
1a4d82fc
JJ
575 self.parent = old_parent;
576 }
577}