Skip to content

Commit dea67eb

Browse files
committed
rustc_resolve: fix fallout of merging ast::ViewItem into ast::Item.
1 parent fcb3c32 commit dea67eb

File tree

3 files changed

+156
-178
lines changed

3 files changed

+156
-178
lines changed

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 131 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ use rustc::middle::subst::FnSpace;
3939
use syntax::ast::{Block, Crate};
4040
use syntax::ast::{DeclItem, DefId};
4141
use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic};
42-
use syntax::ast::{Item, ItemConst, ItemEnum, ItemFn};
42+
use syntax::ast::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn};
4343
use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
44-
use syntax::ast::{ItemStruct, ItemTrait, ItemTy};
44+
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
4545
use syntax::ast::{MethodImplItem, Name, NamedField, NodeId};
4646
use syntax::ast::{PathListIdent, PathListMod};
4747
use syntax::ast::{Public, SelfStatic};
@@ -50,8 +50,7 @@ use syntax::ast::StructVariantKind;
5050
use syntax::ast::TupleVariantKind;
5151
use syntax::ast::TyObjectSum;
5252
use syntax::ast::{TypeImplItem, UnnamedField};
53-
use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
54-
use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
53+
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
5554
use syntax::ast::{Visibility};
5655
use syntax::ast::TyPath;
5756
use syntax::ast;
@@ -238,11 +237,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
238237
}
239238

240239
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 {
243-
return true;
244-
}
245-
246240
// Check each statement.
247241
for statement in block.stmts.iter() {
248242
match statement.node {
@@ -262,7 +256,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
262256
}
263257
}
264258

265-
// If we found neither view items nor items, we don't need to create
259+
// If we found no items, we don't need to create
266260
// an anonymous module.
267261

268262
return false;
@@ -280,6 +274,133 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
280274
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
281275

