Skip to content

Commit f83a972

Browse files
committed
rustc_resolve: fix fallout of merging ast::ViewItem into ast::Item.
1 parent 7dbefce commit f83a972

File tree

3 files changed

+156
-178
lines changed

3 files changed

+156
-178
lines changed

src/librustc_resolve/build_reduced_graph.rs

+131-153
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

@@ -650,145 +771,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
650771
variant.span, PUBLIC | IMPORTABLE);
651772
}
652773

653-
/// Constructs the reduced graph for one 'view item'. View items consist
654-
/// of imports and use directives.
655-
fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem, parent: &Rc<Module>) {
656-
match view_item.node {
657-
ViewItemUse(ref view_path) => {
658-
// Extract and intern the module part of the path. For
659-
// globs and lists, the path is found directly in the AST;
660-
// for simple paths we have to munge the path a little.
661-
let module_path = match view_path.node {
662-
ViewPathSimple(_, ref full_path, _) => {
663-
full_path.segments
664-
.init()
665-
.iter().map(|ident| ident.identifier.name)
666-
.collect()
667-
}
668-
669-
ViewPathGlob(ref module_ident_path, _) |
670-
ViewPathList(ref module_ident_path, _, _) => {
671-
module_ident_path.segments
672-
.iter().map(|ident| ident.identifier.name).collect()
673-
}
674-
};
675-
676-
// Build up the import directives.
677-
let is_public = view_item.vis == ast::Public;
678-
let shadowable =
679-
view_item.attrs
680-
.iter()
681-
.any(|attr| {
682-
attr.name() == token::get_name(
683-
special_idents::prelude_import.name)
684-
});
685-
let shadowable = if shadowable {
686-
Shadowable::Always
687-
} else {
688-
Shadowable::Never
689-
};
690-
691-
match view_path.node {
692-
ViewPathSimple(binding, ref full_path, id) => {
693-
let source_name =
694-
full_path.segments.last().unwrap().identifier.name;
695-
if token::get_name(source_name).get() == "mod" ||
696-
token::get_name(source_name).get() == "self" {
697-
self.resolve_error(view_path.span,
698-
"`self` imports are only allowed within a { } list");
699-
}
700-
701-
let subclass = SingleImport(binding.name,
702-
source_name);
703-
self.build_import_directive(&**parent,
704-
module_path,
705-
subclass,
706-
view_path.span,
707-
id,
708-
is_public,
709-
shadowable);
710-
}
711-
ViewPathList(_, ref source_items, _) => {
712-
// Make sure there's at most one `mod` import in the list.
713-
let mod_spans = source_items.iter().filter_map(|item| match item.node {
714-
PathListMod { .. } => Some(item.span),
715-
_ => None
716-
}).collect::<Vec<Span>>();
717-
if mod_spans.len() > 1 {
718-
self.resolve_error(mod_spans[0],
719-
"`self` import can only appear once in the list");
720-
for other_span in mod_spans.iter().skip(1) {
721-
self.session.span_note(*other_span,
722-
"another `self` import appears here");
723-
}
724-
}
725-
726-
for source_item in source_items.iter() {
727-
let (module_path, name) = match source_item.node {
728-
PathListIdent { name, .. } =>
729-
(module_path.clone(), name.name),
730-
PathListMod { .. } => {
731-
let name = match module_path.last() {
732-
Some(name) => *name,
733-
None => {
734-
self.resolve_error(source_item.span,
735-
"`self` import can only appear in an import list \
736-
with a non-empty prefix");
737-
continue;
738-
}
739-
};
740-
let module_path = module_path.init();
741-
(module_path.to_vec(), name)
742-
}
743-
};
744-
self.build_import_directive(
745-
&**parent,
746-
module_path,
747-
SingleImport(name, name),
748-
source_item.span,
749-
source_item.node.id(),
750-
is_public,
751-
shadowable);
752-
}
753-
}
754-
ViewPathGlob(_, id) => {
755-
self.build_import_directive(&**parent,
756-
module_path,
757-
GlobImport,
758-
view_path.span,
759-
id,
760-
is_public,
761-
shadowable);
762-
}
763-
}
764-
}
765-
766-
ViewItemExternCrate(name, _, node_id) => {
767-
// n.b. we don't need to look at the path option here, because cstore already did
768-
for &crate_id in self.session.cstore
769-
.find_extern_mod_stmt_cnum(node_id).iter() {
770-
let def_id = DefId { krate: crate_id, node: 0 };
771-
self.external_exports.insert(def_id);
772-
let parent_link = ModuleParentLink(parent.downgrade(), name.name);
773-
let external_module = Rc::new(Module::new(parent_link,
774-
Some(def_id),
775-
NormalModuleKind,
776-
false,
777-
true));
778-
debug!("(build reduced graph for item) found extern `{}`",
779-
self.module_to_string(&*external_module));
780-
self.check_for_conflicts_between_external_crates(
781-
&**parent,
782-
name.name,
783-
view_item.span);
784-
parent.external_module_children.borrow_mut()
785-
.insert(name.name, external_module.clone());
786-
self.build_reduced_graph_for_external_crate(&external_module);
787-
}
788-
}
789-
}
790-
}
791-
792774
/// Constructs the reduced graph for one foreign item.
793775
fn build_reduced_graph_for_foreign_item<F>(&mut self,
794776
foreign_item: &ForeignItem,
@@ -1270,10 +1252,6 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
12701252
})
12711253
}
12721254

1273-
fn visit_view_item(&mut self, view_item: &ViewItem) {
1274-
self.builder.build_reduced_graph_for_view_item(view_item, &self.parent);
1275-
}
1276-
12771255
fn visit_block(&mut self, block: &Block) {
12781256
let np = self.builder.build_reduced_graph_for_block(block, &self.parent);
12791257
let old_parent = replace(&mut self.parent, np);

0 commit comments

Comments
 (0)