Merge remote-tracking branch 'rust-lang/master'

Conflicts:
	mk/tests.mk
	src/liballoc/arc.rs
	src/liballoc/boxed.rs
	src/liballoc/rc.rs
	src/libcollections/bit.rs
	src/libcollections/btree/map.rs
	src/libcollections/btree/set.rs
	src/libcollections/dlist.rs
	src/libcollections/ring_buf.rs
	src/libcollections/slice.rs
	src/libcollections/str.rs
	src/libcollections/string.rs
	src/libcollections/vec.rs
	src/libcollections/vec_map.rs
	src/libcore/any.rs
	src/libcore/array.rs
	src/libcore/borrow.rs
	src/libcore/error.rs
	src/libcore/fmt/mod.rs
	src/libcore/iter.rs
	src/libcore/marker.rs
	src/libcore/ops.rs
	src/libcore/result.rs
	src/libcore/slice.rs
	src/libcore/str/mod.rs
	src/libregex/lib.rs
	src/libregex/re.rs
	src/librustc/lint/builtin.rs
	src/libstd/collections/hash/map.rs
	src/libstd/collections/hash/set.rs
	src/libstd/sync/mpsc/mod.rs
	src/libstd/sync/mutex.rs
	src/libstd/sync/poison.rs
	src/libstd/sync/rwlock.rs
	src/libsyntax/feature_gate.rs
	src/libsyntax/test.rs
This commit is contained in:
Brian Anderson 2015-01-24 09:15:42 -08:00
commit 63fcbcf3ce
433 changed files with 7348 additions and 12011 deletions

View file