282276
match item.node {
277+
ItemUse(ref view_path) => {
278+
// Extract and intern the module part of the path. For
279+
// globs and lists, the path is found directly in the AST;
280+
// for simple paths we have to munge the path a little.
281+
let module_path = match view_path.node {
282+
ViewPathSimple(_, ref full_path) => {
283+
full_path.segments
284+
.init()
285+
.iter().map(|ident| ident.identifier.name)
286+
.collect()
287+
}
288+
289+
ViewPathGlob(ref module_ident_path) |
290+
ViewPathList(ref module_ident_path, _) => {
291+
module_ident_path.segments
292+
.iter().map(|ident| ident.identifier.name).collect()
293+
}
294+
};
295+
296+
// Build up the import directives.
297+
let shadowable = item.attrs.iter().any(|attr| {
298+
attr.name() == token::get_name(special_idents::prelude_import.name)
299+
});
300+
let shadowable = if shadowable {
301+
Shadowable::Always
302+
} else {
303+
Shadowable::Never
304+
};
305+
306+
match view_path.node {
307+
ViewPathSimple(binding, ref full_path) => {
308+
let source_name =
309+
full_path.segments.last().unwrap().identifier.name;
310+
if token::get_name(source_name).get() == "mod" ||
311+
token::get_name(source_name).get() == "self" {
312+
self.resolve_error(view_path.span,
313+
"`self` imports are only allowed within a { } list");
314+
}
315+
316+
let subclass = SingleImport(binding.name,
317+
source_name);
318+
self.build_import_directive(&**parent,
319+
module_path,
320+
subclass,
321+
view_path.span,
322+
item.id,
323+
is_public,
324+
shadowable);
325+
}
326+
ViewPathList(_, ref source_items) => {
327+
// Make sure there's at most one `mod` import in the list.
328+
let mod_spans = source_items.iter().filter_map(|item| match item.node {
329+
PathListMod { .. } => Some(item.span),
330+
_ => None
331+
}).collect::<Vec<Span>>();
332+
if mod_spans.len() > 1 {
333+
self.resolve_error(mod_spans[0],
334+
"`self` import can only appear once in the list");
335+
for other_span in mod_spans.iter().skip(1) {
336+
self.session.span_note(*other_span,
337+
"another `self` import appears here");
338+
}
339+
}
340+
341+
for source_item in source_items.iter() {
342+
let (module_path, name) = match source_item.node {
343+
PathListIdent { name, .. } =>
344+
(module_path.clone(), name.name),
345+
PathListMod { .. } => {
346+
let name = match module_path.last() {
347+
Some(name) => *name,
348+
None => {
349+
self.resolve_error(source_item.span,
350+
"`self` import can only appear in an import list \
351+
with a non-empty prefix");
352+
continue;
353+
}
354+
};
355+
let module_path = module_path.init();
356+
(module_path.to_vec(), name)
357+
}
358+
};
359+
self.build_import_directive(
360+
&**parent,
361+
module_path,
362+
SingleImport(name, name),
363+
source_item.span,
364+
source_item.node.id(),
365+
is_public,
366+
shadowable);
367+
}
368+
}
369+
ViewPathGlob(_) => {
370+
self.build_import_directive(&**parent,
371+
module_path,
372+
GlobImport,
373+
view_path.span,
374+
item.id,
375+
is_public,
376+
shadowable);
377+
}
378+
}
379+
parent.clone()
380+
}
381+
382+
ItemExternCrate(_) => {
383+
// n.b. we don't need to look at the path option here, because cstore already did
384+
for &crate_id in self.session.cstore
385+
.find_extern_mod_stmt_cnum(item.id).iter() {
386+
let def_id = DefId { krate: crate_id, node: 0 };
387+
self.external_exports.insert(def_id);
388+
let parent_link = ModuleParentLink(parent.downgrade(), name);
389+
let external_module = Rc::new(Module::new(parent_link,
390+
Some(def_id),
391+
NormalModuleKind,
392+
false,
393+
true));
394+
debug!("(build reduced graph for item) found extern `{}`",
395+
self.module_to_string(&*external_module));
396+
self.check_for_conflicts_between_external_crates(&**parent, name, sp);
397+
parent.external_module_children.borrow_mut()
398+
.insert(name, external_module.clone());
399+
self.build_reduced_graph_for_external_crate(&external_module);
400+
}
401+
parent.clone()
402+
}
403+
283404
ItemMod(..) => {
284405
let name_bindings = self.add_child(name, parent, ForbidDuplicateModules, sp);
285406

@@ -642,145 +763,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
642763
variant.span, PUBLIC | IMPORTABLE);
643764
}
644765

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, _) => {
655-
full_path.segments
656-
.init()
657-
.iter().map(|ident| ident.identifier.name)
658-
.collect()
659-
}
660-
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()
665-
}
666-
};
667-
668-
// Build up the import directives.
669-
let is_public = view_item.vis == ast::Public;
670-
let shadowable =
671-
view_item.attrs
672-
.iter()
673-
.any(|attr| {
674-
attr.name() == token::get_name(
675-
special_idents::prelude_import.name)
676-
});
677-
let shadowable = if shadowable {
678-
Shadowable::Always
679-
} else {
680-
Shadowable::Never
681-
};
682-
683-
match view_path.node {
684-
ViewPathSimple(binding, ref full_path, id) => {
685-
let source_name =
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");
691-
}
692-
693-
let subclass = SingleImport(binding.name,
694-
source_name);
695-
self.build_import_directive(&**parent,
696-
module_path,
697-
subclass,
698-
view_path.span,
699-
id,
700-
is_public,
701-
shadowable);
702-
}
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),
707-
_ => None
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");
715-
}
716-
}
717-
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() {
724-
Some(name) => *name,
725-
None => {
726-
self.resolve_error(source_item.span,
727-
"`self` import can only appear in an import list \
728-
with a non-empty prefix");
729-
continue;
730-
}
731-
};
732-
let module_path = module_path.init();
733-
(module_path.to_vec(), name)
734-
}
735-
};
736-
self.build_import_directive(
737-
&**parent,
738-
module_path,
739-
SingleImport(name, name),
740-
source_item.span,
741-
source_item.node.id(),
742-
is_public,
743-
shadowable);
744-
}
745-
}
746-
ViewPathGlob(_, id) => {
747-
self.build_import_directive(&**parent,
748-
module_path,
749-
GlobImport,
750-
view_path.span,
751-
id,
752-
is_public,
753-
shadowable);
754-
}
755-
}
756-
}
757-
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,
766-
Some(def_id),
767-
NormalModuleKind,
768-
false,
769-
true));
770-
debug!("(build reduced graph for item) found extern `{}`",
771-
self.module_to_string(&*external_module));
772-
self.check_for_conflicts_between_external_crates(
773-
&**parent,
774-
name.name,
775-
view_item.span);
776-
parent.external_module_children.borrow_mut()
777-
.insert(name.name, external_module.clone());
778-
self.build_reduced_graph_for_external_crate(&external_module);
779-
}
780-
}
781-
}
782-
}
783-
784766
/// Constructs the reduced graph for one foreign item.
785767
fn build_reduced_graph_for_foreign_item<F>(&mut self,
786768
foreign_item: &ForeignItem,
@@ -1261,10 +1243,6 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
12611243
})
12621244
}
12631245

1264-
fn visit_view_item(&mut self, view_item: &ViewItem) {
1265-
self.builder.build_reduced_graph_for_view_item(view_item, &self.parent);
1266-
}
1267-
12681246
fn visit_block(&mut self, block: &Block) {
12691247
let np = self.builder.build_reduced_graph_for_block(block, &self.parent);
12701248
let old_parent = replace(&mut self.parent, np);

0 commit comments

Comments
 (0)