about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-21 11:56:00 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-21 11:56:00 -0800
commitdf1cddf20a2a4ece854e5d8592ad3155a3313fd2 (patch)
tree50bdd6498e1378cbeb48e80e35157152920e9c56 /src
parent886c6f3534e6f03916eeff2ea8b235e85dd04b42 (diff)
parent2d17a33878f1af0aa500a4e1ff6aa5c8689ab249 (diff)
downloadrust-df1cddf20a2a4ece854e5d8592ad3155a3313fd2.tar.gz
rust-df1cddf20a2a4ece854e5d8592ad3155a3313fd2.zip
rollup merge of #20179: eddyb/blind-items
Conflicts:
	src/librustc/diagnostics.rs
	src/librustdoc/clean/mod.rs
	src/librustdoc/html/format.rs
	src/libsyntax/parse/parser.rs
Diffstat (limited to 'src')
-rw-r--r--src/doc/reference.md32
-rw-r--r--src/librustc/diagnostics.rs3
-rw-r--r--src/librustc/lint/builtin.rs37
-rw-r--r--src/librustc/lint/context.rs8
-rw-r--r--src/librustc/lint/mod.rs1
-rw-r--r--src/librustc/metadata/creader.rs56
-rw-r--r--src/librustc/metadata/encoder.rs4
-rw-r--r--src/librustc/middle/astencode.rs2
-rw-r--r--src/librustc/middle/reachable.rs1
-rw-r--r--src/librustc/middle/resolve_lifetime.rs2
-rw-r--r--src/librustc/plugin/load.rs24
-rw-r--r--src/librustc_back/svh.rs14
-rw-r--r--src/librustc_driver/pretty.rs2
-rw-r--r--src/librustc_driver/test.rs1
-rw-r--r--src/librustc_privacy/lib.rs96
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs284
-rw-r--r--src/librustc_resolve/check_unused.rs36
-rw-r--r--src/librustc_resolve/lib.rs50
-rw-r--r--src/librustc_trans/save/mod.rs217
-rw-r--r--src/librustc_trans/trans/monomorphize.rs1
-rw-r--r--src/librustc_typeck/collect.rs2
-rw-r--r--src/librustc_typeck/variance.rs4
-rw-r--r--src/librustdoc/clean/mod.rs189
-rw-r--r--src/librustdoc/doctree.rs22
-rw-r--r--src/librustdoc/html/format.rs2
-rw-r--r--src/librustdoc/html/item_type.rs40
-rw-r--r--src/librustdoc/html/render.rs88
-rw-r--r--src/librustdoc/html/static/main.css2
-rw-r--r--src/librustdoc/html/static/main.js5
-rw-r--r--src/librustdoc/passes.rs2
-rw-r--r--src/librustdoc/stability_summary.rs5
-rw-r--r--src/librustdoc/visit_ast.rs119
-rw-r--r--src/libsyntax/ast.rs49
-rw-r--r--src/libsyntax/ast_map/mod.rs25
-rw-r--r--src/libsyntax/ast_util.rs82
-rw-r--r--src/libsyntax/config.rs36
-rw-r--r--src/libsyntax/ext/build.rs77
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs2
-rw-r--r--src/libsyntax/ext/expand.rs5
-rw-r--r--src/libsyntax/ext/quote.rs28
-rw-r--r--src/libsyntax/feature_gate.rs29
-rw-r--r--src/libsyntax/fold.rs56
-rw-r--r--src/libsyntax/parse/mod.rs22
-rw-r--r--src/libsyntax/parse/parser.rs434
-rw-r--r--src/libsyntax/print/pprust.rs68
-rw-r--r--src/libsyntax/std_inject.rs46
-rw-r--r--src/libsyntax/test.rs69
-rw-r--r--src/libsyntax/util/parser_testing.rs7
-rw-r--r--src/libsyntax/visit.rs73
-rw-r--r--src/test/auxiliary/blind-item-mixed-crate-use-item-foo.rs (renamed from src/test/compile-fail/issue-9957.rs)8
-rw-r--r--src/test/auxiliary/blind-item-mixed-crate-use-item-foo2.rs13
-rw-r--r--src/test/compile-fail-fulldeps/gated-plugin.rs3
-rw-r--r--src/test/compile-fail/blind-item-block-item-shadow.rs20
-rw-r--r--src/test/compile-fail/blind-item-block-middle.rs18
-rw-r--r--src/test/compile-fail/blind-item-item-shadow.rs (renamed from src/test/compile-fail/view-items-at-top.rs)12
-rw-r--r--src/test/compile-fail/blind-item-local-shadow.rs20
-rw-r--r--src/test/compile-fail/unnecessary-private.rs3
-rw-r--r--src/test/pretty/issue-4264.pp4
-rw-r--r--src/test/run-pass/blind-item-mixed-crate-use-item.rs33
-rw-r--r--src/test/run-pass/blind-item-mixed-use-item.rs27
60 files changed, 1099 insertions, 1521 deletions
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 3cbfad52c05..9ec4708eb2f 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -803,8 +803,9 @@ Crates contain [items](#items), each of which may have some number of
 ## Items
 
 ```{.ebnf .gram}
-item : mod_item | fn_item | type_item | struct_item | enum_item
-     | static_item | trait_item | impl_item | extern_block ;
+item : extern_crate_decl | use_decl | mod_item | fn_item | type_item
+     | struct_item | enum_item | static_item | trait_item | impl_item
+     | extern_block ;
 ```
 
 An _item_ is a component of a crate; some module items can be defined in crate
@@ -818,6 +819,8 @@ execution, and may reside in read-only memory.
 
 There are several kinds of item:
 
+* [`extern crate` declarations](#extern-crate-declarations)
+* [`use` declarations](#use-declarations)
 * [modules](#modules)
 * [functions](#functions)
 * [type definitions](#type-definitions)
@@ -854,13 +857,10 @@ no notion of type abstraction: there are no first-class "forall" types.
 
 ```{.ebnf .gram}
 mod_item : "mod" ident ( ';' | '{' mod '}' );
-mod : [ view_item | item ] * ;
+mod : item * ;
 ```
 
-A module is a container for zero or more [view items](#view-items) and zero or
-more [items](#items). The view items manage the visibility of the items defined
-within the module, as well as the visibility of names from outside the module
-when referenced from inside the module.
+A module is a container for zero or more [items](#items).
 
 A _module item_ is a module, surrounded in braces, named, and prefixed with the
 keyword `mod`. A module item introduces a new, named module into the tree of
@@ -918,19 +918,6 @@ mod thread {
 }
 ```
 
-#### View items
-
-```{.ebnf .gram}
-view_item : extern_crate_decl | use_decl ;
-```
-
-A view item manages the namespace of a module. View items do not define new
-items, but rather, simply change other items' visibility. There are two
-kinds of view items:
-
-* [`extern crate` declarations](#extern-crate-declarations)
-* [`use` declarations](#use-declarations)
-
 ##### Extern crate declarations
 
 ```{.ebnf .gram}
@@ -2887,13 +2874,12 @@ Point3d {y: 0, z: 10, .. base};
 ### Block expressions
 
 ```{.ebnf .gram}
-block_expr : '{' [ view_item ] *
-                 [ stmt ';' | item ] *
+block_expr : '{' [ stmt ';' | item ] *
                  [ expr ] '}' ;
 ```
 
 A _block expression_ is similar to a module in terms of the declarations that
-are possible. Each block conceptually introduces a new namespace scope. View
+are possible. Each block conceptually introduces a new namespace scope. Use
 items can bring new names into scopes and declared items are in scope for only
 the block itself.
 
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index b48df36a679..04cfa16d2ed 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -77,6 +77,9 @@ register_diagnostics! {
     E0138,
     E0139,
     E0152,
+    E0153,
+    E0154,
+    E0157,
     E0158,
     E0161,
     E0162,
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 59b6520216d..fef1017b782 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -1202,17 +1202,17 @@ impl LintPass for UnusedImportBraces {
         lint_array!(UNUSED_IMPORT_BRACES)
     }
 
-    fn check_view_item(&mut self, cx: &Context, view_item: &ast::ViewItem) {
-        match view_item.node {
-            ast::ViewItemUse(ref view_path) => {
+    fn check_item(&mut self, cx: &Context, item: &ast::Item) {
+        match item.node {
+            ast::ItemUse(ref view_path) => {
                 match view_path.node {
-                    ast::ViewPathList(_, ref items, _) => {
+                    ast::ViewPathList(_, ref items) => {
                         if items.len() == 1 {
                             match items[0].node {
                                 ast::PathListIdent {ref name, ..} => {
                                     let m = format!("braces around {} is unnecessary",
                                                     token::get_ident(*name).get());
-                                    cx.span_lint(UNUSED_IMPORT_BRACES, view_item.span,
+                                    cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
                                                  &m[]);
                                 },
                                 _ => ()
@@ -1709,22 +1709,6 @@ impl LintPass for Stability {
         }
     }
 
-    fn check_view_item(&mut self, cx: &Context, item: &ast::ViewItem) {
-        // compiler-generated `extern crate` statements have a dummy span.
-        if item.span == DUMMY_SP { return }
-
-        let id = match item.node {
-            ast::ViewItemExternCrate(_, _, id) => id,
-            ast::ViewItemUse(..) => return,
-        };
-        let cnum = match cx.tcx.sess.cstore.find_extern_mod_stmt_cnum(id) {
-            Some(cnum) => cnum,
-            None => return,
-        };
-        let id = ast::DefId { krate: cnum, node: ast::CRATE_NODE_ID };
-        self.lint(cx, id, item.span);
-    }
-
     fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
         if self.is_internal(cx, e.span) { return; }
 
@@ -1776,6 +1760,17 @@ impl LintPass for Stability {
         if self.is_internal(cx, item.span) { return }
 
         match item.node {
+            ast::ItemExternCrate(_) => {
+                // compiler-generated `extern crate` items have a dummy span.
+                if item.span == DUMMY_SP { return }
+
+                let cnum = match cx.tcx.sess.cstore.find_extern_mod_stmt_cnum(item.id) {
+                    Some(cnum) => cnum,
+                    None => return,
+                };
+                let id = ast::DefId { krate: cnum, node: ast::CRATE_NODE_ID };
+                self.lint(cx, id, item.span);
+            }
             ast::ItemTrait(_, _, ref supertraits, _) => {
                 for t in supertraits.iter() {
                     if let ast::TraitTyParamBound(ref t, _) = *t {
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index fcb3200089b..4cbfcf7e91a 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -580,14 +580,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
         })
     }
 
-    fn visit_view_item(&mut self, i: &ast::ViewItem) {
-        self.with_lint_attrs(&i.attrs[], |cx| {
-            run_lints!(cx, check_view_item, i);
-            cx.visit_ids(|v| v.visit_view_item(i));
-            visit::walk_view_item(cx, i);
-        })
-    }
-
     fn visit_pat(&mut self, p: &ast::Pat) {
         run_lints!(self, check_pat, p);
         visit::walk_pat(self, p);
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 826a35e3bb5..a4a3f485af1 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -128,7 +128,6 @@ pub trait LintPass {
     fn check_crate(&mut self, _: &Context, _: &ast::Crate) { }
     fn check_ident(&mut self, _: &Context, _: Span, _: ast::Ident) { }
     fn check_mod(&mut self, _: &Context, _: &ast::Mod, _: Span, _: ast::NodeId) { }
-    fn check_view_item(&mut self, _: &Context, _: &ast::ViewItem) { }
     fn check_foreign_item(&mut self, _: &Context, _: &ast::ForeignItem) { }
     fn check_item(&mut self, _: &Context, _: &ast::Item) { }
     fn check_local(&mut self, _: &Context, _: &ast::Local) { }
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index 5de683f8a4f..7b71120ba64 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -40,10 +40,6 @@ pub struct CrateReader<'a> {
 }
 
 impl<'a, 'v> visit::Visitor<'v> for CrateReader<'a> {
-    fn visit_view_item(&mut self, a: &ast::ViewItem) {
-        self.process_view_item(a);
-        visit::walk_view_item(self, a);
-    }
     fn visit_item(&mut self, a: &ast::Item) {
         self.process_item(a);
         visit::walk_item(self, a);
@@ -64,9 +60,8 @@ fn dump_crates(cstore: &CStore) {
     })
 }
 
-fn should_link(i: &ast::ViewItem) -> bool {
+fn should_link(i: &ast::Item) -> bool {
     !attr::contains_name(&i.attrs[], "no_link")
-
 }
 
 struct CrateInfo {
@@ -181,29 +176,10 @@ impl<'a> CrateReader<'a> {
         }
     }
 
-    fn process_view_item(&mut self, i: &ast::ViewItem) {
-        if !should_link(i) {
-            return;
-        }
-
-        match self.extract_crate_info(i) {
-            Some(info) => {
-                let (cnum, _, _) = self.resolve_crate(&None,
-                                                      &info.ident[],
-                                                      &info.name[],
-                                                      None,
-                                                      i.span,
-                                                      PathKind::Crate);
-                self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
-            }
-            None => ()
-        }
-    }
-
-    fn extract_crate_info(&self, i: &ast::ViewItem) -> Option<CrateInfo> {
+    fn extract_crate_info(&self, i: &ast::Item) -> Option<CrateInfo> {
         match i.node {
-            ast::ViewItemExternCrate(ident, ref path_opt, id) => {
-                let ident = token::get_ident(ident);
+            ast::ItemExternCrate(ref path_opt) => {
+                let ident = token::get_ident(i.ident);
                 debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
                        ident, path_opt);
                 let name = match *path_opt {
@@ -218,7 +194,7 @@ impl<'a> CrateReader<'a> {
                 Some(CrateInfo {
                     ident: ident.get().to_string(),
                     name: name,
-                    id: id,
+                    id: i.id,
                     should_link: should_link(i),
                 })
             }
@@ -226,8 +202,26 @@ impl<'a> CrateReader<'a> {
         }
     }
 
-    fn process_item(&self, i: &ast::Item) {
+    fn process_item(&mut self, i: &ast::Item) {
         match i.node {
+            ast::ItemExternCrate(_) => {
+                if !should_link(i) {
+                    return;
+                }
+
+                match self.extract_crate_info(i) {
+                    Some(info) => {
+                        let (cnum, _, _) = self.resolve_crate(&None,
+                                                              &info.ident[],
+                                                              &info.name[],
+                                                              None,
+                                                              i.span,
+                                                              PathKind::Crate);
+                        self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
+                    }
+                    None => ()
+                }
+            }
             ast::ItemForeignMod(ref fm) => {
                 if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic {
                     return;
@@ -533,7 +527,7 @@ impl<'a> CrateReader<'a> {
 
 #[derive(Copy)]
 pub enum CrateOrString<'a> {
-    Krate(&'a ast::ViewItem),
+    Krate(&'a ast::Item),
     Str(&'a str)
 }
 
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 5cbe9750428..d0989160488 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -1456,8 +1456,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
             rbml_w.end_tag();
         }
       }
-      ast::ItemMac(..) => {
-        // macros are encoded separately
+      ast::ItemExternCrate(_) | ast::ItemUse(_) |ast::ItemMac(..) => {
+        // these are encoded separately
       }
     }
 }
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 9fc445d9cb6..537a2b3f545 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -332,8 +332,6 @@ impl Folder for NestedItemsDropper {
                 }
             }).collect();
             let blk_sans_items = P(ast::Block {
-                view_items: Vec::new(), // I don't know if we need the view_items
-                                        // here, but it doesn't break tests!
                 stmts: stmts_sans_items,
                 expr: expr,
                 id: id,
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index d6e652f16c6..b93cde4bf64 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -297,6 +297,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     // These are normal, nothing reachable about these
                     // inherently and their children are already in the
                     // worklist, as determined by the privacy pass
+                    ast::ItemExternCrate(_) | ast::ItemUse(_) |
                     ast::ItemTy(..) | ast::ItemStatic(_, _, _) |
                     ast::ItemMod(..) | ast::ItemForeignMod(..) |
                     ast::ItemImpl(..) | ast::ItemTrait(..) |
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 4aec30e11ea..030bf26699f 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -94,6 +94,8 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
                     // Fn lifetimes get added in visit_fn below:
                     visit::walk_item(this, item);
                 }
+                ast::ItemExternCrate(_) |
+                ast::ItemUse(_) |
                 ast::ItemMod(..) |
                 ast::ItemMac(..) |
                 ast::ItemForeignMod(..) |
diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs
index ef8a89c40fb..c420d1f15b4 100644
--- a/src/librustc/plugin/load.rs
+++ b/src/librustc/plugin/load.rs
@@ -73,8 +73,10 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
     // We need to error on `#[macro_use] extern crate` when it isn't at the
     // crate root, because `$crate` won't work properly. Identify these by
     // spans, because the crate map isn't set up yet.
-    for vi in krate.module.view_items.iter() {
-        loader.span_whitelist.insert(vi.span);
+    for item in krate.module.items.iter() {
+        if let ast::ItemExternCrate(_) = item.node {
+            loader.span_whitelist.insert(item.span);
+        }
     }
 
     visit::walk_crate(&mut loader, krate);
@@ -91,18 +93,21 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
 
 // note that macros aren't expanded yet, and therefore macros can't add plugins.
 impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
-    fn visit_view_item(&mut self, vi: &ast::ViewItem) {
+    fn visit_item(&mut self, item: &ast::Item) {
         // We're only interested in `extern crate`.
-        match vi.node {
-            ast::ViewItemExternCrate(..) => (),
-            _ => return,
+        match item.node {
+            ast::ItemExternCrate(_) => {}
+            _ => {
+                visit::walk_item(self, item);
+                return;
+            }
         }
 
         // Parse the attributes relating to macro / plugin loading.
         let mut plugin_attr = None;
         let mut macro_selection = Some(HashSet::new());  // None => load all
         let mut reexport = HashSet::new();
-        for attr in vi.attrs.iter() {
+        for attr in item.attrs.iter() {
             let mut used = true;
             match attr.name().get() {
                 "phase" => {
@@ -155,7 +160,10 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
             }
         }
 
-        self.load_plugin(CrateOrString::Krate(vi), plugin_attr, macro_selection, Some(reexport))
+        self.load_plugin(CrateOrString::Krate(item),
+                         plugin_attr,
+                         macro_selection,
+                         Some(reexport))
     }
 
     fn visit_mac(&mut self, _: &ast::Mac) {
diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs
index 77ee59dc2ba..ebeaf3e6e22 100644
--- a/src/librustc_back/svh.rs
+++ b/src/librustc_back/svh.rs
@@ -182,7 +182,6 @@ mod svh_visitor {
         SawLifetimeDef(token::InternedString),
 
         SawMod,
-        SawViewItem,
         SawForeignItem,
         SawItem,
         SawDecl,
@@ -430,19 +429,6 @@ mod svh_visitor {
             SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s)
         }
 
-        fn visit_view_item(&mut self, i: &ViewItem) {
-            // Two kinds of view items can affect the ABI for a crate:
-            // exported `pub use` view items (since that may expose
-            // items that downstream crates can call), and `use
-            // foo::Trait`, since changing that may affect method
-            // resolution.
-            //
-            // The simplest approach to handling both of the above is
-            // just to adopt the same simple-minded (fine-grained)
-            // hash that I am deploying elsewhere here.
-            SawViewItem.hash(self.st); visit::walk_view_item(self, i)
-        }
-
         fn visit_foreign_item(&mut self, i: &ForeignItem) {
             // FIXME (#14132) ideally we would incorporate privacy (or
             // perhaps reachability) somewhere here, so foreign items
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 279442891be..582e1032324 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -477,7 +477,7 @@ impl fold::Folder for ReplaceBodyWithLoop {
                          e: Option<P<ast::Expr>>) -> P<ast::Block> {
             P(ast::Block {
                 expr: e,
-                view_items: vec![], stmts: vec![], rules: rules,
+                stmts: vec![], rules: rules,
                 id: ast::DUMMY_NODE_ID, span: codemap::DUMMY_SP,
             })
         }
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index f68c76f4c44..cd28a27f988 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -200,6 +200,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
             }
 
             return match it.node {
+                ast::ItemUse(..) | ast::ItemExternCrate(..) |
                 ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemFn(..) |
                 ast::ItemForeignMod(..) | ast::ItemTy(..) => {
                     None
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index e12c195a3af..414dbb96263 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -830,6 +830,38 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
 
 impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
     fn visit_item(&mut self, item: &ast::Item) {
+        match item.node {
+            ast::ItemUse(ref vpath) => {
+                match vpath.node {
+                    ast::ViewPathSimple(..) | ast::ViewPathGlob(..) => {}
+                    ast::ViewPathList(ref prefix, ref list) => {
+                        for pid in list.iter() {
+                            match pid.node {
+                                ast::PathListIdent { id, name } => {
+                                    debug!("privacy - ident item {}", id);
+                                    let seg = ast::PathSegment {
+                                        identifier: name,
+                                        parameters: ast::PathParameters::none(),
+                                    };
+                                    let segs = vec![seg];
+                                    let path = ast::Path {
+                                        global: false,
+                                        span: pid.span,
+                                        segments: segs,
+                                    };
+                                    self.check_path(pid.span, id, &path);
+                                }
+                                ast::PathListMod { id } => {
+                                    debug!("privacy - mod item {}", id);
+                                    self.check_path(pid.span, id, prefix);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            _ => {}
+        }
         let orig_curitem = replace(&mut self.curitem, item.id);
         visit::walk_item(self, item);
         self.curitem = orig_curitem;
@@ -926,42 +958,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
         visit::walk_expr(self, expr);
     }
 
-    fn visit_view_item(&mut self, a: &ast::ViewItem) {
-        match a.node {
-            ast::ViewItemExternCrate(..) => {}
-            ast::ViewItemUse(ref vpath) => {
-                match vpath.node {
-                    ast::ViewPathSimple(..) | ast::ViewPathGlob(..) => {}
-                    ast::ViewPathList(ref prefix, ref list, _) => {
-                        for pid in list.iter() {
-                            match pid.node {
-                                ast::PathListIdent { id, name } => {
-                                    debug!("privacy - ident item {}", id);
-                                    let seg = ast::PathSegment {
-                                        identifier: name,
-                                        parameters: ast::PathParameters::none(),
-                                    };
-                                    let segs = vec![seg];
-                                    let path = ast::Path {
-                                        global: false,
-                                        span: pid.span,
-                                        segments: segs,
-                                    };
-                                    self.check_path(pid.span, id, &path);
-                                }
-                                ast::PathListMod { id } => {
-                                    debug!("privacy - mod item {}", id);
-                                    self.check_path(pid.span, id, prefix);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        visit::walk_view_item(self, a);
-    }
-
     fn visit_pat(&mut self, pattern: &ast::Pat) {
         // Foreign functions do not have their patterns mapped in the def_map,
         // and there's nothing really relevant there anyway, so don't bother
@@ -1069,23 +1065,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for SanePrivacyVisitor<'a, 'tcx> {
         visit::walk_fn(self, fk, fd, b, s);
         self.in_fn = orig_in_fn;
     }
-
-    fn visit_view_item(&mut self, i: &ast::ViewItem) {
-        match i.vis {
-            ast::Inherited => {}
-            ast::Public => {
-                if self.in_fn {
-                    self.tcx.sess.span_err(i.span, "unnecessary `pub`, imports \
-                                                    in functions are never \
-                                                    reachable");
-                } else if let ast::ViewItemExternCrate(..) = i.node {
-                    self.tcx.sess.span_err(i.span, "`pub` visibility \
-                                                    is not allowed");
-                }
-            }
-        }
-        visit::walk_view_item(self, i);
-    }
 }
 
 impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
@@ -1162,7 +1141,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
 
             ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemStruct(..) |
             ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
-            ast::ItemMac(..) => {}
+            ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemMac(..) => {}
         }
     }
 
@@ -1219,6 +1198,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
                 }
             }
 
+            ast::ItemExternCrate(_) | ast::ItemUse(_) |
             ast::ItemStatic(..) | ast::ItemConst(..) |
             ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
             ast::ItemMac(..) => {}
@@ -1521,11 +1501,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
 
 
     // we don't need to introspect into these at all: an
-    // expression/block context can't possibly contain exported
-    // things, and neither do view_items. (Making them no-ops stops us
-    // from traversing the whole AST without having to be super
-    // careful about our `walk_...` calls above.)
-    fn visit_view_item(&mut self, _: &ast::ViewItem) {}
+    // expression/block context can't possibly contain exported things.
+    // (Making them no-ops stops us from traversing the whole AST without
+    // having to be super careful about our `walk_...` calls above.)
     fn visit_block(&mut self, _: &ast::Block) {}
     fn visit_expr(&mut self, _: &ast::Expr) {}
 }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 21eec383df4..65bd83d7937 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -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);
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index 18066a7b94b..97370112ab4 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -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);
     }
 }
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index cb184b6ab71..94801545c2f 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -65,10 +65,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};
@@ -1143,7 +1143,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)
@@ -1752,10 +1752,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());
@@ -1795,10 +1791,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()
@@ -1892,10 +1884,6 @@ 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) {
                 span_err!(self.session, span, E0259,
                           "an external crate named `{}` has already \
@@ -1909,10 +1897,6 @@ 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) {
                 span_err!(self.session, span, E0260,
                           "the name `{}` conflicts with an external \
@@ -2984,9 +2968,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 });
             }
 
-           ItemMac(..) => {
+            ItemExternCrate(_) | ItemUse(_) | ItemMac(..) => {
                 // do nothing, these are just around to be encoded
-           }
+            }
         }
     }
 
@@ -3527,6 +3511,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);
 
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 26a9ddf95a0..4aec53711ad 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -1037,6 +1037,110 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
         }
 
         match item.node {
+            ast::ItemUse(ref use_item) => {
+                match use_item.node {
+                    ast::ViewPathSimple(ident, ref path) => {
+                        let sub_span = self.span.span_for_last_ident(path.span);
+                        let mod_id = match self.lookup_type_ref(item.id) {
+                            Some(def_id) => {
+                                match self.lookup_def_kind(item.id, path.span) {
+                                    Some(kind) => self.fmt.ref_str(kind,
+                                                                   path.span,
+                                                                   sub_span,
+                                                                   def_id,
+                                                                   self.cur_scope),
+                                    None => {},
+                                }
+                                Some(def_id)
+                            },
+                            None => None,
+                        };
+
+                        // 'use' always introduces an alias, if there is not an explicit
+                        // one, there is an implicit one.
+                        let sub_span =
+                            match self.span.sub_span_after_keyword(use_item.span, keywords::As) {
+                                Some(sub_span) => Some(sub_span),
+                                None => sub_span,
+                            };
+
+                        self.fmt.use_alias_str(path.span,
+                                               sub_span,
+                                               item.id,
+                                               mod_id,
+                                               get_ident(ident).get(),
+                                               self.cur_scope);
+                        self.write_sub_paths_truncated(path);
+                    }
+                    ast::ViewPathGlob(ref path) => {
+                        // Make a comma-separated list of names of imported modules.
+                        let mut name_string = String::new();
+                        let glob_map = &self.analysis.glob_map;
+                        let glob_map = glob_map.as_ref().unwrap();
+                        if glob_map.contains_key(&item.id) {
+                            for n in glob_map[item.id].iter() {
+                                if name_string.len() > 0 {
+                                    name_string.push_str(", ");
+                                }
+                                name_string.push_str(n.as_str());
+                            }
+                        }
+
+                        let sub_span = self.span.sub_span_of_token(path.span,
+                                                                   token::BinOp(token::Star));
+                        self.fmt.use_glob_str(path.span,
+                                              sub_span,
+                                              item.id,
+                                              name_string.as_slice(),
+                                              self.cur_scope);
+                        self.write_sub_paths(path);
+                    }
+                    ast::ViewPathList(ref path, ref list) => {
+                        for plid in list.iter() {
+                            match plid.node {
+                                ast::PathListIdent { id, .. } => {
+                                    match self.lookup_type_ref(id) {
+                                        Some(def_id) =>
+                                            match self.lookup_def_kind(id, plid.span) {
+                                                Some(kind) => {
+                                                    self.fmt.ref_str(
+                                                        kind, plid.span,
+                                                        Some(plid.span),
+                                                        def_id, self.cur_scope);
+                                                }
+                                                None => ()
+                                            },
+                                        None => ()
+                                    }
+                                },
+                                ast::PathListMod { .. } => ()
+                            }
+                        }
+
+                        self.write_sub_paths(path);
+                    }
+                }
+            }
+            ast::ItemExternCrate(ref s) => {
+                let name = get_ident(item.ident);
+                let name = name.get();
+                let s = match *s {
+                    Some((ref s, _)) => s.get().to_string(),
+                    None => name.to_string(),
+                };
+                let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Crate);
+                let cnum = match self.sess.cstore.find_extern_mod_stmt_cnum(item.id) {
+                    Some(cnum) => cnum,
+                    None => 0,
+                };
+                self.fmt.extern_crate_str(item.span,
+                                          sub_span,
+                                          item.id,
+                                          cnum,
+                                          name,
+                                          &s[],
+                                          self.cur_scope);
+            }
             ast::ItemFn(ref decl, _, _, ref ty_params, ref body) =>
                 self.process_fn(item, &**decl, ty_params, &**body),
             ast::ItemStatic(ref typ, mt, ref expr) =>
@@ -1160,119 +1264,6 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
         }
     }
 
-    fn visit_view_item(&mut self, i: &ast::ViewItem) {
-        if generated_code(i.span) {
-            return
-        }
-
-        match i.node {
-            ast::ViewItemUse(ref item) => {
-                match item.node {
-                    ast::ViewPathSimple(ident, ref path, id) => {
-                        let sub_span = self.span.span_for_last_ident(path.span);
-                        let mod_id = match self.lookup_type_ref(id) {
-                            Some(def_id) => {
-                                match self.lookup_def_kind(id, path.span) {
-                                    Some(kind) => self.fmt.ref_str(kind,
-                                                                   path.span,
-                                                                   sub_span,
-                                                                   def_id,
-                                                                   self.cur_scope),
-                                    None => {},
-                                }
-                                Some(def_id)
-                            },
-                            None => None,
-                        };
-
-                        // 'use' always introduces an alias, if there is not an explicit
-                        // one, there is an implicit one.
-                        let sub_span =
-                            match self.span.sub_span_after_keyword(item.span, keywords::As) {
-                                Some(sub_span) => Some(sub_span),
-                                None => sub_span,
-                            };
-
-                        self.fmt.use_alias_str(path.span,
-                                               sub_span,
-                                               id,
-                                               mod_id,
-                                               get_ident(ident).get(),
-                                               self.cur_scope);
-                        self.write_sub_paths_truncated(path);
-                    }
-                    ast::ViewPathGlob(ref path, id) => {
-                        // Make a comma-separated list of names of imported modules.
-                        let mut name_string = String::new();
-                        let glob_map = &self.analysis.glob_map;
-                        let glob_map = glob_map.as_ref().unwrap();
-                        if glob_map.contains_key(&id) {
-                            for n in glob_map[id].iter() {
-                                if name_string.len() > 0 {
-                                    name_string.push_str(", ");
-                                }
-                                name_string.push_str(n.as_str());
-                            }
-                        }
-
-                        let sub_span = self.span.sub_span_of_token(path.span,
-                                                                   token::BinOp(token::Star));
-                        self.fmt.use_glob_str(path.span,
-                                              sub_span,
-                                              id,
-                                              name_string.as_slice(),
-                                              self.cur_scope);
-                        self.write_sub_paths(path);
-                    }
-                    ast::ViewPathList(ref path, ref list, _) => {
-                        for plid in list.iter() {
-                            match plid.node {
-                                ast::PathListIdent { id, .. } => {
-                                    match self.lookup_type_ref(id) {
-                                        Some(def_id) =>
-                                            match self.lookup_def_kind(id, plid.span) {
-                                                Some(kind) => {
-                                                    self.fmt.ref_str(
-                                                        kind, plid.span,
-                                                        Some(plid.span),
-                                                        def_id, self.cur_scope);
-                                                }
-                                                None => ()
-                                            },
-                                        None => ()
-                                    }
-                                },
-                                ast::PathListMod { .. } => ()
-                            }
-                        }
-
-                        self.write_sub_paths(path);
-                    }
-                }
-            },
-            ast::ViewItemExternCrate(ident, ref s, id) => {
-                let name = get_ident(ident);
-                let name = name.get();
-                let s = match *s {
-                    Some((ref s, _)) => s.get().to_string(),
-                    None => name.to_string(),
-                };
-                let sub_span = self.span.sub_span_after_keyword(i.span, keywords::Crate);
-                let cnum = match self.sess.cstore.find_extern_mod_stmt_cnum(id) {
-                    Some(cnum) => cnum,
-                    None => 0,
-                };
-                self.fmt.extern_crate_str(i.span,
-                                          sub_span,
-                                          id,
-                                          cnum,
-                                          name,
-                                          &s[],
-                                          self.cur_scope);
-            },
-        }
-    }
-
     fn visit_ty(&mut self, t: &ast::Ty) {
         if generated_code(t.span) {
             return
diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs
index f52e7c0ec94..93076260349 100644
--- a/src/librustc_trans/trans/monomorphize.rs
+++ b/src/librustc_trans/trans/monomorphize.rs
@@ -274,7 +274,6 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         ast_map::NodeArg(..) |
         ast_map::NodeBlock(..) |
         ast_map::NodePat(..) |
-        ast_map::NodeViewItem(..) |
         ast_map::NodeLocal(..) => {
             ccx.sess().bug(&format!("can't monomorphize a {:?}",
                                    map_node)[])
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 664e5eaa45b..8158b8da86d 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -555,6 +555,7 @@ fn convert(ccx: &CollectCtxt, it: &ast::Item) {
     debug!("convert: item {} with id {}", token::get_ident(it.ident), it.id);
     match it.node {
         // These don't define types.
+        ast::ItemExternCrate(_) | ast::ItemUse(_) |
         ast::ItemForeignMod(_) | ast::ItemMod(_) | ast::ItemMac(_) => {}
         ast::ItemEnum(ref enum_definition, ref generics) => {
             let scheme = ty_of_item(ccx, it);
@@ -1004,6 +1005,7 @@ fn ty_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, it: &ast::Item)
             tcx.tcache.borrow_mut().insert(local_def(it.id), scheme.clone());
             return scheme;
         }
+        ast::ItemExternCrate(_) | ast::ItemUse(_) |
         ast::ItemImpl(..) | ast::ItemMod(_) |
         ast::ItemForeignMod(_) | ast::ItemMac(_) => panic!(),
     }
diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs
index 5c07fcb3688..6ed18368738 100644
--- a/src/librustc_typeck/variance.rs
+++ b/src/librustc_typeck/variance.rs
@@ -380,6 +380,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
                 visit::walk_item(self, item);
             }
 
+            ast::ItemExternCrate(_) |
+            ast::ItemUse(_) |
             ast::ItemImpl(..) |
             ast::ItemStatic(..) |
             ast::ItemConst(..) |
@@ -532,6 +534,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
                 }
             }
 
+            ast::ItemExternCrate(_) |
+            ast::ItemUse(_) |
             ast::ItemStatic(..) |
             ast::ItemConst(..) |
             ast::ItemFn(..) |
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 788ec5af44c..203d9758c57 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -18,8 +18,7 @@ pub use self::TypeKind::*;
 pub use self::StructField::*;
 pub use self::VariantKind::*;
 pub use self::Mutability::*;
-pub use self::ViewItemInner::*;
-pub use self::ViewPath::*;
+pub use self::Import::*;
 pub use self::ItemEnum::*;
 pub use self::Attribute::*;
 pub use self::TyParamBound::*;
@@ -315,6 +314,8 @@ impl Item {
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Show)]
 pub enum ItemEnum {
+    ExternCrateItem(String, Option<String>),
+    ImportItem(Import),
     StructItem(Struct),
     EnumItem(Enum),
     FunctionItem(Function),
@@ -324,8 +325,6 @@ pub enum ItemEnum {
     ConstantItem(Constant),
     TraitItem(Trait),
     ImplItem(Impl),
-    /// `use` and `extern crate`
-    ViewItemItem(ViewItem),
     /// A method signature only. Used for required methods in traits (ie,
     /// non-default-methods).
     TyMethodItem(TyMethod),
@@ -355,27 +354,21 @@ impl Clean<Item> for doctree::Module {
         } else {
             "".to_string()
         };
-        let mut foreigns = Vec::new();
-        for subforeigns in self.foreigns.clean(cx).into_iter() {
-            for foreign in subforeigns.into_iter() {
-                foreigns.push(foreign)
-            }
-        }
-        let items: Vec<Vec<Item> > = vec!(
-            self.structs.clean(cx),
-            self.enums.clean(cx),
-            self.fns.clean(cx),
-            foreigns,
-            self.mods.clean(cx),
-            self.typedefs.clean(cx),
-            self.statics.clean(cx),
-            self.constants.clean(cx),
-            self.traits.clean(cx),
-            self.impls.clean(cx),
-            self.view_items.clean(cx).into_iter()
-                           .flat_map(|s| s.into_iter()).collect(),
-            self.macros.clean(cx),
-        );
+        let items: Vec<Item> =
+                   self.extern_crates.iter().map(|x| x.clean(cx))
+            .chain(self.imports.iter().flat_map(|x| x.clean(cx).into_iter()))
+            .chain(self.structs.iter().map(|x| x.clean(cx)))
+            .chain(self.enums.iter().map(|x| x.clean(cx)))
+            .chain(self.fns.iter().map(|x| x.clean(cx)))
+            .chain(self.foreigns.iter().flat_map(|x| x.clean(cx).into_iter()))
+            .chain(self.mods.iter().map(|x| x.clean(cx)))
+            .chain(self.typedefs.iter().map(|x| x.clean(cx)))
+            .chain(self.statics.iter().map(|x| x.clean(cx)))
+            .chain(self.constants.iter().map(|x| x.clean(cx)))
+            .chain(self.traits.iter().map(|x| x.clean(cx)))
+            .chain(self.impls.iter().map(|x| x.clean(cx)))
+            .chain(self.macros.iter().map(|x| x.clean(cx)))
+            .collect();
 
         // determine if we should display the inner contents or
         // the outer `mod` item for the source code.
@@ -401,9 +394,7 @@ impl Clean<Item> for doctree::Module {
             def_id: ast_util::local_def(self.id),
             inner: ModuleItem(Module {
                is_crate: self.is_crate,
-               items: items.iter()
-                           .flat_map(|x| x.iter().map(|x| (*x).clone()))
-                           .collect(),
+               items: items
             })
         }
     }
@@ -2143,12 +2134,21 @@ impl Clean<Item> for doctree::Impl {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
-pub struct ViewItem {
-    pub inner: ViewItemInner,
+impl Clean<Item> for doctree::ExternCrate {
+    fn clean(&self, cx: &DocContext) -> Item {
+        Item {
+            name: None,
+            attrs: self.attrs.clean(cx),
+            source: self.whence.clean(cx),
+            def_id: ast_util::local_def(0),
+            visibility: self.vis.clean(cx),
+            stability: None,
+            inner: ExternCrateItem(self.name.clean(cx), self.path.clone())
+        }
+    }
 }
 
-impl Clean<Vec<Item>> for ast::ViewItem {
+impl Clean<Vec<Item>> for doctree::Import {
     fn clean(&self, cx: &DocContext) -> Vec<Item> {
         // We consider inlining the documentation of `pub use` statements, but we
         // forcefully don't inline if this is not public or if the
@@ -2159,81 +2159,63 @@ impl Clean<Vec<Item>> for ast::ViewItem {
                 None => false,
             }
         });
-        let convert = |&: node: &ast::ViewItem_| {
-            Item {
-                name: None,
-                attrs: self.attrs.clean(cx),
-                source: self.span.clean(cx),
-                def_id: ast_util::local_def(0),
-                visibility: self.vis.clean(cx),
-                stability: None,
-                inner: ViewItemItem(ViewItem { inner: node.clean(cx) }),
+        let (mut ret, inner) = match self.node {
+            ast::ViewPathGlob(ref p) => {
+                (vec![], GlobImport(resolve_use_source(cx, p.clean(cx), self.id)))
             }
-        };
-        let mut ret = Vec::new();
-        match self.node {
-            ast::ViewItemUse(ref path) if !denied => {
-                match path.node {
-                    ast::ViewPathGlob(..) => ret.push(convert(&self.node)),
-                    ast::ViewPathList(ref a, ref list, ref b) => {
-                        // Attempt to inline all reexported items, but be sure
-                        // to keep any non-inlineable reexports so they can be
-                        // listed in the documentation.
-                        let remaining = list.iter().filter(|path| {
-                            match inline::try_inline(cx, path.node.id(), None) {
-                                Some(items) => {
-                                    ret.extend(items.into_iter()); false
-                                }
-                                None => true,
+            ast::ViewPathList(ref p, ref list) => {
+                // Attempt to inline all reexported items, but be sure
+                // to keep any non-inlineable reexports so they can be
+                // listed in the documentation.
+                let mut ret = vec![];
+                let remaining = if !denied {
+                    let mut remaining = vec![];
+                    for path in list.iter() {
+                        match inline::try_inline(cx, path.node.id(), None) {
+                            Some(items) => {
+                                ret.extend(items.into_iter());
+                            }
+                            None => {
+                                remaining.push(path.clean(cx));
                             }
-                        }).map(|a| a.clone()).collect::<Vec<ast::PathListItem>>();
-                        if remaining.len() > 0 {
-                            let path = ast::ViewPathList(a.clone(),
-                                                         remaining,
-                                                         b.clone());
-                            let path = syntax::codemap::dummy_spanned(path);
-                            ret.push(convert(&ast::ViewItemUse(P(path))));
-                        }
-                    }
-                    ast::ViewPathSimple(ident, _, id) => {
-                        match inline::try_inline(cx, id, Some(ident)) {
-                            Some(items) => ret.extend(items.into_iter()),
-                            None => ret.push(convert(&self.node)),
                         }
                     }
-                }
-            }
-            ref n => ret.push(convert(n)),
-        }
-        return ret;
-    }
-}
-
-#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
-pub enum ViewItemInner {
-    ExternCrate(String, Option<String>, ast::NodeId),
-    Import(ViewPath)
-}
-
-impl Clean<ViewItemInner> for ast::ViewItem_ {
-    fn clean(&self, cx: &DocContext) -> ViewItemInner {
-        match self {
-            &ast::ViewItemExternCrate(ref i, ref p, ref id) => {
-                let string = match *p {
-                    None => None,
-                    Some((ref x, _)) => Some(x.get().to_string()),
+                    remaining
+                } else {
+                    list.clean(cx)
                 };
-                ExternCrate(i.clean(cx), string, *id)
+                if remaining.is_empty() {
+                    return ret;
+                }
+                (ret, ImportList(resolve_use_source(cx, p.clean(cx), self.id),
+                                 remaining))
             }
-            &ast::ViewItemUse(ref vp) => {
-                Import(vp.clean(cx))
+            ast::ViewPathSimple(i, ref p) => {
+                if !denied {
+                    match inline::try_inline(cx, self.id, Some(i)) {
+                        Some(items) => return items,
+                        None => {}
+                    }
+                }
+                (vec![], SimpleImport(i.clean(cx),
+                                      resolve_use_source(cx, p.clean(cx), self.id)))
             }
-        }
+        };
+        ret.push(Item {
+            name: None,
+            attrs: self.attrs.clean(cx),
+            source: self.whence.clean(cx),
+            def_id: ast_util::local_def(0),
+            visibility: self.vis.clean(cx),
+            stability: None,
+            inner: ImportItem(inner)
+        });
+        ret
     }
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Show)]
-pub enum ViewPath {
+pub enum Import {
     // use source as str;
     SimpleImport(String, ImportSource),
     // use source::*;
@@ -2248,21 +2230,6 @@ pub struct ImportSource {
     pub did: Option<ast::DefId>,
 }
 
-impl Clean<ViewPath> for ast::ViewPath {
-    fn clean(&self, cx: &DocContext) -> ViewPath {
-        match self.node {
-            ast::ViewPathSimple(ref i, ref p, id) =>
-                SimpleImport(i.clean(cx), resolve_use_source(cx, p.clean(cx), id)),
-            ast::ViewPathGlob(ref p, id) =>
-                GlobImport(resolve_use_source(cx, p.clean(cx), id)),
-            ast::ViewPathList(ref p, ref pl, id) => {
-                ImportList(resolve_use_source(cx, p.clean(cx), id),
-                           pl.clean(cx))
-            }
-        }
-    }
-}
-
 #[derive(Clone, RustcEncodable, RustcDecodable, Show)]
 pub struct ViewListIdent {
     pub name: String,
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 99afef4173f..0e8ab594c20 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -25,6 +25,8 @@ pub struct Module {
     pub attrs: Vec<ast::Attribute>,
     pub where_outer: Span,
     pub where_inner: Span,
+    pub extern_crates: Vec<ExternCrate>,
+    pub imports: Vec<Import>,
     pub structs: Vec<Struct>,
     pub enums: Vec<Enum>,
     pub fns: Vec<Function>,
@@ -38,7 +40,6 @@ pub struct Module {
     pub stab: Option<attr::Stability>,
     pub impls: Vec<Impl>,
     pub foreigns: Vec<ast::ForeignMod>,
-    pub view_items: Vec<ast::ViewItem>,
     pub macros: Vec<Macro>,
     pub is_crate: bool,
 }
@@ -53,6 +54,8 @@ impl Module {
             where_outer: syntax::codemap::DUMMY_SP,
             where_inner: syntax::codemap::DUMMY_SP,
             attrs      : Vec::new(),
+            extern_crates: Vec::new(),
+            imports    : Vec::new(),
             structs    : Vec::new(),
             enums      : Vec::new(),
             fns        : Vec::new(),
@@ -62,7 +65,6 @@ impl Module {
             constants  : Vec::new(),
             traits     : Vec::new(),
             impls      : Vec::new(),
-            view_items : Vec::new(),
             foreigns   : Vec::new(),
             macros     : Vec::new(),
             is_crate   : false,
@@ -202,6 +204,22 @@ pub struct Macro {
     pub stab: Option<attr::Stability>,
 }
 
+pub struct ExternCrate {
+    pub name: Ident,
+    pub path: Option<String>,
+    pub vis: ast::Visibility,
+    pub attrs: Vec<ast::Attribute>,
+    pub whence: Span,
+}
+
+pub struct Import {
+    pub id: NodeId,
+    pub vis: ast::Visibility,
+    pub attrs: Vec<ast::Attribute>,
+    pub node: ast::ViewPath_,
+    pub whence: Span,
+}
+
 pub fn struct_type_from_def(sd: &ast::StructDef) -> StructType {
     if sd.ctor_id.is_some() {
         // We are in a tuple-struct
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index bc0f77d1957..b713032bc05 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -617,7 +617,7 @@ impl fmt::Display for UnsafetySpace {
     }
 }
 
-impl fmt::Display for clean::ViewPath {
+impl fmt::Display for clean::Import {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             clean::SimpleImport(ref name, ref src) => {
diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs
index fbc8ae2c0b4..356be2ffeb0 100644
--- a/src/librustdoc/html/item_type.rs
+++ b/src/librustdoc/html/item_type.rs
@@ -22,29 +22,31 @@ use clean;
 #[derive(Copy, PartialEq, Clone)]
 pub enum ItemType {
     Module          = 0,
-    Struct          = 1,
-    Enum            = 2,
-    Function        = 3,
-    Typedef         = 4,
-    Static          = 5,
-    Trait           = 6,
-    Impl            = 7,
-    ViewItem        = 8,
-    TyMethod        = 9,
-    Method          = 10,
-    StructField     = 11,
-    Variant         = 12,
-    // we used to have ForeignFunction and ForeignStatic. they are retired now.
-    Macro           = 15,
-    Primitive       = 16,
-    AssociatedType  = 17,
-    Constant        = 18,
+    ExternCrate     = 1,
+    Import          = 2,
+    Struct          = 3,
+    Enum            = 4,
+    Function        = 5,
+    Typedef         = 6,
+    Static          = 7,
+    Trait           = 8,
+    Impl            = 9,
+    TyMethod        = 10,
+    Method          = 11,
+    StructField     = 12,
+    Variant         = 13,
+    Macro           = 14,
+    Primitive       = 15,
+    AssociatedType  = 16,
+    Constant        = 17,
 }
 
 impl ItemType {
     pub fn from_item(item: &clean::Item) -> ItemType {
         match item.inner {
             clean::ModuleItem(..)          => ItemType::Module,
+            clean::ExternCrateItem(..)     => ItemType::ExternCrate,
+            clean::ImportItem(..)          => ItemType::Import,
             clean::StructItem(..)          => ItemType::Struct,
             clean::EnumItem(..)            => ItemType::Enum,
             clean::FunctionItem(..)        => ItemType::Function,
@@ -53,7 +55,6 @@ impl ItemType {
             clean::ConstantItem(..)        => ItemType::Constant,
             clean::TraitItem(..)           => ItemType::Trait,
             clean::ImplItem(..)            => ItemType::Impl,
-            clean::ViewItemItem(..)        => ItemType::ViewItem,
             clean::TyMethodItem(..)        => ItemType::TyMethod,
             clean::MethodItem(..)          => ItemType::Method,
             clean::StructFieldItem(..)     => ItemType::StructField,
@@ -83,6 +84,8 @@ impl ItemType {
     pub fn to_static_str(&self) -> &'static str {
         match *self {
             ItemType::Module          => "mod",
+            ItemType::ExternCrate     => "externcrate",
+            ItemType::Import          => "import",
             ItemType::Struct          => "struct",
             ItemType::Enum            => "enum",
             ItemType::Function        => "fn",
@@ -90,7 +93,6 @@ impl ItemType {
             ItemType::Static          => "static",
             ItemType::Trait           => "trait",
             ItemType::Impl            => "impl",
-            ItemType::ViewItem        => "viewitem",
             ItemType::TyMethod        => "tymethod",
             ItemType::Method          => "method",
             ItemType::StructField     => "structfield",
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 3656c3a459c..cd2ed5f0a97 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -35,7 +35,7 @@
 pub use self::ExternalLocation::*;
 
 use std::cell::RefCell;
-use std::cmp::Ordering::{self, Less, Greater, Equal};
+use std::cmp::Ordering;
 use std::collections::{HashMap, HashSet};
 use std::default::Default;
 use std::fmt;
@@ -1497,18 +1497,19 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
     // the order of item types in the listing
     fn reorder(ty: ItemType) -> u8 {
         match ty {
-            ItemType::ViewItem        => 0,
-            ItemType::Primitive       => 1,
-            ItemType::Module          => 2,
-            ItemType::Macro           => 3,
-            ItemType::Struct          => 4,
-            ItemType::Enum            => 5,
-            ItemType::Constant        => 6,
-            ItemType::Static          => 7,
-            ItemType::Trait           => 8,
-            ItemType::Function        => 9,
-            ItemType::Typedef         => 10,
-            _                         => 11 + ty as u8,
+            ItemType::ExternCrate     => 0,
+            ItemType::Import          => 1,
+            ItemType::Primitive       => 2,
+            ItemType::Module          => 3,
+            ItemType::Macro           => 4,
+            ItemType::Struct          => 5,
+            ItemType::Enum            => 6,
+            ItemType::Constant        => 7,
+            ItemType::Static          => 8,
+            ItemType::Trait           => 9,
+            ItemType::Function        => 10,
+            ItemType::Typedef         => 12,
+            _                         => 13 + ty as u8,
         }
     }
 
@@ -1518,25 +1519,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
         if ty1 == ty2 {
             return i1.name.cmp(&i2.name);
         }
-
-        let tycmp = reorder(ty1).cmp(&reorder(ty2));
-        if let Equal = tycmp {
-            // for reexports, `extern crate` takes precedence.
-            match (&i1.inner, &i2.inner) {
-                (&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => {
-                    match (&a.inner, &b.inner) {
-                        (&clean::ExternCrate(..), _) => return Less,
-                        (_, &clean::ExternCrate(..)) => return Greater,
-                        _ => {}
-                    }
-                }
-                (_, _) => {}
-            }
-
-            idx1.cmp(&idx2)
-        } else {
-            tycmp
-        }
+        (reorder(ty1), idx1).cmp(&(reorder(ty2), idx2))
     }
 
     indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
@@ -1547,12 +1530,17 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
         let myitem = &items[idx];
 
         let myty = Some(shortty(myitem));
-        if myty != curty {
+        if curty == Some(ItemType::ExternCrate) && myty == Some(ItemType::Import) {
+            // Put `extern crate` and `use` re-exports in the same section.
+            curty = myty;
+        } else if myty != curty {
             if curty.is_some() {
                 try!(write!(w, "</table>"));
             }
             curty = myty;
             let (short, name) = match myty.unwrap() {
+                ItemType::ExternCrate |
+                ItemType::Import          => ("reexports", "Reexports"),
                 ItemType::Module          => ("modules", "Modules"),
                 ItemType::Struct          => ("structs", "Structs"),
                 ItemType::Enum            => ("enums", "Enums"),
@@ -1562,7 +1550,6 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
                 ItemType::Constant        => ("constants", "Constants"),
                 ItemType::Trait           => ("traits", "Traits"),
                 ItemType::Impl            => ("impls", "Implementations"),
-                ItemType::ViewItem        => ("reexports", "Reexports"),
                 ItemType::TyMethod        => ("tymethods", "Type Methods"),
                 ItemType::Method          => ("methods", "Methods"),
                 ItemType::StructField     => ("fields", "Struct Fields"),
@@ -1578,28 +1565,25 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
         }
 
         match myitem.inner {
-            clean::ViewItemItem(ref item) => {
-                match item.inner {
-                    clean::ExternCrate(ref name, ref src, _) => {
-                        match *src {
-                            Some(ref src) =>
-                                try!(write!(w, "<tr><td><code>extern crate \"{}\" as {}",
-                                            src.as_slice(),
-                                            name.as_slice())),
-                            None =>
-                                try!(write!(w, "<tr><td><code>extern crate {}",
-                                            name.as_slice())),
-                        }
-                        try!(write!(w, ";</code></td></tr>"));
+            clean::ExternCrateItem(ref name, ref src) => {
+                match *src {
+                    Some(ref src) => {
+                        try!(write!(w, "<tr><td><code>{}extern crate \"{}\" as {};",
+                                    VisSpace(myitem.visibility),
+                                    src.as_slice(),
+                                    name.as_slice()))
                     }
-
-                    clean::Import(ref import) => {
-                        try!(write!(w, "<tr><td><code>{}{}</code></td></tr>",
-                                      VisSpace(myitem.visibility),
-                                      *import));
+                    None => {
+                        try!(write!(w, "<tr><td><code>{}extern crate {};",
+                                    VisSpace(myitem.visibility), name.as_slice()))
                     }
                 }
+                try!(write!(w, "</code></td></tr>"));
+            }
 
+            clean::ImportItem(ref import) => {
+                try!(write!(w, "<tr><td><code>{}{}</code></td></tr>",
+                            VisSpace(myitem.visibility), *import));
             }
 
             _ => {
diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css
index 5951ac2bae7..0914f93efd8 100644
--- a/src/librustdoc/html/static/main.css
+++ b/src/librustdoc/html/static/main.css
@@ -245,7 +245,6 @@ nav.sub {
 .content .highlighted.method { background-color: #c6afb3; }
 .content .highlighted.tymethod { background-color: #c6afb3; }
 .content .highlighted.type { background-color: #c6afb3; }
-.content .highlighted.ffi { background-color: #c6afb3; }
 
 .docblock.short.nowrap {
     display: block;
@@ -365,7 +364,6 @@ p a:hover { text-decoration: underline; }
 .content span.fn, .content a.fn, .block a.current.fn { color: #8c6067; }
 .content span.method, .content a.method, .block a.current.method { color: #8c6067; }
 .content span.tymethod, .content a.tymethod, .block a.current.tymethod { color: #8c6067; }
-.content span.ffi, .content a.ffi, .block a.current.ffi { color: #8c6067; }
 .content .fnname { color: #8c6067; }
 
 .search-input {
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index f27f0cd70f4..1b0c3b00640 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -555,6 +555,8 @@
         // This mapping table should match the discriminants of
         // `rustdoc::html::item_type::ItemType` type in Rust.
         var itemTypes = ["mod",
+                         "externcrate",
+                         "import",
                          "struct",
                          "enum",
                          "fn",
@@ -562,13 +564,10 @@
                          "static",
                          "trait",
                          "impl",
-                         "viewitem",
                          "tymethod",
                          "method",
                          "structfield",
                          "variant",
-                         "ffi", // retained for backward compatibility
-                         "ffs", // retained for backward compatibility
                          "macro",
                          "primitive",
                          "associatedtype",
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index 34a23774e5b..30b2ad810f1 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -149,7 +149,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
                 }
             }
 
-            clean::ViewItemItem(..) => {
+            clean::ExternCrateItem(..) | clean::ImportItem(_) => {
                 if i.visibility != Some(ast::Public) {
                     return None
                 }
diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs
index 451dbce568e..943bc6ec996 100644
--- a/src/librustdoc/stability_summary.rs
+++ b/src/librustdoc/stability_summary.rs
@@ -21,7 +21,7 @@ use syntax::ast::Public;
 
 use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
 use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod};
-use clean::{TypeTraitItem, ViewItemItem, PrimitiveItem, Stability};
+use clean::{TypeTraitItem, ExternCrateItem, ImportItem, PrimitiveItem, Stability};
 
 use html::render::cache;
 
@@ -199,7 +199,8 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
             }))
         }
         // no stability information for the following items:
-        ViewItemItem(_) | PrimitiveItem(_) => (Counts::zero(), None),
+        ExternCrateItem(..) | ImportItem(_) |
+        PrimitiveItem(_) => (Counts::zero(), None),
         _ => (item_counts, None)
     }
 }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 428b4e92a68..848205f589e 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -20,7 +20,6 @@ use syntax::ast_map;
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
 use syntax::codemap::Span;
-use syntax::ptr::P;
 
 use rustc::middle::stability;
 
@@ -142,9 +141,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                               m: &ast::Mod,
                               name: Option<ast::Ident>) -> Module {
         let mut om = Module::new(name);
-        for item in m.view_items.iter() {
-            self.visit_view_item(item, &mut om);
-        }
         om.where_outer = span;
         om.where_inner = m.inner;
         om.attrs = attrs;
@@ -157,68 +153,41 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         om
     }
 
-    pub fn visit_view_item(&mut self, item: &ast::ViewItem, om: &mut Module) {
-        if item.vis != ast::Public {
-            return om.view_items.push(item.clone());
-        }
-        let please_inline = item.attrs.iter().any(|item| {
-            match item.meta_item_list() {
-                Some(list) => {
-                    list.iter().any(|i| i.name().get() == "inline")
-                }
-                None => false,
-            }
-        });
-        let item = match item.node {
-            ast::ViewItemUse(ref vpath) => {
-                match self.visit_view_path(&**vpath, om, please_inline) {
-                    None => return,
-                    Some(path) => {
-                        ast::ViewItem {
-                            node: ast::ViewItemUse(path),
-                            .. item.clone()
-                        }
-                    }
-                }
-            }
-            ast::ViewItemExternCrate(..) => item.clone()
-        };
-        om.view_items.push(item);
-    }
-
-    fn visit_view_path(&mut self, path: &ast::ViewPath,
+    fn visit_view_path(&mut self, path: ast::ViewPath_,
                        om: &mut Module,
-                       please_inline: bool) -> Option<P<ast::ViewPath>> {
-        match path.node {
-            ast::ViewPathSimple(dst, _, id) => {
+                       id: ast::NodeId,
+                       please_inline: bool) -> Option<ast::ViewPath_> {
+        match path {
+            ast::ViewPathSimple(dst, base) => {
                 if self.resolve_id(id, Some(dst), false, om, please_inline) {
-                    return None
+                    None
+                } else {
+                    Some(ast::ViewPathSimple(dst, base))
                 }
             }
-            ast::ViewPathList(ref p, ref paths, ref b) => {
-                let mut mine = Vec::new();
-                for path in paths.iter() {
-                    if !self.resolve_id(path.node.id(), None, false, om,
-                                        please_inline) {
-                        mine.push(path.clone());
-                    }
-                }
+            ast::ViewPathList(p, paths) => {
+                let mine = paths.into_iter().filter(|path| {
+                    !self.resolve_id(path.node.id(), None, false, om,
+                                     please_inline)
+                }).collect::<Vec<ast::PathListItem>>();
 
-                if mine.len() == 0 { return None }
-                return Some(P(::syntax::codemap::Spanned {
-                    node: ast::ViewPathList(p.clone(), mine, b.clone()),
-                    span: path.span,
-                }))
+                if mine.len() == 0 {
+                    None
+                } else {
+                    Some(ast::ViewPathList(p, mine))
+                }
             }
 
             // these are feature gated anyway
-            ast::ViewPathGlob(_, id) => {
+            ast::ViewPathGlob(base) => {
                 if self.resolve_id(id, None, true, om, please_inline) {
-                    return None
+                    None
+                } else {
+                    Some(ast::ViewPathGlob(base))
                 }
             }
         }
-        Some(P(path.clone()))
+
     }
 
     fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
@@ -242,9 +211,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 if glob {
                     match it.node {
                         ast::ItemMod(ref m) => {
-                            for vi in m.view_items.iter() {
-                                self.visit_view_item(vi, om);
-                            }
                             for i in m.items.iter() {
                                 self.visit_item(&**i, None, om);
                             }
@@ -268,6 +234,45 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         debug!("Visiting item {:?}", item);
         let name = renamed.unwrap_or(item.ident);
         match item.node {
+            ast::ItemExternCrate(ref p) => {
+                let path = match *p {
+                    None => None,
+                    Some((ref x, _)) => Some(x.get().to_string()),
+                };
+                om.extern_crates.push(ExternCrate {
+                    name: name,
+                    path: path,
+                    vis: item.vis,
+                    attrs: item.attrs.clone(),
+                    whence: item.span,
+                })
+            }
+            ast::ItemUse(ref vpath) => {
+                let node = vpath.node.clone();
+                let node = if item.vis == ast::Public {
+                    let please_inline = item.attrs.iter().any(|item| {
+                        match item.meta_item_list() {
+                            Some(list) => {
+                                list.iter().any(|i| i.name().get() == "inline")
+                            }
+                            None => false,
+                        }
+                    });
+                    match self.visit_view_path(node, om, item.id, please_inline) {
+                        None => return,
+                        Some(p) => p
+                    }
+                } else {
+                    node
+                };
+                om.imports.push(Import {
+                    id: item.id,
+                    vis: item.vis,
+                    attrs: item.attrs.clone(),
+                    node: node,
+                    whence: item.span,
+                });
+            }
             ast::ItemMod(ref m) => {
                 om.mods.push(self.visit_mod_contents(item.span,
                                                      item.attrs.clone(),
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index acc5c70ac3c..7111fe3af1f 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -53,7 +53,6 @@ pub use self::UnboxedClosureKind::*;
 pub use self::UnOp::*;
 pub use self::UnsafeSource::*;
 pub use self::VariantKind::*;
-pub use self::ViewItem_::*;
 pub use self::ViewPath_::*;
 pub use self::Visibility::*;
 pub use self::PathParameters::*;
@@ -511,7 +510,6 @@ impl PartialEq for MetaItem_ {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
 pub struct Block {
-    pub view_items: Vec<ViewItem>,
     pub stmts: Vec<P<Stmt>>,
     pub expr: Option<P<Expr>>,
     pub id: NodeId,
@@ -1443,14 +1441,12 @@ pub struct Mod {
     /// For `mod foo;`, the inner span ranges from the first token
     /// to the last token in the external file.
     pub inner: Span,
-    pub view_items: Vec<ViewItem>,
     pub items: Vec<P<Item>>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
 pub struct ForeignMod {
     pub abi: Abi,
-    pub view_items: Vec<ViewItem>,
     pub items: Vec<P<ForeignItem>>,
 }
 
@@ -1509,44 +1505,13 @@ pub enum ViewPath_ {
     /// or just
     ///
     /// `foo::bar::baz` (with `as baz` implicitly on the right)
-    ViewPathSimple(Ident, Path, NodeId),
+    ViewPathSimple(Ident, Path),
 
     /// `foo::bar::*`
-    ViewPathGlob(Path, NodeId),
+    ViewPathGlob(Path),
 
     /// `foo::bar::{a,b,c}`
-    ViewPathList(Path, Vec<PathListItem> , NodeId)
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
-pub struct ViewItem {
-    pub node: ViewItem_,
-    pub attrs: Vec<Attribute>,
-    pub vis: Visibility,
-    pub span: Span,
-}
-
-impl ViewItem {
-    pub fn id(&self) -> NodeId {
-        match self.node {
-            ViewItemExternCrate(_, _, id) => id,
-            ViewItemUse(ref vp) => match vp.node {
-                ViewPathSimple(_, _, id) => id,
-                ViewPathGlob(_, id) => id,
-                ViewPathList(_, _, id) => id,
-            }
-        }
-    }
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
-pub enum ViewItem_ {
-    /// Ident: name used to refer to this crate in the code
-    /// optional (InternedString,StrStyle): if present, this is a location
-    /// (containing arbitrary characters) from which to fetch the crate sources
-    /// For example, extern crate whatever = "github.com/rust-lang/rust"
-    ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
-    ViewItemUse(P<ViewPath>),
+    ViewPathList(Path, Vec<PathListItem>)
 }
 
 /// Meta-data associated with an item
@@ -1668,6 +1633,12 @@ pub struct Item {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
 pub enum Item_ {
+    // Optional location (containing arbitrary characters) from which
+    // to fetch the crate sources.
+    // For example, extern crate whatever = "github.com/rust-lang/rust".
+    ItemExternCrate(Option<(InternedString, StrStyle)>),
+    ItemUse(P<ViewPath>),
+
     ItemStatic(P<Ty>, Mutability, P<Expr>),
     ItemConst(P<Ty>, P<Expr>),
     ItemFn(P<FnDecl>, Unsafety, Abi, Generics, P<Block>),
@@ -1694,6 +1665,8 @@ pub enum Item_ {
 impl Item_ {
     pub fn descriptive_variant(&self) -> &str {
         match *self {
+            ItemExternCrate(..) => "extern crate",
+            ItemUse(..) => "use",
             ItemStatic(..) => "static item",
             ItemConst(..) => "constant item",
             ItemFn(..) => "function",
diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs
index 6dc7d93c47b..8a114e4b748 100644
--- a/src/libsyntax/ast_map/mod.rs
+++ b/src/libsyntax/ast_map/mod.rs
@@ -107,7 +107,6 @@ pub fn path_to_string<PI: Iterator<Item=PathElem>>(path: PI) -> String {
 #[derive(Copy, Show)]
 pub enum Node<'ast> {
     NodeItem(&'ast Item),
-    NodeViewItem(&'ast ViewItem),
     NodeForeignItem(&'ast ForeignItem),
     NodeTraitItem(&'ast TraitItem),
     NodeImplItem(&'ast ImplItem),
@@ -134,7 +133,6 @@ enum MapEntry<'ast> {
 
     /// All the node types, with a parent ID.
     EntryItem(NodeId, &'ast Item),
-    EntryViewItem(NodeId, &'ast ViewItem),
     EntryForeignItem(NodeId, &'ast ForeignItem),
     EntryTraitItem(NodeId, &'ast TraitItem),
     EntryImplItem(NodeId, &'ast ImplItem),
@@ -169,7 +167,6 @@ impl<'ast> MapEntry<'ast> {
     fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> {
         match node {
             NodeItem(n) => EntryItem(p, n),
-            NodeViewItem(n) => EntryViewItem(p, n),
             NodeForeignItem(n) => EntryForeignItem(p, n),
             NodeTraitItem(n) => EntryTraitItem(p, n),
             NodeImplItem(n) => EntryImplItem(p, n),
@@ -188,7 +185,6 @@ impl<'ast> MapEntry<'ast> {
     fn parent(self) -> Option<NodeId> {
         Some(match self {
             EntryItem(id, _) => id,
-            EntryViewItem(id, _) => id,
             EntryForeignItem(id, _) => id,
             EntryTraitItem(id, _) => id,
             EntryImplItem(id, _) => id,
@@ -208,7 +204,6 @@ impl<'ast> MapEntry<'ast> {
     fn to_node(self) -> Option<Node<'ast>> {
         Some(match self {
             EntryItem(_, n) => NodeItem(n),
-            EntryViewItem(_, n) => NodeViewItem(n),
             EntryForeignItem(_, n) => NodeForeignItem(n),
             EntryTraitItem(_, n) => NodeTraitItem(n),
             EntryImplItem(_, n) => NodeImplItem(n),
@@ -341,13 +336,6 @@ impl<'ast> Map<'ast> {
         }
     }
 
-    pub fn expect_view_item(&self, id: NodeId) -> &'ast ViewItem {
-        match self.find(id) {
-            Some(NodeViewItem(view_item)) => view_item,
-            _ => panic!("expected view item, found {}", self.node_to_string(id))
-        }
-    }
-
     pub fn expect_struct(&self, id: NodeId) -> &'ast StructDef {
         match self.find(id) {
             Some(NodeItem(i)) => {
@@ -533,7 +521,6 @@ impl<'ast> Map<'ast> {
     pub fn opt_span(&self, id: NodeId) -> Option<Span> {
         let sp = match self.find(id) {
             Some(NodeItem(item)) => item.span,
-            Some(NodeViewItem(item)) => item.span,
             Some(NodeForeignItem(foreign_item)) => foreign_item.span,
             Some(NodeTraitItem(trait_method)) => {
                 match *trait_method {
@@ -826,11 +813,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
         self.parent = parent;
     }
 
-    fn visit_view_item(&mut self, item: &'ast ViewItem) {
-        self.insert(item.id(), NodeViewItem(item));
-        visit::walk_view_item(self, item);
-    }
-
     fn visit_pat(&mut self, pat: &'ast Pat) {
         self.insert(pat.id, match pat.node {
             // Note: this is at least *potentially* a pattern...
@@ -904,7 +886,6 @@ pub fn map_crate<'ast, F: FoldOps>(forest: &'ast mut Forest, fold_ops: F) -> Map
     let krate = mem::replace(&mut forest.krate, Crate {
         module: Mod {
             inner: DUMMY_SP,
-            view_items: vec![],
             items: vec![],
         },
         attrs: vec![],
@@ -1036,7 +1017,6 @@ impl<'a> NodePrinter for pprust::State<'a> {
     fn print_node(&mut self, node: &Node) -> IoResult<()> {
         match *node {
             NodeItem(a)        => self.print_item(&*a),
-            NodeViewItem(a)    => self.print_view_item(&*a),
             NodeForeignItem(a) => self.print_foreign_item(&*a),
             NodeTraitItem(a)   => self.print_trait_method(&*a),
             NodeImplItem(a)    => self.print_impl_item(&*a),
@@ -1065,6 +1045,8 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
         Some(NodeItem(item)) => {
             let path_str = map.path_to_str_with_ident(id, item.ident);
             let item_str = match item.node {
+                ItemExternCrate(..) => "extern crate",
+                ItemUse(..) => "use",
                 ItemStatic(..) => "static",
                 ItemConst(..) => "const",
                 ItemFn(..) => "fn",
@@ -1079,9 +1061,6 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
             };
             format!("{} {}{}", item_str, path_str, id_str)
         }
-        Some(NodeViewItem(item)) => {
-            format!("view item {}{}", pprust::view_item_to_string(&*item), id_str)
-        }
         Some(NodeForeignItem(item)) => {
             let path_str = map.path_to_str_with_ident(id, item.ident);
             format!("foreign item {}{}", path_str, id_str)
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 34fd498322c..892b3c1e7f2 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -410,37 +410,6 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
         visit::walk_mod(self, module)
     }
 
-    fn visit_view_item(&mut self, view_item: &ViewItem) {
-        if !self.pass_through_items {
-            if self.visited_outermost {
-                return;
-            } else {
-                self.visited_outermost = true;
-            }
-        }
-        match view_item.node {
-            ViewItemExternCrate(_, _, node_id) => {
-                self.operation.visit_id(node_id)
-            }
-            ViewItemUse(ref view_path) => {
-                match view_path.node {
-                    ViewPathSimple(_, _, node_id) |
-                    ViewPathGlob(_, node_id) => {
-                        self.operation.visit_id(node_id)
-                    }
-                    ViewPathList(_, ref paths, node_id) => {
-                        self.operation.visit_id(node_id);
-                        for path in paths.iter() {
-                            self.operation.visit_id(path.node.id())
-                        }
-                    }
-                }
-            }
-        }
-        visit::walk_view_item(self, view_item);
-        self.visited_outermost = false;
-    }
-
     fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
         self.operation.visit_id(foreign_item.id);
         visit::walk_foreign_item(self, foreign_item)
@@ -456,10 +425,24 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
         }
 
         self.operation.visit_id(item.id);
-        if let ItemEnum(ref enum_definition, _) = item.node {
-            for variant in enum_definition.variants.iter() {
-                self.operation.visit_id(variant.node.id)
+        match item.node {
+            ItemUse(ref view_path) => {
+                match view_path.node {
+                    ViewPathSimple(_, _) |
+                    ViewPathGlob(_) => {}
+                    ViewPathList(_, ref paths) => {
+                        for path in paths.iter() {
+                            self.operation.visit_id(path.node.id())
+                        }
+                    }
+                }
+            }
+            ItemEnum(ref enum_definition, _) => {
+                for variant in enum_definition.variants.iter() {
+                    self.operation.visit_id(variant.node.id)
+                }
             }
+            _ => {}
         }
 
         visit::walk_item(self, item);
@@ -662,37 +645,6 @@ pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool where F: FnMut(&Pat) -> bool {
     walk_pat_(pat, &mut it)
 }
 
-pub trait EachViewItem {
-    fn each_view_item<F>(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool;
-}
-
-struct EachViewItemData<F> where F: FnMut(&ast::ViewItem) -> bool {
-    callback: F,
-}
-
-impl<'v, F> Visitor<'v> for EachViewItemData<F> where F: FnMut(&ast::ViewItem) -> bool {
-    fn visit_view_item(&mut self, view_item: &ast::ViewItem) {
-        let _ = (self.callback)(view_item);
-    }
-}
-
-impl EachViewItem for ast::Crate {
-    fn each_view_item<F>(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool {
-        let mut visit = EachViewItemData {
-            callback: f,
-        };
-        visit::walk_crate(&mut visit, self);
-        true
-    }
-}
-
-pub fn view_path_id(p: &ViewPath) -> NodeId {
-    match p.node {
-        ViewPathSimple(_, _, id) | ViewPathGlob(_, id)
-        | ViewPathList(_, _, id) => id
-    }
-}
-
 /// Returns true if the given struct def is tuple-like; i.e. that its fields
 /// are unnamed.
 pub fn struct_def_is_tuple_like(struct_def: &ast::StructDef) -> bool {
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 3f91831a5df..3eaac0fe333 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -63,28 +63,13 @@ pub fn strip_items<F>(krate: ast::Crate, in_cfg: F) -> ast::Crate where
     ctxt.fold_crate(krate)
 }
 
-fn filter_view_item<F>(cx: &mut Context<F>,
-                       view_item: ast::ViewItem)
-                       -> Option<ast::ViewItem> where
-    F: FnMut(&[ast::Attribute]) -> bool
-{
-    if view_item_in_cfg(cx, &view_item) {
-        Some(view_item)
-    } else {
-        None
-    }
-}
-
 fn fold_mod<F>(cx: &mut Context<F>,
-               ast::Mod {inner,
-               view_items, items}: ast::Mod) -> ast::Mod where
+               ast::Mod {inner, items}: ast::Mod)
+               -> ast::Mod where
     F: FnMut(&[ast::Attribute]) -> bool
 {
     ast::Mod {
         inner: inner,
-        view_items: view_items.into_iter().filter_map(|a| {
-            filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
-        }).collect(),
         items: items.into_iter().flat_map(|a| {
             cx.fold_item(a).into_iter()
         }).collect()
@@ -104,15 +89,12 @@ fn filter_foreign_item<F>(cx: &mut Context<F>,
 }
 
 fn fold_foreign_mod<F>(cx: &mut Context<F>,
-                       ast::ForeignMod {abi, view_items, items}: ast::ForeignMod)
+                       ast::ForeignMod {abi, items}: ast::ForeignMod)
                        -> ast::ForeignMod where
     F: FnMut(&[ast::Attribute]) -> bool
 {
     ast::ForeignMod {
         abi: abi,
-        view_items: view_items.into_iter().filter_map(|a| {
-            filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
-        }).collect(),
         items: items.into_iter()
                     .filter_map(|a| filter_foreign_item(cx, a))
                     .collect()
@@ -216,18 +198,14 @@ fn retain_stmt<F>(cx: &mut Context<F>, stmt: &ast::Stmt) -> bool where
 fn fold_block<F>(cx: &mut Context<F>, b: P<ast::Block>) -> P<ast::Block> where
     F: FnMut(&[ast::Attribute]) -> bool
 {
-    b.map(|ast::Block {id, view_items, stmts, expr, rules, span}| {
+    b.map(|ast::Block {id, stmts, expr, rules, span}| {
         let resulting_stmts: Vec<P<ast::Stmt>> =
             stmts.into_iter().filter(|a| retain_stmt(cx, &**a)).collect();
         let resulting_stmts = resulting_stmts.into_iter()
             .flat_map(|stmt| cx.fold_stmt(stmt).into_iter())
             .collect();
-        let filtered_view_items = view_items.into_iter().filter_map(|a| {
-            filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
-        }).collect();
         ast::Block {
             id: id,
-            view_items: filtered_view_items,
             stmts: resulting_stmts,
             expr: expr.map(|x| cx.fold_expr(x)),
             rules: rules,
@@ -267,12 +245,6 @@ fn foreign_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ForeignItem) -> bool
     return (cx.in_cfg)(item.attrs.as_slice());
 }
 
-fn view_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ViewItem) -> bool where
-    F: FnMut(&[ast::Attribute]) -> bool
-{
-    return (cx.in_cfg)(item.attrs.as_slice());
-}
-
 fn trait_method_in_cfg<F>(cx: &mut Context<F>, meth: &ast::TraitItem) -> bool where
     F: FnMut(&[ast::Attribute]) -> bool
 {
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 8773c0f2f79..92619cf42e4 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -97,7 +97,6 @@ pub trait AstBuilder {
              expr: Option<P<ast::Expr>>) -> P<ast::Block>;
     fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block>;
     fn block_all(&self, span: Span,
-                 view_items: Vec<ast::ViewItem>,
                  stmts: Vec<P<ast::Stmt>>,
                  expr: Option<P<ast::Expr>>) -> P<ast::Block>;
 
@@ -242,7 +241,7 @@ pub trait AstBuilder {
 
     fn item_mod(&self, span: Span, inner_span: Span,
                 name: Ident, attrs: Vec<ast::Attribute>,
-                vi: Vec<ast::ViewItem> , items: Vec<P<ast::Item>> ) -> P<ast::Item>;
+                items: Vec<P<ast::Item>>) -> P<ast::Item>;
 
     fn item_static(&self,
                    span: Span,
@@ -280,15 +279,15 @@ pub trait AstBuilder {
                        value: ast::Lit_)
                        -> P<ast::MetaItem>;
 
-    fn view_use(&self, sp: Span,
-                vis: ast::Visibility, vp: P<ast::ViewPath>) -> ast::ViewItem;
-    fn view_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> ast::ViewItem;
-    fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
-                        ident: ast::Ident, path: ast::Path) -> ast::ViewItem;
-    fn view_use_list(&self, sp: Span, vis: ast::Visibility,
-                     path: Vec<ast::Ident> , imports: &[ast::Ident]) -> ast::ViewItem;
-    fn view_use_glob(&self, sp: Span,
-                     vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem;
+    fn item_use(&self, sp: Span,
+                vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item>;
+    fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item>;
+    fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
+                        ident: ast::Ident, path: ast::Path) -> P<ast::Item>;
+    fn item_use_list(&self, sp: Span, vis: ast::Visibility,
+                     path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item>;
+    fn item_use_glob(&self, sp: Span,
+                     vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item>;
 }
 
 impl<'a> AstBuilder for ExtCtxt<'a> {
@@ -519,7 +518,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     fn block(&self, span: Span, stmts: Vec<P<ast::Stmt>>,
              expr: Option<P<Expr>>) -> P<ast::Block> {
-        self.block_all(span, Vec::new(), stmts, expr)
+        self.block_all(span, stmts, expr)
     }
 
     fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> P<ast::Stmt> {
@@ -528,15 +527,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
-        self.block_all(expr.span, Vec::new(), Vec::new(), Some(expr))
+        self.block_all(expr.span, Vec::new(), Some(expr))
     }
     fn block_all(&self,
                  span: Span,
-                 view_items: Vec<ast::ViewItem>,
                  stmts: Vec<P<ast::Stmt>>,
                  expr: Option<P<ast::Expr>>) -> P<ast::Block> {
             P(ast::Block {
-               view_items: view_items,
                stmts: stmts,
                expr: expr,
                id: ast::DUMMY_NODE_ID,
@@ -1031,16 +1028,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     fn item_mod(&self, span: Span, inner_span: Span, name: Ident,
-                attrs: Vec<ast::Attribute> ,
-                vi: Vec<ast::ViewItem> ,
-                items: Vec<P<ast::Item>> ) -> P<ast::Item> {
+                attrs: Vec<ast::Attribute>,
+                items: Vec<P<ast::Item>>) -> P<ast::Item> {
         self.item(
             span,
             name,
             attrs,
             ast::ItemMod(ast::Mod {
                 inner: inner_span,
-                view_items: vi,
                 items: items,
             })
         )
@@ -1101,47 +1096,47 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         P(respan(sp, ast::MetaNameValue(name, respan(sp, value))))
     }
 
-    fn view_use(&self, sp: Span,
-                vis: ast::Visibility, vp: P<ast::ViewPath>) -> ast::ViewItem {
-        ast::ViewItem {
-            node: ast::ViewItemUse(vp),
-            attrs: Vec::new(),
+    fn item_use(&self, sp: Span,
+                vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item> {
+        P(ast::Item {
+            id: ast::DUMMY_NODE_ID,
+            ident: special_idents::invalid,
+            attrs: vec![],
+            node: ast::ItemUse(vp),
             vis: vis,
             span: sp
-        }
+        })
     }
 
-    fn view_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> ast::ViewItem {
+    fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item> {
         let last = path.segments.last().unwrap().identifier;
-        self.view_use_simple_(sp, vis, last, path)
+        self.item_use_simple_(sp, vis, last, path)
     }
 
-    fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
-                        ident: ast::Ident, path: ast::Path) -> ast::ViewItem {
-        self.view_use(sp, vis,
+    fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
+                        ident: ast::Ident, path: ast::Path) -> P<ast::Item> {
+        self.item_use(sp, vis,
                       P(respan(sp,
                                ast::ViewPathSimple(ident,
-                                                   path,
-                                                   ast::DUMMY_NODE_ID))))
+                                                   path))))
     }
 
-    fn view_use_list(&self, sp: Span, vis: ast::Visibility,
-                     path: Vec<ast::Ident> , imports: &[ast::Ident]) -> ast::ViewItem {
+    fn item_use_list(&self, sp: Span, vis: ast::Visibility,
+                     path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item> {
         let imports = imports.iter().map(|id| {
             respan(sp, ast::PathListIdent { name: *id, id: ast::DUMMY_NODE_ID })
         }).collect();
 
-        self.view_use(sp, vis,
+        self.item_use(sp, vis,
                       P(respan(sp,
                                ast::ViewPathList(self.path(sp, path),
-                                                 imports,
-                                                 ast::DUMMY_NODE_ID))))
+                                                 imports))))
     }
 
-    fn view_use_glob(&self, sp: Span,
-                     vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem {
-        self.view_use(sp, vis,
+    fn item_use_glob(&self, sp: Span,
+                     vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item> {
+        self.item_use(sp, vis,
                       P(respan(sp,
-                               ast::ViewPathGlob(self.path(sp, path), ast::DUMMY_NODE_ID))))
+                               ast::ViewPathGlob(self.path(sp, path)))))
     }
 }
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index 583f316289f..272b0464010 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -1073,7 +1073,7 @@ impl<'a> MethodDef<'a> {
             //   <delegated expression referring to __self0_vi, et al.>
             // }
             let arm_expr = cx.expr_block(
-                cx.block_all(sp, Vec::new(), index_let_stmts, Some(arm_expr)));
+                cx.block_all(sp, index_let_stmts, Some(arm_expr)));
 
             // Builds arm:
             // _ => { let __self0_vi = ...;
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 9aa602b39b4..629991799e7 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -206,7 +206,6 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
                     // wrap the if-let expr in a block
                     let span = els.span;
                     let blk = P(ast::Block {
-                        view_items: vec![],
                         stmts: vec![],
                         expr: Some(P(els)),
                         id: ast::DUMMY_NODE_ID,
@@ -799,8 +798,7 @@ pub fn expand_block(blk: P<Block>, fld: &mut MacroExpander) -> P<Block> {
 
 // expand the elements of a block.
 pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> {
-    b.map(|Block {id, view_items, stmts, expr, rules, span}| {
-        let new_view_items = view_items.into_iter().map(|x| fld.fold_view_item(x)).collect();
+    b.map(|Block {id, stmts, expr, rules, span}| {
         let new_stmts = stmts.into_iter().flat_map(|x| {
             // perform all pending renames
             let renamed_stmt = {
@@ -821,7 +819,6 @@ pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> {
         });
         Block {
             id: fld.new_id(id),
-            view_items: new_view_items,
             stmts: new_stmts,
             expr: new_expr,
             rules: rules,
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 5339c3d77c6..7e345a2d078 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -352,18 +352,11 @@ pub mod rt {
     impl<'a> ExtParseUtils for ExtCtxt<'a> {
 
         fn parse_item(&self, s: String) -> P<ast::Item> {
-            let res = parse::parse_item_from_source_str(
+            parse::parse_item_from_source_str(
                 "<quote expansion>".to_string(),
                 s,
                 self.cfg(),
-                self.parse_sess());
-            match res {
-                Some(ast) => ast,
-                None => {
-                    error!("parse error");
-                    panic!()
-                }
-            }
+                self.parse_sess()).expect("parse error")
         }
 
         fn parse_stmt(&self, s: String) -> P<ast::Stmt> {
@@ -767,7 +760,6 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     vector.extend(mk_tts(cx, &tts[]).into_iter());
     let block = cx.expr_block(
         cx.block_all(sp,
-                     Vec::new(),
                      vector,
                      Some(cx.expr_ident(sp, id_ext("tt")))));
 
@@ -778,18 +770,18 @@ fn expand_wrapper(cx: &ExtCtxt,
                   sp: Span,
                   cx_expr: P<ast::Expr>,
                   expr: P<ast::Expr>) -> P<ast::Expr> {
-    let uses = [
-        &["syntax", "ext", "quote", "rt"],
-    ].iter().map(|path| {
-        let path = path.iter().map(|s| s.to_string()).collect();
-        cx.view_use_glob(sp, ast::Inherited, ids_ext(path))
-    }).collect();
-
     // Explicitly borrow to avoid moving from the invoker (#16992)
     let cx_expr_borrow = cx.expr_addr_of(sp, cx.expr_deref(sp, cx_expr));
     let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr_borrow);
 
-    cx.expr_block(cx.block_all(sp, uses, vec!(stmt_let_ext_cx), Some(expr)))
+    let stmts = [
+        &["syntax", "ext", "quote", "rt"],
+    ].iter().map(|path| {
+        let path = path.iter().map(|s| s.to_string()).collect();
+        cx.stmt_item(sp, cx.item_use_glob(sp, ast::Inherited, ids_ext(path)))
+    }).chain(Some(stmt_let_ext_cx).into_iter()).collect();
+
+    cx.expr_block(cx.block_all(sp, stmts, Some(expr)))
 }
 
 fn expand_parse_call(cx: &ExtCtxt,
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 13b7944998a..762a1dcbfc3 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -64,7 +64,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
 
     ("rustc_diagnostic_macros", Active),
     ("unboxed_closures", Active),
-    ("import_shadowing", Active),
+    ("import_shadowing", Removed),
     ("advanced_slice_patterns", Active),
     ("tuple_indexing", Accepted),
     ("associated_types", Accepted),
@@ -127,7 +127,6 @@ enum Status {
 pub struct Features {
     pub unboxed_closures: bool,
     pub rustc_diagnostic_macros: bool,
-    pub import_shadowing: bool,
     pub visible_private_types: bool,
     pub quote: bool,
     pub old_orphan_check: bool,
@@ -139,7 +138,6 @@ impl Features {
         Features {
             unboxed_closures: false,
             rustc_diagnostic_macros: false,
-            import_shadowing: false,
             visible_private_types: false,
             quote: false,
             old_orphan_check: false,
@@ -228,22 +226,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
         }
     }
 
-    fn visit_view_item(&mut self, i: &ast::ViewItem) {
-        match i.node {
-            ast::ViewItemUse(..) => {}
-            ast::ViewItemExternCrate(..) => {
-                for attr in i.attrs.iter() {
-                    if attr.check_name("plugin") {
-                        self.gate_feature("plugin", attr.span,
-                                          "compiler plugins are experimental \
-                                           and possibly buggy");
-                    }
-                }
-            }
-        }
-        visit::walk_view_item(self, i)
-    }
-
     fn visit_item(&mut self, i: &ast::Item) {
         for attr in i.attrs.iter() {
             if attr.name() == "thread_local" {
@@ -262,6 +244,14 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
             }
         }
         match i.node {
+            ast::ItemExternCrate(_) => {
+                if attr::contains_name(&i.attrs[], "plugin") {
+                    self.gate_feature("plugin", i.span,
+                                      "compiler plugins are experimental \
+                                       and possibly buggy");
+                }
+            }
+
             ast::ItemForeignMod(ref foreign_module) => {
                 if attr::contains_name(&i.attrs[], "link_args") {
                     self.gate_feature("link_args", i.span,
@@ -537,7 +527,6 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
     (Features {
         unboxed_closures: cx.has_feature("unboxed_closures"),
         rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
-        import_shadowing: cx.has_feature("import_shadowing"),
         visible_private_types: cx.has_feature("visible_private_types"),
         quote: cx.has_feature("quote"),
         old_orphan_check: cx.has_feature("old_orphan_check"),
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index a876b378060..9f8427cc8ae 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -78,10 +78,6 @@ pub trait Folder : Sized {
         noop_fold_view_path(view_path, self)
     }
 
-    fn fold_view_item(&mut self, vi: ViewItem) -> ViewItem {
-        noop_fold_view_item(vi, self)
-    }
-
     fn fold_foreign_item(&mut self, ni: P<ForeignItem>) -> P<ForeignItem> {
         noop_fold_foreign_item(ni, self)
     }
@@ -349,16 +345,13 @@ pub fn noop_fold_meta_items<T: Folder>(meta_items: Vec<P<MetaItem>>, fld: &mut T
 pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<ViewPath> {
     view_path.map(|Spanned {node, span}| Spanned {
         node: match node {
-            ViewPathSimple(ident, path, node_id) => {
-                let id = fld.new_id(node_id);
-                ViewPathSimple(ident, fld.fold_path(path), id)
+            ViewPathSimple(ident, path) => {
+                ViewPathSimple(ident, fld.fold_path(path))
             }
-            ViewPathGlob(path, node_id) => {
-                let id = fld.new_id(node_id);
-                ViewPathGlob(fld.fold_path(path), id)
+            ViewPathGlob(path) => {
+                ViewPathGlob(fld.fold_path(path))
             }
-            ViewPathList(path, path_list_idents, node_id) => {
-                let id = fld.new_id(node_id);
+            ViewPathList(path, path_list_idents) => {
                 ViewPathList(fld.fold_path(path),
                              path_list_idents.move_map(|path_list_ident| {
                                 Spanned {
@@ -373,8 +366,7 @@ pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<
                                     },
                                     span: fld.new_span(path_list_ident.span)
                                 }
-                             }),
-                             id)
+                             }))
             }
         },
         span: fld.new_span(span)
@@ -470,11 +462,10 @@ pub fn noop_fold_qpath<T: Folder>(qpath: P<QPath>, fld: &mut T) -> P<QPath> {
     })
 }
 
-pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, view_items, items}: ForeignMod,
+pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, items}: ForeignMod,
                                         fld: &mut T) -> ForeignMod {
     ForeignMod {
         abi: abi,
-        view_items: view_items.move_map(|x| fld.fold_view_item(x)),
         items: items.move_map(|x| fld.fold_foreign_item(x)),
     }
 }
@@ -953,28 +944,9 @@ fn noop_fold_variant_arg<T: Folder>(VariantArg {id, ty}: VariantArg, folder: &mu
     }
 }
 
-pub fn noop_fold_view_item<T: Folder>(ViewItem {node, attrs, vis, span}: ViewItem,
-                                      folder: &mut T) -> ViewItem {
-    ViewItem {
-        node: match node {
-            ViewItemExternCrate(ident, string, node_id) => {
-                ViewItemExternCrate(ident, string,
-                                    folder.new_id(node_id))
-            }
-            ViewItemUse(view_path) => {
-                ViewItemUse(folder.fold_view_path(view_path))
-            }
-        },
-        attrs: attrs.move_map(|a| folder.fold_attribute(a)),
-        vis: vis,
-        span: folder.new_span(span)
-    }
-}
-
 pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
-    b.map(|Block {id, view_items, stmts, expr, rules, span}| Block {
+    b.map(|Block {id, stmts, expr, rules, span}| Block {
         id: folder.new_id(id),
-        view_items: view_items.move_map(|x| folder.fold_view_item(x)),
         stmts: stmts.into_iter().flat_map(|s| folder.fold_stmt(s).into_iter()).collect(),
         expr: expr.map(|x| folder.fold_expr(x)),
         rules: rules,
@@ -984,6 +956,10 @@ pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
 
 pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
     match i {
+        ItemExternCrate(string) => ItemExternCrate(string),
+        ItemUse(view_path) => {
+            ItemUse(folder.fold_view_path(view_path))
+        }
         ItemStatic(t, m, e) => {
             ItemStatic(folder.fold_ty(t), m, folder.fold_expr(e))
         }
@@ -1103,10 +1079,9 @@ pub fn noop_fold_type_method<T: Folder>(m: TypeMethod, fld: &mut T) -> TypeMetho
     }
 }
 
-pub fn noop_fold_mod<T: Folder>(Mod {inner, view_items, items}: Mod, folder: &mut T) -> Mod {
+pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod {
     Mod {
         inner: folder.new_span(inner),
-        view_items: view_items.move_map(|x| folder.fold_view_item(x)),
         items: items.into_iter().flat_map(|x| folder.fold_item(x).into_iter()).collect(),
     }
 }
@@ -1137,9 +1112,8 @@ pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, mut exported_mac
         }
         None => (ast::Mod {
             inner: span,
-            view_items: Vec::new(),
-            items: Vec::new(),
-        }, Vec::new(), span)
+            items: vec![],
+        }, vec![], span)
     };
 
     for def in exported_macros.iter_mut() {
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index a73911c809a..8cb7ee5b337 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -757,11 +757,10 @@ mod test {
     use attr::{first_attr_value_str_by_name, AttrMetaMethods};
     use parse::parser::Parser;
     use parse::token::{str_to_ident};
-    use print::pprust::view_item_to_string;
+    use print::pprust::item_to_string;
     use ptr::P;
     use util::parser_testing::{string_to_tts, string_to_parser};
-    use util::parser_testing::{string_to_expr, string_to_item};
-    use util::parser_testing::{string_to_stmt, string_to_view_item};
+    use util::parser_testing::{string_to_expr, string_to_item, string_to_stmt};
 
     // produce a codemap::span
     fn sp(a: u32, b: u32) -> Span {
@@ -1079,7 +1078,6 @@ mod test {
                                         }
                                     },
                                     P(ast::Block {
-                                        view_items: Vec::new(),
                                         stmts: vec!(P(Spanned{
                                             node: ast::StmtSemi(P(ast::Expr{
                                                 id: ast::DUMMY_NODE_ID,
@@ -1111,25 +1109,25 @@ mod test {
 
     #[test] fn parse_use() {
         let use_s = "use foo::bar::baz;";
-        let vitem = string_to_view_item(use_s.to_string());
-        let vitem_s = view_item_to_string(&vitem);
+        let vitem = string_to_item(use_s.to_string()).unwrap();
+        let vitem_s = item_to_string(&*vitem);
         assert_eq!(&vitem_s[], use_s);
 
         let use_s = "use foo::bar as baz;";
-        let vitem = string_to_view_item(use_s.to_string());
-        let vitem_s = view_item_to_string(&vitem);
+        let vitem = string_to_item(use_s.to_string()).unwrap();
+        let vitem_s = item_to_string(&*vitem);
         assert_eq!(&vitem_s[], use_s);
     }
 
     #[test] fn parse_extern_crate() {
         let ex_s = "extern crate foo;";
-        let vitem = string_to_view_item(ex_s.to_string());
-        let vitem_s = view_item_to_string(&vitem);
+        let vitem = string_to_item(ex_s.to_string()).unwrap();
+        let vitem_s = item_to_string(&*vitem);
         assert_eq!(&vitem_s[], ex_s);
 
         let ex_s = "extern crate \"foo\" as bar;";
-        let vitem = string_to_view_item(ex_s.to_string());
-        let vitem_s = view_item_to_string(&vitem);
+        let vitem = string_to_item(ex_s.to_string()).unwrap();
+        let vitem_s = item_to_string(&*vitem);
         assert_eq!(&vitem_s[], ex_s);
     }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 20946c48884..fc02cb4acb8 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 pub use self::PathParsingMode::*;
-use self::ItemOrViewItem::*;
 
 use abi;
 use ast::{AssociatedType, BareFnTy};
@@ -35,6 +34,7 @@ use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRet
 use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
 use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
+use ast::{ItemExternCrate, ItemUse};
 use ast::{LifetimeDef, Lit, Lit_};
 use ast::{LitBool, LitChar, LitByte, LitBinary};
 use ast::{LitStr, LitInt, Local, LocalLet};
@@ -59,7 +59,6 @@ use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath
 use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
 use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
 use ast::{UnnamedField, UnsafeBlock};
-use ast::{ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::{Visibility, WhereClause};
 use ast;
@@ -122,14 +121,9 @@ pub enum BoundParsingMode {
     Modified,
 }
 
-enum ItemOrViewItem {
-    /// Indicates a failure to parse any kind of item. The attributes are
-    /// returned.
-    IoviNone(Vec<Attribute>),
-    IoviItem(P<Item>),
-    IoviForeignItem(P<ForeignItem>),
-    IoviViewItem(ViewItem)
-}
+/// The `Err` case indicates a failure to parse any kind of item.
+/// The attributes are returned.
+type MaybeItem = Result<P<Item>, Vec<Attribute>>;
 
 
 /// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
@@ -231,19 +225,6 @@ macro_rules! maybe_whole {
             }
         }
     );
-    (iovi $p:expr, $constructor:ident) => (
-        {
-            let found = match ($p).token {
-                token::Interpolated(token::$constructor(_)) => {
-                    Some(($p).bump_and_get())
-                }
-                _ => None
-            };
-            if let Some(token::Interpolated(token::$constructor(x))) = found {
-                return IoviItem(x.clone());
-            }
-        }
-    );
     (pair_empty $p:expr, $constructor:ident) => (
         {
             let found = match ($p).token {
@@ -269,14 +250,6 @@ fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
     lhs
 }
 
-
-struct ParsedItemsAndViewItems {
-    attrs_remaining: Vec<Attribute>,
-    view_items: Vec<ViewItem>,
-    items: Vec<P<Item>> ,
-    foreign_items: Vec<P<ForeignItem>>
-}
-
 /* ident is handled by common.rs */
 
 pub struct Parser<'a> {
@@ -3032,8 +3005,7 @@ impl<'a> Parser<'a> {
         let body = self.parse_expr();
         let fakeblock = P(ast::Block {
             id: ast::DUMMY_NODE_ID,
-            view_items: Vec::new(),
-            stmts: Vec::new(),
+            stmts: vec![],
             span: body.span,
             expr: Some(body),
             rules: DefaultBlock,
@@ -3731,20 +3703,13 @@ impl<'a> Parser<'a> {
         } else {
             let found_attrs = !item_attrs.is_empty();
             let item_err = Parser::expected_item_err(&item_attrs[]);
-            match self.parse_item_or_view_item(item_attrs, false) {
-                IoviItem(i) => {
+            match self.parse_item_(item_attrs, false) {
+                Ok(i) => {
                     let hi = i.span.hi;
                     let decl = P(spanned(lo, hi, DeclItem(i)));
                     P(spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
                 }
-                IoviViewItem(vi) => {
-                    self.span_fatal(vi.span,
-                                    "view items must be declared at the top of the block");
-                }
-                IoviForeignItem(_) => {
-                    self.fatal("foreign items are not allowed here");
-                }
-                IoviNone(_) => {
+                Err(_) => {
                     if found_attrs {
                         let last_span = self.last_span;
                         self.span_err(last_span, item_err);
@@ -3794,36 +3759,17 @@ impl<'a> Parser<'a> {
         (inner, self.parse_block_tail_(lo, DefaultBlock, next))
     }
 
-    /// Precondition: already parsed the '{' or '#{'
-    /// I guess that also means "already parsed the 'impure'" if
-    /// necessary, and this should take a qualifier.
-    /// Some blocks start with "#{"...
+    /// Precondition: already parsed the '{'.
     fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
         self.parse_block_tail_(lo, s, Vec::new())
     }
 
     /// Parse the rest of a block expression or function body
     fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
-                         first_item_attrs: Vec<Attribute> ) -> P<Block> {
-        let mut stmts = Vec::new();
+                         first_item_attrs: Vec<Attribute>) -> P<Block> {
+        let mut stmts = vec![];
         let mut expr = None;
-
-        // wouldn't it be more uniform to parse view items only, here?
-        let ParsedItemsAndViewItems {
-            attrs_remaining,
-            view_items,
-            items,
-            ..
-        } = self.parse_items_and_view_items(first_item_attrs,
-                                            false, false);
-
-        for item in items.into_iter() {
-            let span = item.span;
-            let decl = P(spanned(span.lo, span.hi, DeclItem(item)));
-            stmts.push(P(spanned(span.lo, span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID))));
-        }
-
-        let mut attributes_box = attrs_remaining;
+        let mut attributes_box = first_item_attrs;
 
         while self.token != token::CloseDelim(token::Brace) {
             // parsing items even when they're not allowed lets us give
@@ -3932,7 +3878,6 @@ impl<'a> Parser<'a> {
         let hi = self.span.hi;
         self.bump();
         P(ast::Block {
-            view_items: view_items,
             stmts: stmts,
             expr: expr,
             id: ast::DUMMY_NODE_ID,
@@ -5031,39 +4976,34 @@ impl<'a> Parser<'a> {
                        first_item_attrs: Vec<Attribute>,
                        inner_lo: BytePos)
                        -> Mod {
-        // parse all of the items up to closing or an attribute.
-        // view items are legal here.
-        let ParsedItemsAndViewItems {
-            attrs_remaining,
-            view_items,
-            items: starting_items,
-            ..
-        } = self.parse_items_and_view_items(first_item_attrs, true, true);
-        let mut items: Vec<P<Item>> = starting_items;
-        let attrs_remaining_len = attrs_remaining.len();
+        // Parse all of the items up to closing or an attribute.
+
+        let mut attrs = first_item_attrs;
+        attrs.push_all(&self.parse_outer_attributes()[]);
+        let mut items = vec![];
+
+        loop {
+            match self.parse_item_(attrs, true) {
+                Err(returned_attrs) => {
+                    attrs = returned_attrs;
+                    break
+                }
+                Ok(item) => {
+                    attrs = self.parse_outer_attributes();
+                    items.push(item)
+                }
+            }
+        }
 
         // don't think this other loop is even necessary....
 
-        let mut first = true;
         while self.token != term {
-            let mut attrs = self.parse_outer_attributes();
-            if first {
-                let mut tmp = attrs_remaining.clone();
-                tmp.push_all(&attrs[]);
-                attrs = tmp;
-                first = false;
-            }
-            debug!("parse_mod_items: parse_item_or_view_item(attrs={:?})",
-                   attrs);
-            match self.parse_item_or_view_item(attrs,
-                                               true /* macros allowed */) {
-              IoviItem(item) => items.push(item),
-              IoviViewItem(view_item) => {
-                self.span_fatal(view_item.span,
-                                "view items must be declared at the top of \
-                                 the module");
-              }
-              _ => {
+            let mut attrs = mem::replace(&mut attrs, vec![]);
+            attrs.push_all(&self.parse_outer_attributes()[]);
+            debug!("parse_mod_items: parse_item_(attrs={:?})", attrs);
+            match self.parse_item_(attrs, true /* macros allowed */) {
+              Ok(item) => items.push(item),
+              Err(_) => {
                   let token_str = self.this_token_to_string();
                   self.fatal(&format!("expected item, found `{}`",
                                      token_str)[])
@@ -5071,16 +5011,15 @@ impl<'a> Parser<'a> {
             }
         }
 
-        if first && attrs_remaining_len > 0us {
+        if !attrs.is_empty() {
             // We parsed attributes for the first item but didn't find it
             let last_span = self.last_span;
             self.span_err(last_span,
-                          Parser::expected_item_err(&attrs_remaining[]));
+                          Parser::expected_item_err(&attrs[]));
         }
 
         ast::Mod {
             inner: mk_sp(inner_lo, self.span.lo),
-            view_items: view_items,
             items: items
         }
     }
@@ -5298,23 +5237,12 @@ impl<'a> Parser<'a> {
     /// parse_foreign_items.
     fn parse_foreign_mod_items(&mut self,
                                abi: abi::Abi,
-                               first_item_attrs: Vec<Attribute> )
+                               first_item_attrs: Vec<Attribute>)
                                -> ForeignMod {
-        let ParsedItemsAndViewItems {
-            attrs_remaining,
-            view_items,
-            items: _,
-            foreign_items,
-        } = self.parse_foreign_items(first_item_attrs, true);
-        if !attrs_remaining.is_empty() {
-            let last_span = self.last_span;
-            self.span_err(last_span,
-                          Parser::expected_item_err(&attrs_remaining[]));
-        }
+        let foreign_items = self.parse_foreign_items(first_item_attrs);
         assert!(self.token == token::CloseDelim(token::Brace));
         ast::ForeignMod {
             abi: abi,
-            view_items: view_items,
             items: foreign_items
         }
     }
@@ -5329,8 +5257,8 @@ impl<'a> Parser<'a> {
     fn parse_item_extern_crate(&mut self,
                                 lo: BytePos,
                                 visibility: Visibility,
-                                attrs: Vec<Attribute> )
-                                -> ItemOrViewItem {
+                                attrs: Vec<Attribute>)
+                                -> P<Item> {
 
         let span = self.span;
         let (maybe_path, ident) = match self.token {
@@ -5374,12 +5302,13 @@ impl<'a> Parser<'a> {
             }
         };
 
-        IoviViewItem(ast::ViewItem {
-                node: ViewItemExternCrate(ident, maybe_path, ast::DUMMY_NODE_ID),
-                attrs: attrs,
-                vis: visibility,
-                span: mk_sp(lo, self.last_span.hi)
-            })
+        let last_span = self.last_span;
+        self.mk_item(lo,
+                     last_span.hi,
+                     ident,
+                     ItemExternCrate(maybe_path),
+                     visibility,
+                     attrs)
     }
 
     /// Parse `extern` for foreign ABIs
@@ -5396,8 +5325,8 @@ impl<'a> Parser<'a> {
                               lo: BytePos,
                               opt_abi: Option<abi::Abi>,
                               visibility: Visibility,
-                              attrs: Vec<Attribute> )
-                              -> ItemOrViewItem {
+                              attrs: Vec<Attribute>)
+                              -> P<Item> {
 
         self.expect(&token::OpenDelim(token::Brace));
 
@@ -5408,13 +5337,12 @@ impl<'a> Parser<'a> {
         self.expect(&token::CloseDelim(token::Brace));
 
         let last_span = self.last_span;
-        let item = self.mk_item(lo,
-                                last_span.hi,
-                                special_idents::invalid,
-                                ItemForeignMod(m),
-                                visibility,
-                                maybe_append(attrs, Some(inner)));
-        return IoviItem(item);
+        self.mk_item(lo,
+                     last_span.hi,
+                     special_idents::invalid,
+                     ItemForeignMod(m),
+                     visibility,
+                     maybe_append(attrs, Some(inner)))
     }
 
     /// Parse type Foo = Bar;
@@ -5556,14 +5484,12 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parse one of the items or view items allowed by the
-    /// flags; on failure, return IoviNone.
+    /// Parse one of the items allowed by the flags; on failure,
+    /// return `Err(remaining_attrs)`.
     /// NB: this function no longer parses the items inside an
     /// extern crate.
-    fn parse_item_or_view_item(&mut self,
-                               attrs: Vec<Attribute> ,
-                               macros_allowed: bool)
-                               -> ItemOrViewItem {
+    fn parse_item_(&mut self, attrs: Vec<Attribute>,
+                   macros_allowed: bool) -> MaybeItem {
         let nt_item = match self.token {
             token::Interpolated(token::NtItem(ref item)) => {
                 Some((**item).clone())
@@ -5576,7 +5502,7 @@ impl<'a> Parser<'a> {
                 let mut attrs = attrs;
                 mem::swap(&mut item.attrs, &mut attrs);
                 item.attrs.extend(attrs.into_iter());
-                return IoviItem(P(item));
+                return Ok(P(item));
             }
             None => {}
         }
@@ -5585,22 +5511,24 @@ impl<'a> Parser<'a> {
 
         let visibility = self.parse_visibility();
 
-        // must be a view item:
         if self.eat_keyword(keywords::Use) {
-            // USE ITEM (IoviViewItem)
-            let view_item = self.parse_use();
+            // USE ITEM
+            let item_ = ItemUse(self.parse_view_path());
             self.expect(&token::Semi);
-            return IoviViewItem(ast::ViewItem {
-                node: view_item,
-                attrs: attrs,
-                vis: visibility,
-                span: mk_sp(lo, self.last_span.hi)
-            });
+
+            let last_span = self.last_span;
+            let item = self.mk_item(lo,
+                                    last_span.hi,
+                                    token::special_idents::invalid,
+                                    item_,
+                                    visibility,
+                                    attrs);
+            return Ok(item);
         }
-        // either a view item or an item:
+
         if self.eat_keyword(keywords::Extern) {
             if self.eat_keyword(keywords::Crate) {
-                return self.parse_item_extern_crate(lo, visibility, attrs);
+                return Ok(self.parse_item_extern_crate(lo, visibility, attrs));
             }
 
             let opt_abi = self.parse_opt_abi();
@@ -5617,9 +5545,9 @@ impl<'a> Parser<'a> {
                                         item_,
                                         visibility,
                                         maybe_append(attrs, extra_attrs));
-                return IoviItem(item);
+                return Ok(item);
             } else if self.check(&token::OpenDelim(token::Brace)) {
-                return self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs);
+                return Ok(self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs));
             }
 
             let span = self.span;
@@ -5634,7 +5562,6 @@ impl<'a> Parser<'a> {
             self.span_err(span, "`virtual` structs have been removed from the language");
         }
 
-        // the rest are all guaranteed to be items:
         if self.token.is_keyword(keywords::Static) {
             // STATIC ITEM
             self.bump();
@@ -5647,7 +5574,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.token.is_keyword(keywords::Const) {
             // CONST ITEM
@@ -5665,7 +5592,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.token.is_keyword(keywords::Unsafe) &&
             self.look_ahead(1us, |t| t.is_keyword(keywords::Trait))
@@ -5682,7 +5609,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.token.is_keyword(keywords::Unsafe) &&
             self.look_ahead(1us, |t| t.is_keyword(keywords::Impl))
@@ -5698,7 +5625,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.token.is_keyword(keywords::Fn) {
             // FUNCTION ITEM
@@ -5712,7 +5639,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.token.is_keyword(keywords::Unsafe)
             && self.look_ahead(1us, |t| *t != token::OpenDelim(token::Brace)) {
@@ -5733,7 +5660,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.eat_keyword(keywords::Mod) {
             // MODULE ITEM
@@ -5746,7 +5673,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.eat_keyword(keywords::Type) {
             // TYPE ITEM
@@ -5758,7 +5685,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.eat_keyword(keywords::Enum) {
             // ENUM ITEM
@@ -5770,7 +5697,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.eat_keyword(keywords::Trait) {
             // TRAIT ITEM
@@ -5783,7 +5710,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.eat_keyword(keywords::Impl) {
             // IMPL ITEM
@@ -5795,7 +5722,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         if self.eat_keyword(keywords::Struct) {
             // STRUCT ITEM
@@ -5807,32 +5734,30 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return IoviItem(item);
+            return Ok(item);
         }
         self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
     }
 
-    /// Parse a foreign item; on failure, return IoviNone.
-    fn parse_foreign_item(&mut self,
-                          attrs: Vec<Attribute> ,
-                          macros_allowed: bool)
-                          -> ItemOrViewItem {
-        maybe_whole!(iovi self, NtItem);
+    /// Parse a foreign item; on failure, return `Err(remaining_attrs)`.
+    fn parse_foreign_item(&mut self, attrs: Vec<Attribute>)
+                          -> Result<P<ForeignItem>, Vec<Attribute>> {
         let lo = self.span.lo;
 
         let visibility = self.parse_visibility();
 
         if self.token.is_keyword(keywords::Static) {
             // FOREIGN STATIC ITEM
-            let item = self.parse_item_foreign_static(visibility, attrs);
-            return IoviForeignItem(item);
+            return Ok(self.parse_item_foreign_static(visibility, attrs));
         }
         if self.token.is_keyword(keywords::Fn) || self.token.is_keyword(keywords::Unsafe) {
             // FOREIGN FUNCTION ITEM
-            let item = self.parse_item_foreign_fn(visibility, attrs);
-            return IoviForeignItem(item);
+            return Ok(self.parse_item_foreign_fn(visibility, attrs));
         }
-        self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
+
+        // FIXME #5668: this will occur for a macro invocation:
+        let item = try!(self.parse_macro_use_or_failure(attrs, true, lo, visibility));
+        self.span_fatal(item.span, "macros cannot expand to foreign items");
     }
 
     /// This is the fall-through for parsing items.
@@ -5842,7 +5767,7 @@ impl<'a> Parser<'a> {
         macros_allowed: bool,
         lo: BytePos,
         visibility: Visibility
-    ) -> ItemOrViewItem {
+    ) -> MaybeItem {
         if macros_allowed && !self.token.is_any_keyword()
                 && self.look_ahead(1, |t| *t == token::Not)
                 && (self.look_ahead(2, |t| t.is_plain_ident())
@@ -5891,7 +5816,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     attrs);
-            return IoviItem(item);
+            return Ok(item);
         }
 
         // FAILURE TO PARSE ITEM
@@ -5902,7 +5827,7 @@ impl<'a> Parser<'a> {
                 self.span_fatal(last_span, "unmatched visibility `pub`");
             }
         }
-        return IoviNone(attrs);
+        Err(attrs)
     }
 
     pub fn parse_item_with_outer_attributes(&mut self) -> Option<P<Item>> {
@@ -5911,30 +5836,9 @@ impl<'a> Parser<'a> {
     }
 
     pub fn parse_item(&mut self, attrs: Vec<Attribute>) -> Option<P<Item>> {
-        match self.parse_item_or_view_item(attrs, true) {
-            IoviNone(_) => None,
-            IoviViewItem(_) =>
-                self.fatal("view items are not allowed here"),
-            IoviForeignItem(_) =>
-                self.fatal("foreign items are not allowed here"),
-            IoviItem(item) => Some(item)
-        }
+        self.parse_item_(attrs, true).ok()
     }
 
-    /// Parse a ViewItem, e.g. `use foo::bar` or `extern crate foo`
-    pub fn parse_view_item(&mut self, attrs: Vec<Attribute>) -> ViewItem {
-        match self.parse_item_or_view_item(attrs, false) {
-            IoviViewItem(vi) => vi,
-            _ => self.fatal("expected `use` or `extern crate`"),
-        }
-    }
-
-    /// Parse, e.g., "use a::b::{z,y}"
-    fn parse_use(&mut self) -> ViewItem_ {
-        return ViewItemUse(self.parse_view_path());
-    }
-
-
     /// Matches view_path : MOD? non_global_path as IDENT
     /// | MOD? non_global_path MOD_SEP LBRACE RBRACE
     /// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
@@ -5959,8 +5863,7 @@ impl<'a> Parser<'a> {
                 global: false,
                 segments: Vec::new()
             };
-            return P(spanned(lo, self.span.hi,
-                             ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
+            return P(spanned(lo, self.span.hi, ViewPathList(path, idents)));
         }
 
         let first_ident = self.parse_ident();
@@ -5994,8 +5897,7 @@ impl<'a> Parser<'a> {
                             }
                         }).collect()
                     };
-                    return P(spanned(lo, self.span.hi,
-                                     ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
+                    return P(spanned(lo, self.span.hi, ViewPathList(path, idents)));
                   }
 
                   // foo::bar::*
@@ -6011,8 +5913,7 @@ impl<'a> Parser<'a> {
                             }
                         }).collect()
                     };
-                    return P(spanned(lo, self.span.hi,
-                                     ViewPathGlob(path, ast::DUMMY_NODE_ID)));
+                    return P(spanned(lo, self.span.hi, ViewPathGlob(path)));
                   }
 
                   _ => break
@@ -6033,136 +5934,39 @@ impl<'a> Parser<'a> {
         if self.eat_keyword(keywords::As) {
             rename_to = self.parse_ident()
         }
-        P(spanned(lo,
-                  self.last_span.hi,
-                  ViewPathSimple(rename_to, path, ast::DUMMY_NODE_ID)))
-    }
-
-    /// Parses a sequence of items. Stops when it finds program
-    /// text that can't be parsed as an item
-    /// - mod_items uses extern_mod_allowed = true
-    /// - block_tail_ uses extern_mod_allowed = false
-    fn parse_items_and_view_items(&mut self,
-                                  first_item_attrs: Vec<Attribute> ,
-                                  mut extern_mod_allowed: bool,
-                                  macros_allowed: bool)
-                                  -> ParsedItemsAndViewItems {
-        let mut attrs = first_item_attrs;
-        attrs.push_all(&self.parse_outer_attributes()[]);
-        // First, parse view items.
-        let mut view_items : Vec<ast::ViewItem> = Vec::new();
-        let mut items = Vec::new();
-
-        // I think this code would probably read better as a single
-        // loop with a mutable three-state-variable (for extern crates,
-        // view items, and regular items) ... except that because
-        // of macros, I'd like to delay that entire check until later.
-        loop {
-            match self.parse_item_or_view_item(attrs, macros_allowed) {
-                IoviNone(attrs) => {
-                    return ParsedItemsAndViewItems {
-                        attrs_remaining: attrs,
-                        view_items: view_items,
-                        items: items,
-                        foreign_items: Vec::new()
-                    }
-                }
-                IoviViewItem(view_item) => {
-                    match view_item.node {
-                        ViewItemUse(..) => {
-                            // `extern crate` must precede `use`.
-                            extern_mod_allowed = false;
-                        }
-                        ViewItemExternCrate(..) if !extern_mod_allowed => {
-                            self.span_err(view_item.span,
-                                          "\"extern crate\" declarations are \
-                                           not allowed here");
-                        }
-                        ViewItemExternCrate(..) => {}
-                    }
-                    view_items.push(view_item);
-                }
-                IoviItem(item) => {
-                    items.push(item);
-                    attrs = self.parse_outer_attributes();
-                    break;
-                }
-                IoviForeignItem(_) => {
-                    panic!();
-                }
-            }
-            attrs = self.parse_outer_attributes();
-        }
-
-        // Next, parse items.
-        loop {
-            match self.parse_item_or_view_item(attrs, macros_allowed) {
-                IoviNone(returned_attrs) => {
-                    attrs = returned_attrs;
-                    break
-                }
-                IoviViewItem(view_item) => {
-                    attrs = self.parse_outer_attributes();
-                    self.span_err(view_item.span,
-                                  "`use` and `extern crate` declarations must precede items");
-                }
-                IoviItem(item) => {
-                    attrs = self.parse_outer_attributes();
-                    items.push(item)
-                }
-                IoviForeignItem(_) => {
-                    panic!();
-                }
-            }
-        }
-
-        ParsedItemsAndViewItems {
-            attrs_remaining: attrs,
-            view_items: view_items,
-            items: items,
-            foreign_items: Vec::new()
-        }
+        P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path)))
     }
 
     /// Parses a sequence of foreign items. Stops when it finds program
     /// text that can't be parsed as an item
-    fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
-                           macros_allowed: bool)
-        -> ParsedItemsAndViewItems {
+    fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute>)
+                           -> Vec<P<ForeignItem>> {
         let mut attrs = first_item_attrs;
         attrs.push_all(&self.parse_outer_attributes()[]);
         let mut foreign_items = Vec::new();
         loop {
-            match self.parse_foreign_item(attrs, macros_allowed) {
-                IoviNone(returned_attrs) => {
+            match self.parse_foreign_item(attrs) {
+                Ok(foreign_item) => {
+                    foreign_items.push(foreign_item);
+                }
+                Err(returned_attrs) => {
                     if self.check(&token::CloseDelim(token::Brace)) {
                         attrs = returned_attrs;
                         break
                     }
                     self.unexpected();
-                },
-                IoviViewItem(view_item) => {
-                    // I think this can't occur:
-                    self.span_err(view_item.span,
-                                  "`use` and `extern crate` declarations must precede items");
-                }
-                IoviItem(item) => {
-                    // FIXME #5668: this will occur for a macro invocation:
-                    self.span_fatal(item.span, "macros cannot expand to foreign items");
-                }
-                IoviForeignItem(foreign_item) => {
-                    foreign_items.push(foreign_item);
                 }
             }
             attrs = self.parse_outer_attributes();
         }
 
-        ParsedItemsAndViewItems {
-            attrs_remaining: attrs,
-            view_items: Vec::new(),
-            items: Vec::new(),
-            foreign_items: foreign_items
+        if !attrs.is_empty() {
+            let last_span = self.last_span;
+            self.span_err(last_span,
+                          Parser::expected_item_err(&attrs[]));
         }
+
+        foreign_items
     }
 
     /// Parses a source module as a crate. This is the main
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index af470e14a35..42f156d6a11 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -337,10 +337,6 @@ pub fn item_to_string(i: &ast::Item) -> String {
     $to_string(|s| s.print_item(i))
 }
 
-pub fn view_item_to_string(i: &ast::ViewItem) -> String {
-    $to_string(|s| s.print_view_item(i))
-}
-
 pub fn generics_to_string(generics: &ast::Generics) -> String {
     $to_string(|s| s.print_generics(generics))
 }
@@ -638,9 +634,6 @@ impl<'a> State<'a> {
     pub fn print_mod(&mut self, _mod: &ast::Mod,
                      attrs: &[ast::Attribute]) -> IoResult<()> {
         try!(self.print_inner_attributes(attrs));
-        for vitem in _mod.view_items.iter() {
-            try!(self.print_view_item(vitem));
-        }
         for item in _mod.items.iter() {
             try!(self.print_item(&**item));
         }
@@ -650,9 +643,6 @@ impl<'a> State<'a> {
     pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
                              attrs: &[ast::Attribute]) -> IoResult<()> {
         try!(self.print_inner_attributes(attrs));
-        for vitem in nmod.view_items.iter() {
-            try!(self.print_view_item(vitem));
-        }
         for item in nmod.items.iter() {
             try!(self.print_foreign_item(&**item));
         }
@@ -809,6 +799,28 @@ impl<'a> State<'a> {
         try!(self.print_outer_attributes(&item.attrs[]));
         try!(self.ann.pre(self, NodeItem(item)));
         match item.node {
+            ast::ItemExternCrate(ref optional_path) => {
+                try!(self.head(&visibility_qualified(item.vis,
+                                                     "extern crate")[]));
+                for &(ref p, style) in optional_path.iter() {
+                    try!(self.print_string(p.get(), style));
+                    try!(space(&mut self.s));
+                    try!(word(&mut self.s, "as"));
+                    try!(space(&mut self.s));
+                }
+                try!(self.print_ident(item.ident));
+                try!(word(&mut self.s, ";"));
+                try!(self.end()); // end inner head-block
+                try!(self.end()); // end outer head-block
+            }
+            ast::ItemUse(ref vp) => {
+                try!(self.head(&visibility_qualified(item.vis,
+                                                     "use")[]));
+                try!(self.print_view_path(&**vp));
+                try!(word(&mut self.s, ";"));
+                try!(self.end()); // end inner head-block
+                try!(self.end()); // end outer head-block
+            }
             ast::ItemStatic(ref ty, m, ref expr) => {
                 try!(self.head(&visibility_qualified(item.vis,
                                                     "static")[]));
@@ -1380,9 +1392,6 @@ impl<'a> State<'a> {
 
         try!(self.print_inner_attributes(attrs));
 
-        for vi in blk.view_items.iter() {
-            try!(self.print_view_item(vi));
-        }
         for st in blk.stmts.iter() {
             try!(self.print_stmt(&**st));
         }
@@ -2577,7 +2586,7 @@ impl<'a> State<'a> {
 
     pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> {
         match vp.node {
-            ast::ViewPathSimple(ident, ref path, _) => {
+            ast::ViewPathSimple(ident, ref path) => {
                 try!(self.print_path(path, false));
 
                 // FIXME(#6993) can't compare identifiers directly here
@@ -2591,12 +2600,12 @@ impl<'a> State<'a> {
                 Ok(())
             }
 
-            ast::ViewPathGlob(ref path, _) => {
+            ast::ViewPathGlob(ref path) => {
                 try!(self.print_path(path, false));
                 word(&mut self.s, "::*")
             }
 
-            ast::ViewPathList(ref path, ref idents, _) => {
+            ast::ViewPathList(ref path, ref idents) => {
                 if path.segments.is_empty() {
                     try!(word(&mut self.s, "{"));
                 } else {
@@ -2618,33 +2627,6 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_view_item(&mut self, item: &ast::ViewItem) -> IoResult<()> {
-        try!(self.hardbreak_if_not_bol());
-        try!(self.maybe_print_comment(item.span.lo));
-        try!(self.print_outer_attributes(&item.attrs[]));
-        try!(self.print_visibility(item.vis));
-        match item.node {
-            ast::ViewItemExternCrate(id, ref optional_path, _) => {
-                try!(self.head("extern crate"));
-                for &(ref p, style) in optional_path.iter() {
-                    try!(self.print_string(p.get(), style));
-                    try!(space(&mut self.s));
-                    try!(word(&mut self.s, "as"));
-                    try!(space(&mut self.s));
-                }
-                try!(self.print_ident(id));
-            }
-
-            ast::ViewItemUse(ref vp) => {
-                try!(self.head("use"));
-                try!(self.print_view_path(&**vp));
-            }
-        }
-        try!(word(&mut self.s, ";"));
-        try!(self.end()); // end inner head-block
-        self.end() // end outer head-block
-    }
-
     pub fn print_mutability(&mut self,
                             mutbl: ast::Mutability) -> IoResult<()> {
         match mutbl {
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index 28b9eaa54aa..d75fbcf199d 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -20,8 +20,6 @@ use parse::token;
 use ptr::P;
 use util::small_vector::SmallVector;
 
-use std::mem;
-
 pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>)
                                -> ast::Crate {
     if use_std(&krate) {
@@ -60,20 +58,16 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
             None => token::intern_and_get_ident("std"),
         };
 
-        let mut vis = vec!(ast::ViewItem {
-            node: ast::ViewItemExternCrate(token::str_to_ident("std"),
-                                           Some((actual_crate_name, ast::CookedStr)),
-                                           ast::DUMMY_NODE_ID),
+        krate.module.items.insert(0, P(ast::Item {
+            id: ast::DUMMY_NODE_ID,
+            ident: token::str_to_ident("std"),
             attrs: vec!(
                 attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
                         InternedString::new("macro_use")))),
+            node: ast::ItemExternCrate(Some((actual_crate_name, ast::CookedStr))),
             vis: ast::Inherited,
             span: DUMMY_SP
-        });
-
-        // `extern crate` must be precede `use` items
-        mem::swap(&mut vis, &mut krate.module.view_items);
-        krate.module.view_items.extend(vis.into_iter());
+        }));
 
         // don't add #![no_std] here, that will block the prelude injection later.
         // Add it during the prelude injection instead.
@@ -123,7 +117,7 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
         }
     }
 
-    fn fold_mod(&mut self, ast::Mod {inner, view_items, items}: ast::Mod) -> ast::Mod {
+    fn fold_mod(&mut self, mut mod_: ast::Mod) -> ast::Mod {
         let prelude_path = ast::Path {
             span: DUMMY_SP,
             global: false,
@@ -143,18 +137,11 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
             ],
         };
 
-        let (crates, uses): (Vec<_>, _) = view_items.iter().cloned().partition(|x| {
-            match x.node {
-                ast::ViewItemExternCrate(..) => true,
-                _ => false,
-            }
-        });
-
-        // add prelude after any `extern crate` but before any `use`
-        let mut view_items = crates;
-        let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path, ast::DUMMY_NODE_ID)));
-        view_items.push(ast::ViewItem {
-            node: ast::ViewItemUse(vp),
+        let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path)));
+        mod_.items.insert(0, P(ast::Item {
+            id: ast::DUMMY_NODE_ID,
+            ident: special_idents::invalid,
+            node: ast::ItemUse(vp),
             attrs: vec![ast::Attribute {
                 span: DUMMY_SP,
                 node: ast::Attribute_ {
@@ -170,14 +157,9 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
             }],
             vis: ast::Inherited,
             span: DUMMY_SP,
-        });
-        view_items.extend(uses.into_iter());
-
-        fold::noop_fold_mod(ast::Mod {
-            inner: inner,
-            view_items: view_items,
-            items: items
-        }, self)
+        }));
+
+        fold::noop_fold_mod(mod_, self)
     }
 }
 
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 3022b2b41b7..e5d8e4e5143 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -105,11 +105,11 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
         // Add a special __test module to the crate that will contain code
         // generated for the test harness
         let (mod_, reexport) = mk_test_module(&mut self.cx);
-        folded.module.items.push(mod_);
         match reexport {
-            Some(re) => folded.module.view_items.push(re),
+            Some(re) => folded.module.items.push(re),
             None => {}
         }
+        folded.module.items.push(mod_);
         folded
     }
 
@@ -205,22 +205,19 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
 
 fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
                    tested_submods: Vec<(ast::Ident, ast::Ident)>) -> (P<ast::Item>, ast::Ident) {
-    let mut view_items = Vec::new();
     let super_ = token::str_to_ident("super");
 
-    view_items.extend(tests.into_iter().map(|r| {
-        cx.ext_cx.view_use_simple(DUMMY_SP, ast::Public,
+    let items = tests.into_iter().map(|r| {
+        cx.ext_cx.item_use_simple(DUMMY_SP, ast::Public,
                                   cx.ext_cx.path(DUMMY_SP, vec![super_, r]))
-    }));
-    view_items.extend(tested_submods.into_iter().map(|(r, sym)| {
+    }).chain(tested_submods.into_iter().map(|(r, sym)| {
         let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]);
-        cx.ext_cx.view_use_simple_(DUMMY_SP, ast::Public, r, path)
+        cx.ext_cx.item_use_simple_(DUMMY_SP, ast::Public, r, path)
     }));
 
     let reexport_mod = ast::Mod {
         inner: DUMMY_SP,
-        view_items: view_items,
-        items: Vec::new(),
+        items: items.collect(),
     };
 
     let sym = token::gensym_ident("__test_reexports");
@@ -388,29 +385,29 @@ mod __test {
 
 */
 
-fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
+fn mk_std(cx: &TestCtxt) -> P<ast::Item> {
     let id_test = token::str_to_ident("test");
-    let (vi, vis) = if cx.is_test_crate {
-        (ast::ViewItemUse(
+    let (vi, vis, ident) = if cx.is_test_crate {
+        (ast::ItemUse(
             P(nospan(ast::ViewPathSimple(id_test,
-                                         path_node(vec!(id_test)),
-                                         ast::DUMMY_NODE_ID)))),
-         ast::Public)
+                                         path_node(vec!(id_test)))))),
+         ast::Public, token::special_idents::invalid)
     } else {
-        (ast::ViewItemExternCrate(id_test, None, ast::DUMMY_NODE_ID),
-         ast::Inherited)
+        (ast::ItemExternCrate(None), ast::Inherited, id_test)
     };
-    ast::ViewItem {
+    P(ast::Item {
+        id: ast::DUMMY_NODE_ID,
+        ident: ident,
         node: vi,
-        attrs: Vec::new(),
+        attrs: vec![],
         vis: vis,
         span: DUMMY_SP
-    }
+    })
 }
 
-fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) {
+fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) {
     // Link to test crate
-    let view_items = vec!(mk_std(cx));
+    let import = mk_std(cx);
 
     // A constant vector of test descriptors.
     let tests = mk_tests(cx);
@@ -427,8 +424,7 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) {
 
     let testmod = ast::Mod {
         inner: DUMMY_SP,
-        view_items: view_items,
-        items: vec!(mainfn, tests),
+        items: vec![import, mainfn, tests],
     };
     let item_ = ast::ItemMod(testmod);
 
@@ -439,34 +435,35 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) {
                                            vec![unstable])));
         attr::mk_attr_inner(attr::mk_attr_id(), allow)
     };
-    let item = ast::Item {
-        ident: mod_ident,
+    let item = P(ast::Item {
         id: ast::DUMMY_NODE_ID,
+        ident: mod_ident,
+        attrs: vec![allow_unstable],
         node: item_,
         vis: ast::Public,
         span: DUMMY_SP,
-        attrs: vec![allow_unstable],
-    };
+    });
     let reexport = cx.reexport_test_harness_main.as_ref().map(|s| {
         // building `use <ident> = __test::main`
         let reexport_ident = token::str_to_ident(s.get());
 
         let use_path =
             nospan(ast::ViewPathSimple(reexport_ident,
-                                       path_node(vec![mod_ident, token::str_to_ident("main")]),
-                                       ast::DUMMY_NODE_ID));
+                                       path_node(vec![mod_ident, token::str_to_ident("main")])));
 
-        ast::ViewItem {
-            node: ast::ViewItemUse(P(use_path)),
+        P(ast::Item {
+            id: ast::DUMMY_NODE_ID,
+            ident: token::special_idents::invalid,
             attrs: vec![],
+            node: ast::ItemUse(P(use_path)),
             vis: ast::Inherited,
             span: DUMMY_SP
-        }
+        })
     });
 
-    debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&item));
+    debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&*item));
 
-    (P(item), reexport)
+    (item, reexport)
 }
 
 fn nospan<T>(t: T) -> codemap::Spanned<T> {
diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs
index 5466b7337e7..89854f5d979 100644
--- a/src/libsyntax/util/parser_testing.rs
+++ b/src/libsyntax/util/parser_testing.rs
@@ -69,13 +69,6 @@ pub fn string_to_stmt(source_str : String) -> P<ast::Stmt> {
     })
 }
 
-/// Parse a string, return a view item
-pub fn string_to_view_item (source_str : String) -> ast::ViewItem {
-    with_error_checking_parse(source_str, |p| {
-        p.parse_view_item(Vec::new())
-    })
-}
-
 /// Parse a string, return a pat. Uses "irrefutable"... which doesn't
 /// (currently) affect parsing.
 pub fn string_to_pat(source_str: String) -> P<ast::Pat> {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 7778b4fa34a..eb906788aa7 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -62,7 +62,6 @@ pub trait Visitor<'v> : Sized {
         self.visit_name(span, ident.name);
     }
     fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) { walk_mod(self, m) }
-    fn visit_view_item(&mut self, i: &'v ViewItem) { walk_view_item(self, i) }
     fn visit_foreign_item(&mut self, i: &'v ForeignItem) { walk_foreign_item(self, i) }
     fn visit_item(&mut self, i: &'v Item) { walk_item(self, i) }
     fn visit_local(&mut self, l: &'v Local) { walk_local(self, l) }
@@ -166,51 +165,11 @@ pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
 }
 
 pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) {
-    for view_item in module.view_items.iter() {
-        visitor.visit_view_item(view_item)
-    }
-
     for item in module.items.iter() {
         visitor.visit_item(&**item)
     }
 }
 
-pub fn walk_view_item<'v, V: Visitor<'v>>(visitor: &mut V, vi: &'v ViewItem) {
-    match vi.node {
-        ViewItemExternCrate(name, _, _) => {
-            visitor.visit_ident(vi.span, name)
-        }
-        ViewItemUse(ref vp) => {
-            match vp.node {
-                ViewPathSimple(ident, ref path, id) => {
-                    visitor.visit_ident(vp.span, ident);
-                    visitor.visit_path(path, id);
-                }
-                ViewPathGlob(ref path, id) => {
-                    visitor.visit_path(path, id);
-                }
-                ViewPathList(ref prefix, ref list, _) => {
-                    for id in list.iter() {
-                        match id.node {
-                            PathListIdent { name, .. } => {
-                                visitor.visit_ident(id.span, name);
-                            }
-                            PathListMod { .. } => ()
-                        }
-                    }
-
-                    // Note that the `prefix` here is not a complete
-                    // path, so we don't use `visit_path`.
-                    walk_path(visitor, prefix);
-                }
-            }
-        }
-    }
-    for attr in vi.attrs.iter() {
-        visitor.visit_attribute(attr);
-    }
-}
-
 pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
     visitor.visit_pat(&*local.pat);
     walk_ty_opt(visitor, &local.ty);
@@ -269,6 +228,32 @@ pub fn walk_trait_ref<'v,V>(visitor: &mut V,
 pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
     visitor.visit_ident(item.span, item.ident);
     match item.node {
+        ItemExternCrate(..) => {}
+        ItemUse(ref vp) => {
+            match vp.node {
+                ViewPathSimple(ident, ref path) => {
+                    visitor.visit_ident(vp.span, ident);
+                    visitor.visit_path(path, item.id);
+                }
+                ViewPathGlob(ref path) => {
+                    visitor.visit_path(path, item.id);
+                }
+                ViewPathList(ref prefix, ref list) => {
+                    for id in list.iter() {
+                        match id.node {
+                            PathListIdent { name, .. } => {
+                                visitor.visit_ident(id.span, name);
+                            }
+                            PathListMod { .. } => ()
+                        }
+                    }
+
+                    // Note that the `prefix` here is not a complete
+                    // path, so we don't use `visit_path`.
+                    walk_path(visitor, prefix);
+                }
+            }
+        }
         ItemStatic(ref typ, _, ref expr) |
         ItemConst(ref typ, ref expr) => {
             visitor.visit_ty(&**typ);
@@ -285,9 +270,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             visitor.visit_mod(module, item.span, item.id)
         }
         ItemForeignMod(ref foreign_module) => {
-            for view_item in foreign_module.view_items.iter() {
-                visitor.visit_view_item(view_item)
-            }
             for foreign_item in foreign_module.items.iter() {
                 visitor.visit_foreign_item(&**foreign_item)
             }
@@ -732,9 +714,6 @@ pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V,
 }
 
 pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {
-    for view_item in block.view_items.iter() {
-        visitor.visit_view_item(view_item)
-    }
     for statement in block.stmts.iter() {
         visitor.visit_stmt(&**statement)
     }
diff --git a/src/test/compile-fail/issue-9957.rs b/src/test/auxiliary/blind-item-mixed-crate-use-item-foo.rs
index b1204e82890..f129b4b77bb 100644
--- a/src/test/compile-fail/issue-9957.rs
+++ b/src/test/auxiliary/blind-item-mixed-crate-use-item-foo.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub extern crate core; //~ ERROR: `pub` visibility is not allowed
+#![crate_type="lib"]
 
-fn main() {
-    pub use std::usize; //~ ERROR: imports in functions are never reachable
-}
+pub const X: () = ();
diff --git a/src/test/auxiliary/blind-item-mixed-crate-use-item-foo2.rs b/src/test/auxiliary/blind-item-mixed-crate-use-item-foo2.rs
new file mode 100644
index 00000000000..91fa9124551
--- /dev/null
+++ b/src/test/auxiliary/blind-item-mixed-crate-use-item-foo2.rs
@@ -0,0 +1,13 @@
+// Copyright 2015 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.
+
+#![crate_type="lib"]
+
+pub const Y: () = ();
diff --git a/src/test/compile-fail-fulldeps/gated-plugin.rs b/src/test/compile-fail-fulldeps/gated-plugin.rs
index 89090d5f38a..be9e57e2d19 100644
--- a/src/test/compile-fail-fulldeps/gated-plugin.rs
+++ b/src/test/compile-fail-fulldeps/gated-plugin.rs
@@ -11,8 +11,7 @@
 // aux-build:macro_crate_test.rs
 // ignore-stage1
 
-#[plugin] #[no_link]
+#[plugin] #[no_link] extern crate macro_crate_test;
 //~^ ERROR compiler plugins are experimental and possibly buggy
-extern crate macro_crate_test;
 
 fn main() {}
diff --git a/src/test/compile-fail/blind-item-block-item-shadow.rs b/src/test/compile-fail/blind-item-block-item-shadow.rs
new file mode 100644
index 00000000000..d4adaa042b2
--- /dev/null
+++ b/src/test/compile-fail/blind-item-block-item-shadow.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+mod foo { pub struct Bar; }
+
+fn main() {
+    {
+        struct Bar;
+        use foo::Bar;
+        //~^ ERROR import `Bar` conflicts with type in this module
+        //~^^ ERROR import `Bar` conflicts with value in this module
+    }
+}
diff --git a/src/test/compile-fail/blind-item-block-middle.rs b/src/test/compile-fail/blind-item-block-middle.rs
new file mode 100644
index 00000000000..fbb0730f014
--- /dev/null
+++ b/src/test/compile-fail/blind-item-block-middle.rs
@@ -0,0 +1,18 @@
+// Copyright 2015 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.
+
+mod foo { struct bar; }
+
+fn main() {
+    let bar = 5;
+    //~^ ERROR declaration of `bar` shadows an enum variant or unit-like struct in scope
+    use foo::bar;
+    //~^ ERROR imports are not allowed after non-item statements
+}
diff --git a/src/test/compile-fail/view-items-at-top.rs b/src/test/compile-fail/blind-item-item-shadow.rs
index 7b78a8d932b..9f21d6a9234 100644
--- a/src/test/compile-fail/view-items-at-top.rs
+++ b/src/test/compile-fail/blind-item-item-shadow.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,12 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-extern crate test;
+mod foo { pub mod foo {  } }
 
-fn f() {
-}
+use foo::foo; //~ ERROR import `foo` conflicts with existing submodule
 
-use test::net;    //~ ERROR `use` and `extern crate` declarations must precede items
-
-fn main() {
-}
+fn main() {}
diff --git a/src/test/compile-fail/blind-item-local-shadow.rs b/src/test/compile-fail/blind-item-local-shadow.rs
new file mode 100644
index 00000000000..a28f5f6e557
--- /dev/null
+++ b/src/test/compile-fail/blind-item-local-shadow.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+mod bar {
+    pub fn foo() -> bool { true }
+}
+
+fn main() {
+    let foo = |&:| false;
+    use bar::foo;
+    //~^ ERROR imports are not allowed after non-item statements
+    assert_eq!(foo(), false);
+}
diff --git a/src/test/compile-fail/unnecessary-private.rs b/src/test/compile-fail/unnecessary-private.rs
index 6e6ffd23c4a..e3707292f24 100644
--- a/src/test/compile-fail/unnecessary-private.rs
+++ b/src/test/compile-fail/unnecessary-private.rs
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 fn main() {
+    pub use std::uint; //~ ERROR: visibility has no effect
     pub struct A; //~ ERROR: visibility has no effect
     pub enum B {} //~ ERROR: visibility has no effect
     pub trait C { //~ ERROR: visibility has no effect
diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp
index dac6e628d10..c18d076c0d3 100644
--- a/src/test/pretty/issue-4264.pp
+++ b/src/test/pretty/issue-4264.pp
@@ -1,8 +1,8 @@
 #![no_std]
-#[macro_use]
-extern crate "std" as std;
 #[prelude_import]
 use std::prelude::v1::*;
+#[macro_use]
+extern crate "std" as std;
 // 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.
diff --git a/src/test/run-pass/blind-item-mixed-crate-use-item.rs b/src/test/run-pass/blind-item-mixed-crate-use-item.rs
new file mode 100644
index 00000000000..80c73e5e60b
--- /dev/null
+++ b/src/test/run-pass/blind-item-mixed-crate-use-item.rs
@@ -0,0 +1,33 @@
+// Copyright 2015 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.
+
+// aux-build:blind-item-mixed-crate-use-item-foo.rs
+// aux-build:blind-item-mixed-crate-use-item-foo2.rs
+
+mod m {
+    pub fn f<T>(_: T, _: (), _: ()) { }
+    pub fn g<T>(_: T, _: (), _: ()) { }
+}
+
+const BAR: () = ();
+struct Data;
+use m::f;
+extern crate "blind-item-mixed-crate-use-item-foo" as foo;
+
+fn main() {
+    const BAR2: () = ();
+    struct Data2;
+    use m::g;
+
+    extern crate "blind-item-mixed-crate-use-item-foo2" as foo2;
+
+    f(Data, BAR, foo::X);
+    g(Data2, BAR2, foo2::Y);
+}
diff --git a/src/test/run-pass/blind-item-mixed-use-item.rs b/src/test/run-pass/blind-item-mixed-use-item.rs
new file mode 100644
index 00000000000..a3dad01acf1
--- /dev/null
+++ b/src/test/run-pass/blind-item-mixed-use-item.rs
@@ -0,0 +1,27 @@
+// Copyright 2015 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.
+
+mod m {
+    pub fn f<T>(_: T, _: ()) { }
+    pub fn g<T>(_: T, _: ()) { }
+}
+
+const BAR: () = ();
+struct Data;
+use m::f;
+
+fn main() {
+    const BAR2: () = ();
+    struct Data2;
+    use m::g;
+
+    f(Data, BAR);
+    g(Data2, BAR2);
+}