@ -39,9 +39,9 @@ use rustc::middle::subst::FnSpace;
use syntax::ast::{Block, Crate};
use syntax::ast::{DeclItem, DefId};
use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic};
use syntax::ast::{Item, ItemConst, ItemEnum, ItemFn};
use syntax::ast::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn};
use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
use syntax::ast::{ItemStruct, ItemTrait, ItemTy};
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
use syntax::ast::{MethodImplItem, Name, NamedField, NodeId};
use syntax::ast::{PathListIdent, PathListMod};
use syntax::ast::{Public, SelfStatic};
@ -50,8 +50,7 @@ use syntax::ast::StructVariantKind;
use syntax::ast::TupleVariantKind;
use syntax::ast::TyObjectSum;
use syntax::ast::{TypeImplItem, UnnamedField};
use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::ast::{Visibility};
use syntax::ast::TyPath;
use syntax::ast;
@ -238,11 +237,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
}
fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
// If the block has view items, we need an anonymous module.
if block.view_items.len() > 0 {
return true;
}
// Check each statement.
for statement in block.stmts.iter() {
match statement.node {
@ -262,7 +256,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
}
}
// If we found neither view items nor items, we don't need to create
// If we found no items, we don't need to create
// an anonymous module.
return false;
@ -280,6 +274,133 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
match item.node {
ItemUse(ref view_path) => {
// Extract and intern the module part of the path. For
// globs and lists, the path is found directly in the AST;
// for simple paths we have to munge the path a little.
let module_path = match view_path.node {
ViewPathSimple(_, ref full_path) => {
full_path.segments
.init()
.iter().map(|ident| ident.identifier.name)
.collect()
}
ViewPathGlob(ref module_ident_path) |
ViewPathList(ref module_ident_path, _) => {
module_ident_path.segments
.iter().map(|ident| ident.identifier.name).collect()
}
};
// Build up the import directives.
let shadowable = item.attrs.iter().any(|attr| {
attr.name() == token::get_name(special_idents::prelude_import.name)
});
let shadowable = if shadowable {
Shadowable::Always
} else {
Shadowable::Never
};
match view_path.node {
ViewPathSimple(binding, ref full_path) => {
let source_name =
full_path.segments.last().unwrap().identifier.name;
if token::get_name(source_name).get() == "mod" ||
token::get_name(source_name).get() == "self" {
self.resolve_error(view_path.span,
"`self` imports are only allowed within a { } list");
}
let subclass = SingleImport(binding.name,
source_name);
self.build_import_directive(&**parent,
module_path,
subclass,
view_path.span,
item.id,
is_public,
shadowable);
}
ViewPathList(_, ref source_items) => {
// Make sure there's at most one `mod` import in the list.
let mod_spans = source_items.iter().filter_map(|item| match item.node {
PathListMod { .. } => Some(item.span),
_ => None
}).collect::<Vec<Span>>();
if mod_spans.len() > 1 {
self.resolve_error(mod_spans[0],
"`self` import can only appear once in the list");
for other_span in mod_spans.iter().skip(1) {
self.session.span_note(*other_span,
"another `self` import appears here");
}
}
for source_item in source_items.iter() {
let (module_path, name) = match source_item.node {
PathListIdent { name, .. } =>
(module_path.clone(), name.name),
PathListMod { .. } => {
let name = match module_path.last() {
Some(name) => *name,
None => {
self.resolve_error(source_item.span,
"`self` import can only appear in an import list \
with a non-empty prefix");
continue;
}
};
let module_path = module_path.init();
(module_path.to_vec(), name)
}
};
self.build_import_directive(
&**parent,
module_path,
SingleImport(name, name),
source_item.span,
source_item.node.id(),
is_public,
shadowable);
}
}
ViewPathGlob(_) => {
self.build_import_directive(&**parent,
module_path,
GlobImport,
view_path.span,
item.id,
is_public,
shadowable);
}
}
parent.clone()
}
ItemExternCrate(_) => {
// n.b. we don't need to look at the path option here, because cstore already did
for &crate_id in self.session.cstore
.find_extern_mod_stmt_cnum(item.id).iter() {
let def_id = DefId { krate: crate_id, node: 0 };
self.external_exports.insert(def_id);
let parent_link = ModuleParentLink(parent.downgrade(), name);
let external_module = Rc::new(Module::new(parent_link,
Some(def_id),
NormalModuleKind,
false,
true));
debug!("(build reduced graph for item) found extern `{}`",
self.module_to_string(&*external_module));
self.check_for_conflicts_between_external_crates(&**parent, name, sp);
parent.external_module_children.borrow_mut()
.insert(name, external_module.clone());
self.build_reduced_graph_for_external_crate(&external_module);
}
parent.clone()
}
ItemMod(..) => {
let name_bindings = self.add_child(name, parent, ForbidDuplicateModules, sp);
@ -650,145 +771,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
variant.span, PUBLIC | IMPORTABLE);
}
/// Constructs the reduced graph for one 'view item'. View items consist
/// of imports and use directives.
fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem, parent: &Rc<Module>) {
match view_item.node {
ViewItemUse(ref view_path) => {
// Extract and intern the module part of the path. For
// globs and lists, the path is found directly in the AST;
// for simple paths we have to munge the path a little.
let module_path = match view_path.node {
ViewPathSimple(_, ref full_path, _) => {
full_path.segments
.init()
.iter().map(|ident| ident.identifier.name)
.collect()
}
ViewPathGlob(ref module_ident_path, _) |
ViewPathList(ref module_ident_path, _, _) => {
module_ident_path.segments
.iter().map(|ident| ident.identifier.name).collect()
}
};
// Build up the import directives.
let is_public = view_item.vis == ast::Public;
let shadowable =
view_item.attrs
.iter()
.any(|attr| {
attr.name() == token::get_name(
special_idents::prelude_import.name)
});
let shadowable = if shadowable {
Shadowable::Always
} else {
Shadowable::Never
};
match view_path.node {
ViewPathSimple(binding, ref full_path, id) => {
let source_name =
full_path.segments.last().unwrap().identifier.name;
if token::get_name(source_name).get() == "mod" ||
token::get_name(source_name).get() == "self" {
self.resolve_error(view_path.span,
"`self` imports are only allowed within a { } list");
}
let subclass = SingleImport(binding.name,
source_name);
self.build_import_directive(&**parent,
module_path,
subclass,
view_path.span,
id,
is_public,
shadowable);
}
ViewPathList(_, ref source_items, _) => {
// Make sure there's at most one `mod` import in the list.
let mod_spans = source_items.iter().filter_map(|item| match item.node {
PathListMod { .. } => Some(item.span),
_ => None
}).collect::<Vec<Span>>();
if mod_spans.len() > 1 {
self.resolve_error(mod_spans[0],
"`self` import can only appear once in the list");
for other_span in mod_spans.iter().skip(1) {
self.session.span_note(*other_span,
"another `self` import appears here");
}
}
for source_item in source_items.iter() {
let (module_path, name) = match source_item.node {
PathListIdent { name, .. } =>
(module_path.clone(), name.name),
PathListMod { .. } => {
let name = match module_path.last() {
Some(name) => *name,
None => {
self.resolve_error(source_item.span,
"`self` import can only appear in an import list \
with a non-empty prefix");
continue;
}
};
let module_path = module_path.init();
(module_path.to_vec(), name)
}
};
self.build_import_directive(
&**parent,
module_path,
SingleImport(name, name),
source_item.span,
source_item.node.id(),
is_public,
shadowable);
}
}
ViewPathGlob(_, id) => {
self.build_import_directive(&**parent,
module_path,
GlobImport,
view_path.span,
id,
is_public,
shadowable);
}
}
}
ViewItemExternCrate(name, _, node_id) => {
// n.b. we don't need to look at the path option here, because cstore already did
for &crate_id in self.session.cstore
.find_extern_mod_stmt_cnum(node_id).iter() {
let def_id = DefId { krate: crate_id, node: 0 };
self.external_exports.insert(def_id);
let parent_link = ModuleParentLink(parent.downgrade(), name.name);
let external_module = Rc::new(Module::new(parent_link,
Some(def_id),
NormalModuleKind,
false,
true));
debug!("(build reduced graph for item) found extern `{}`",
self.module_to_string(&*external_module));
self.check_for_conflicts_between_external_crates(
&**parent,
name.name,
view_item.span);
parent.external_module_children.borrow_mut()
.insert(name.name, external_module.clone());
self.build_reduced_graph_for_external_crate(&external_module);
}
}
}
}
/// Constructs the reduced graph for one foreign item.
fn build_reduced_graph_for_foreign_item<F>(&mut self,
foreign_item: &ForeignItem,
@ -1270,10 +1252,6 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
})
}
fn visit_view_item(&mut self, view_item: &ViewItem) {
self.builder.build_reduced_graph_for_view_item(view_item, &self.parent);
}
fn visit_block(&mut self, block: &Block) {
let np = self.builder.build_reduced_graph_for_block(block, &self.parent);
let old_parent = replace(&mut self.parent, np);

View file

@ -25,7 +25,6 @@ use Namespace::{TypeNS, ValueNS};
use rustc::lint;
use rustc::middle::privacy::{DependsOn, LastImport, Used, Unused};
use syntax::ast;
use syntax::ast::{ViewItem, ViewItemExternCrate, ViewItemUse};
use syntax::ast::{ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::codemap::{Span, DUMMY_SP};
use syntax::visit::{self, Visitor};
@ -109,53 +108,54 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
}
impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
fn visit_view_item(&mut self, vi: &ViewItem) {
fn visit_item(&mut self, item: &ast::Item) {
// Ignore is_public import statements because there's no way to be sure
// whether they're used or not. Also ignore imports with a dummy span
// because this means that they were generated in some fashion by the
// compiler and we don't need to consider them.
if vi.vis == ast::Public || vi.span == DUMMY_SP {
visit::walk_view_item(self, vi);
if item.vis == ast::Public || item.span == DUMMY_SP {
visit::walk_item(self, item);
return;
}
match vi.node {
ViewItemExternCrate(_, _, id) => {
if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) {
match item.node {
ast::ItemExternCrate(_) => {
if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) {
if !self.used_crates.contains(&crate_num) {
self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
id,
vi.span,
item.id,
item.span,
"unused extern crate".to_string());
}
}
},
ViewItemUse(ref p) => {
ast::ItemUse(ref p) => {
match p.node {
ViewPathSimple(_, _, id) => {
self.finalize_import(id, p.span)
ViewPathSimple(_, _) => {
self.finalize_import(item.id, p.span)
}
ViewPathList(_, ref list, _) => {
ViewPathList(_, ref list) => {
for i in list.iter() {
self.finalize_import(i.node.id(), i.span);
}
}
ViewPathGlob(_, id) => {
if !self.used_imports.contains(&(id, TypeNS)) &&
!self.used_imports.contains(&(id, ValueNS)) {
ViewPathGlob(_) => {
if !self.used_imports.contains(&(item.id, TypeNS)) &&
!self.used_imports.contains(&(item.id, ValueNS)) {
self.session
.add_lint(lint::builtin::UNUSED_IMPORTS,
id,
item.id,
p.span,
"unused import".to_string());
}
}
}
}
_ => {}
}
visit::walk_view_item(self, vi);
visit::walk_item(self, item);
}
}

View file

@ -0,0 +1,29 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(non_snake_case)]
register_diagnostics! {
E0154,
E0157,
E0153,
E0251, // a named type or value has already been imported in this module
E0252, // a named type or value has already been imported in this module
E0253, // not directly importable
E0254, // import conflicts with imported crate in this module
E0255, // import conflicts with value in this module
E0256, // import conflicts with type in this module
E0257, // inherent implementations are only allowen on types defined in the current module
E0258, // import conflicts with existing submodule
E0259, // an extern crate has already been imported into this module
E0260 // name conflicts with an external crate that has been imported into this module
}
__build_diagnostic_array! { DIAGNOSTICS }

View file

@ -26,6 +26,7 @@
#![feature(core)]
#![feature(rustc_private)]
#![feature(std_misc)]
#![feature(hash)]
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
@ -70,10 +71,10 @@ use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField};
use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
use syntax::ast::{ExprPath, ExprQPath, ExprStruct, FnDecl};
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemFn};
use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, Local, LOCAL_CRATE};
use syntax::ast::{MethodImplItem, Mod, Name, NodeId};
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
use syntax::ast::{Local, MethodImplItem, Mod, Name, NodeId};
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
use syntax::ast::{PatRange, PatStruct, Path};
use syntax::ast::{PolyTraitRef, PrimTy, SelfExplicit};
@ -102,6 +103,10 @@ use std::mem::replace;
use std::rc::{Rc, Weak};
use std::uint;
// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;
mod check_unused;
mod record_exports;
mod build_reduced_graph;
@ -541,7 +546,7 @@ impl Module {
}
}
impl fmt::Show for Module {
impl fmt::Debug for Module {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}, kind: {:?}, {}",
self.def_id,
@ -1144,7 +1149,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
fn get_trait_name(&self, did: DefId) -> Name {
if did.krate == LOCAL_CRATE {
if did.krate == ast::LOCAL_CRATE {
self.ast_map.expect_item(did.node).ident.name
} else {
csearch::get_trait_name(&self.session.cstore, did)
@ -1723,7 +1728,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
in this module",
namespace_name,
token::get_name(name).get());
self.session.span_err(import_directive.span, msg.as_slice());
span_err!(self.session, import_directive.span, E0251, "{}", msg.as_slice());
} else {
let target = Target::new(containing_module.clone(),
name_bindings.clone(),
@ -1753,10 +1758,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
import_span: Span,
name: Name,
namespace: Namespace) {
if self.session.features.borrow().import_shadowing {
return
}
debug!("check_for_conflicting_import: {}; target exists: {}",
token::get_name(name).get(),
target.is_some());
@ -1770,7 +1771,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ValueNS => "value",
},
token::get_name(name).get());
self.session.span_err(import_span, &msg[]);
span_err!(self.session, import_span, E0252, "{}", &msg[]);
}
Some(_) | None => {}
}
@ -1785,7 +1786,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
let msg = format!("`{}` is not directly importable",
token::get_name(name));
self.session.span_err(import_span, &msg[]);
span_err!(self.session, import_span, E0253, "{}", &msg[]);
}
}
@ -1796,10 +1797,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&ImportResolution,
import_span: Span,
name: Name) {
if self.session.features.borrow().import_shadowing {
return
}
// First, check for conflicts between imports and `extern crate`s.
if module.external_module_children
.borrow()
@ -1810,7 +1807,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
crate in this module \
(maybe you meant `use {0}::*`?)",
token::get_name(name).get());
self.session.span_err(import_span, &msg[]);
span_err!(self.session, import_span, E0254, "{}", &msg[]);
}
Some(_) | None => {}
}
@ -1832,7 +1829,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let msg = format!("import `{}` conflicts with value \
in this module",
token::get_name(name).get());
self.session.span_err(import_span, &msg[]);
span_err!(self.session, import_span, E0255, "{}", &msg[]);
if let Some(span) = value.value_span {
self.session.span_note(span,
"conflicting value here");
@ -1850,7 +1847,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let msg = format!("import `{}` conflicts with type in \
this module",
token::get_name(name).get());
self.session.span_err(import_span, &msg[]);
span_err!(self.session, import_span, E0256, "{}", &msg[]);
if let Some(span) = ty.type_span {
self.session.span_note(span,
"note conflicting type here")
@ -1863,7 +1860,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let msg = format!("inherent implementations \
are only allowed on types \
defined in the current module");
self.session.span_err(span, &msg[]);
span_err!(self.session, span, E0257, "{}", &msg[]);
self.session.span_note(import_span,
"import from other module here")
}
@ -1872,7 +1869,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let msg = format!("import `{}` conflicts with existing \
submodule",
token::get_name(name).get());
self.session.span_err(import_span, &msg[]);
span_err!(self.session, import_span, E0258, "{}", &msg[]);
if let Some(span) = ty.type_span {
self.session.span_note(span,
"note conflicting module here")
@ -1893,16 +1890,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
module: &Module,
name: Name,
span: Span) {
if self.session.features.borrow().import_shadowing {
return
}
if module.external_module_children.borrow().contains_key(&name) {
self.session
.span_err(span,
&format!("an external crate named `{}` has already \
span_err!(self.session, span, E0259,
"an external crate named `{}` has already \
been imported into this module",
token::get_name(name).get())[]);
token::get_name(name).get());
}
}
@ -1911,17 +1903,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
module: &Module,
name: Name,
span: Span) {
if self.session.features.borrow().import_shadowing {
return
}
if module.external_module_children.borrow().contains_key(&name) {
self.session
.span_err(span,
&format!("the name `{}` conflicts with an external \
span_err!(self.session, span, E0260,
"the name `{}` conflicts with an external \
crate that has been imported into this \
module",
token::get_name(name).get())[]);
token::get_name(name).get());
}
}
@ -1970,7 +1957,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let module_name = self.module_to_string(&*search_module);
let mut span = span;
let msg = if "???" == &module_name[] {
span.hi = span.lo + Pos::from_uint(segment_name.get().len());
span.hi = span.lo + Pos::from_usize(segment_name.get().len());
match search_parent_externals(name,
&self.current_module) {
@ -2088,8 +2075,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let msg = format!("Could not find `{}` in `{}`",
// idx +- 1 to account for the
// colons on either side
&mpath[(idx + 1)..],
&mpath[..(idx - 1)]);
&mpath[idx + 1..],
&mpath[..idx - 1]);
return Failed(Some((span, msg)));
},
None => {
@ -2765,7 +2752,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
for (i, rib) in ribs.iter().enumerate().rev() {
match rib.bindings.get(&name).cloned() {
Some(def_like) => {
return self.upvarify(&ribs[(i + 1)..], def_like, span);
return self.upvarify(&ribs[i + 1..], def_like, span);
}
None => {
// Continue.
@ -2987,9 +2974,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
});
}
ItemMac(..) => {
ItemExternCrate(_) | ItemUse(_) | ItemMac(..) => {
// do nothing, these are just around to be encoded
}
}
}
}
@ -3530,6 +3517,26 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
// Check for imports appearing after non-item statements.
let mut found_non_item = false;
for statement in block.stmts.iter() {
if let ast::StmtDecl(ref declaration, _) = statement.node {
if let ast::DeclItem(ref i) = declaration.node {
match i.node {
ItemExternCrate(_) | ItemUse(_) if found_non_item => {
span_err!(self.session, i.span, E0154,
"imports are not allowed after non-item statements");
}
_ => {}
}
} else {
found_non_item = true
}
} else {
found_non_item = true;
}
}
// Descend into the block.
visit::walk_block(self, block);