about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2016-06-29 21:21:21 +0530
committerGitHub <noreply@github.com>2016-06-29 21:21:21 +0530
commitfd45e6e9127e737ad7d7bca5efe3c50b0dab03f7 (patch)
treeefa5b5d02389e82c7b683bab044b9977c0760e6f
parent470c5191f553eb86a3a849e88d642dbd09a32e25 (diff)
parente58963d3e45895c150a8c5894c2b7ad87b448568 (diff)
downloadrust-fd45e6e9127e737ad7d7bca5efe3c50b0dab03f7.tar.gz
rust-fd45e6e9127e737ad7d7bca5efe3c50b0dab03f7.zip
Rollup merge of #34459 - jseyfried:expansion_cleanup, r=nrc
Miscellaneous macro expansion cleanup and groundwork

r? @nrc
-rw-r--r--src/librustc/hir/lowering.rs21
-rw-r--r--src/librustc/hir/map/def_collector.rs8
-rw-r--r--src/librustc/hir/map/definitions.rs8
-rw-r--r--src/librustc/hir/map/mod.rs10
-rw-r--r--src/librustc/session/mod.rs19
-rw-r--r--src/librustc_driver/driver.rs85
-rw-r--r--src/librustc_metadata/astencode.rs21
-rw-r--r--src/librustc_resolve/lib.rs89
-rw-r--r--src/libsyntax/ast.rs10
-rw-r--r--src/libsyntax/attr.rs4
-rw-r--r--src/libsyntax/config.rs7
-rw-r--r--src/libsyntax/ext/base.rs4
-rw-r--r--src/libsyntax/ext/expand.rs32
13 files changed, 121 insertions, 197 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 5b655522f34..2cc39412182 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -50,6 +50,7 @@ use session::Session;
 use std::collections::BTreeMap;
 use std::iter;
 use syntax::ast::*;
+use syntax::errors;
 use syntax::ptr::P;
 use syntax::codemap::{respan, Spanned};
 use syntax::parse::token;
@@ -60,7 +61,7 @@ use syntax_pos::Span;
 pub struct LoweringContext<'a> {
     crate_root: Option<&'static str>,
     // Use to assign ids to hir nodes that do not directly correspond to an ast node
-    id_assigner: &'a NodeIdAssigner,
+    sess: Option<&'a Session>,
     // As we walk the AST we must keep track of the current 'parent' def id (in
     // the form of a DefIndex) so that if we create a new node which introduces
     // a definition, then we can properly create the def id.
@@ -99,7 +100,6 @@ impl Resolver for DummyResolver {
 
 pub fn lower_crate(sess: &Session,
                    krate: &Crate,
-                   id_assigner: &NodeIdAssigner,
                    resolver: &mut Resolver)
                    -> hir::Crate {
     // We're constructing the HIR here; we don't care what we will
@@ -115,17 +115,17 @@ pub fn lower_crate(sess: &Session,
         } else {
             Some("std")
         },
-        id_assigner: id_assigner,
+        sess: Some(sess),
         parent_def: None,
         resolver: resolver,
     }.lower_crate(krate)
 }
 
 impl<'a> LoweringContext<'a> {
-    pub fn testing_context(id_assigner: &'a NodeIdAssigner, resolver: &'a mut Resolver) -> Self {
+    pub fn testing_context(resolver: &'a mut Resolver) -> Self {
         LoweringContext {
             crate_root: None,
-            id_assigner: id_assigner,
+            sess: None,
             parent_def: None,
             resolver: resolver,
         }
@@ -161,7 +161,12 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn next_id(&self) -> NodeId {
-        self.id_assigner.next_node_id()
+        self.sess.map(Session::next_node_id).unwrap_or(0)
+    }
+
+    fn diagnostic(&self) -> &errors::Handler {
+        self.sess.map(Session::diagnostic)
+                 .unwrap_or_else(|| panic!("this lowerer cannot emit diagnostics"))
     }
 
     fn str_to_ident(&self, s: &'static str) -> Name {
@@ -786,7 +791,7 @@ impl<'a> LoweringContext<'a> {
         if let Some(SelfKind::Explicit(..)) = sig.decl.get_self().map(|eself| eself.node) {
             match hir_sig.decl.get_self().map(|eself| eself.node) {
                 Some(hir::SelfKind::Value(..)) | Some(hir::SelfKind::Region(..)) => {
-                    self.id_assigner.diagnostic().span_err(sig.decl.inputs[0].ty.span,
+                    self.diagnostic().span_err(sig.decl.inputs[0].ty.span,
                         "the type placeholder `_` is not allowed within types on item signatures");
                 }
                 _ => {}
@@ -1212,7 +1217,7 @@ impl<'a> LoweringContext<'a> {
                             make_struct(self, e, &["RangeInclusive", "NonEmpty"],
                                                  &[("start", e1), ("end", e2)]),
 
-                        _ => panic!(self.id_assigner.diagnostic()
+                        _ => panic!(self.diagnostic()
                                         .span_fatal(e.span, "inclusive range with no end")),
                     };
                 }
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index ccb3e154d92..2b89695ab41 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -25,15 +25,15 @@ pub struct DefCollector<'ast> {
     // If we are walking HIR (c.f., AST), we need to keep a reference to the
     // crate.
     hir_crate: Option<&'ast hir::Crate>,
-    pub definitions: Definitions,
+    definitions: &'ast mut Definitions,
     parent_def: Option<DefIndex>,
 }
 
 impl<'ast> DefCollector<'ast> {
-    pub fn root() -> DefCollector<'ast> {
+    pub fn root(definitions: &'ast mut Definitions) -> DefCollector<'ast> {
         let mut collector = DefCollector {
             hir_crate: None,
-            definitions: Definitions::new(),
+            definitions: definitions,
             parent_def: None,
         };
         let root = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot);
@@ -48,7 +48,7 @@ impl<'ast> DefCollector<'ast> {
     pub fn extend(parent_node: NodeId,
                   parent_def_path: DefPath,
                   parent_def_id: DefId,
-                  definitions: Definitions)
+                  definitions: &'ast mut Definitions)
                   -> DefCollector<'ast> {
         let mut collector = DefCollector {
             hir_crate: None,
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
index d66df3e4e8f..3317585f820 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc/hir/map/definitions.rs
@@ -10,8 +10,9 @@
 
 use middle::cstore::LOCAL_CRATE;
 use hir::def_id::{DefId, DefIndex};
+use hir::map::def_collector::DefCollector;
 use rustc_data_structures::fnv::FnvHashMap;
-use syntax::ast;
+use syntax::{ast, visit};
 use syntax::parse::token::InternedString;
 use util::nodemap::NodeMap;
 
@@ -189,6 +190,11 @@ impl Definitions {
         }
     }
 
+    pub fn collect(&mut self, krate: &ast::Crate) {
+        let mut def_collector = DefCollector::root(self);
+        visit::walk_crate(&mut def_collector, krate);
+    }
+
     /// Get the number of definitions.
     pub fn len(&self) -> usize {
         self.data.len()
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index f9fb8ac66b7..960e32ae99f 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -24,7 +24,6 @@ use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
 use syntax::abi::Abi;
 use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, };
 use syntax::codemap::Spanned;
-use syntax::visit;
 use syntax_pos::Span;
 
 use hir::*;
@@ -780,12 +779,6 @@ impl<F: FoldOps> Folder for IdAndSpanUpdater<F> {
     }
 }
 
-pub fn collect_definitions<'ast>(krate: &'ast ast::Crate) -> Definitions {
-    let mut def_collector = DefCollector::root();
-    visit::walk_crate(&mut def_collector, krate);
-    def_collector.definitions
-}
-
 pub fn map_crate<'ast>(forest: &'ast mut Forest,
                        definitions: Definitions)
                        -> Map<'ast> {
@@ -842,13 +835,12 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
     let ii = map.forest.inlined_items.alloc(ii);
     let ii_parent_id = fld.new_id(DUMMY_NODE_ID);
 
-    let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new());
+    let defs = &mut *map.definitions.borrow_mut();
     let mut def_collector = DefCollector::extend(ii_parent_id,
                                                  parent_def_path.clone(),
                                                  parent_def_id,
                                                  defs);
     def_collector.walk_item(ii, map.krate());
-    *map.definitions.borrow_mut() = def_collector.definitions;
 
     let mut collector = NodeCollector::extend(map.krate(),
                                               ii,
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 77259cea24d..fdaf182c605 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -20,7 +20,7 @@ use ty::tls;
 use util::nodemap::{NodeMap, FnvHashMap};
 use mir::transform as mir_pass;
 
-use syntax::ast::{NodeId, NodeIdAssigner, Name};
+use syntax::ast::{NodeId, Name};
 use errors::{self, DiagnosticBuilder};
 use errors::emitter::{Emitter, BasicEmitter, EmitterWriter};
 use syntax::json::JsonEmitter;
@@ -272,6 +272,9 @@ impl Session {
 
         id
     }
+    pub fn next_node_id(&self) -> NodeId {
+        self.reserve_node_ids(1)
+    }
     pub fn diagnostic<'a>(&'a self) -> &'a errors::Handler {
         &self.parse_sess.span_diagnostic
     }
@@ -345,20 +348,6 @@ impl Session {
     }
 }
 
-impl NodeIdAssigner for Session {
-    fn next_node_id(&self) -> NodeId {
-        self.reserve_node_ids(1)
-    }
-
-    fn peek_node_id(&self) -> NodeId {
-        self.next_node_id.get().checked_add(1).unwrap()
-    }
-
-    fn diagnostic(&self) -> &errors::Handler {
-        self.diagnostic()
-    }
-}
-
 fn split_msg_into_multilines(msg: &str) -> Option<String> {
     // Conditions for enabling multi-line errors:
     if !msg.contains("mismatched types") &&
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index eb442c0a34e..46009e58130 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc::dep_graph::DepGraph;
 use rustc::hir;
 use rustc::hir::{map as hir_map, FreevarMap, TraitMap};
 use rustc::hir::def::DefMap;
@@ -27,7 +26,7 @@ use rustc::util::nodemap::NodeSet;
 use rustc_back::sha2::{Sha256, Digest};
 use rustc_borrowck as borrowck;
 use rustc_incremental;
-use rustc_resolve as resolve;
+use rustc_resolve::{MakeGlobMap, Resolver};
 use rustc_metadata::macro_import;
 use rustc_metadata::creader::read_local_crates;
 use rustc_metadata::cstore::CStore;
@@ -49,13 +48,11 @@ use std::ffi::{OsString, OsStr};
 use std::fs;
 use std::io::{self, Write};
 use std::path::{Path, PathBuf};
-use syntax::ast::{self, NodeIdAssigner};
+use syntax::{ast, diagnostics, visit};
 use syntax::attr::{self, AttrMetaMethods};
-use syntax::diagnostics;
 use syntax::fold::Folder;
 use syntax::parse::{self, PResult, token};
 use syntax::util::node_count::NodeCounter;
-use syntax::visit;
 use syntax;
 use syntax_ext;
 
@@ -293,7 +290,7 @@ pub struct CompileController<'a> {
     pub after_analysis: PhaseController<'a>,
     pub after_llvm: PhaseController<'a>,
 
-    pub make_glob_map: resolve::MakeGlobMap,
+    pub make_glob_map: MakeGlobMap,
 }
 
 impl<'a> CompileController<'a> {
@@ -305,7 +302,7 @@ impl<'a> CompileController<'a> {
             after_hir_lowering: PhaseController::basic(),
             after_analysis: PhaseController::basic(),
             after_llvm: PhaseController::basic(),
-            make_glob_map: resolve::MakeGlobMap::No,
+            make_glob_map: MakeGlobMap::No,
         }
     }
 }
@@ -564,7 +561,7 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
                                         mut krate: ast::Crate,
                                         crate_name: &'a str,
                                         addl_plugins: Option<Vec<String>>,
-                                        make_glob_map: resolve::MakeGlobMap)
+                                        make_glob_map: MakeGlobMap)
                                         -> Result<ExpansionResult<'a>, usize> {
     let time_passes = sess.time_passes();
 
@@ -729,13 +726,16 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
 
     krate = assign_node_ids(sess, krate);
 
+    let resolver_arenas = Resolver::arenas();
+    let mut resolver = Resolver::new(sess, make_glob_map, &resolver_arenas);
+
     // Collect defintions for def ids.
-    let mut defs =
-        time(sess.time_passes(), "collecting defs", || hir_map::collect_definitions(&krate));
+    time(sess.time_passes(), "collecting defs", || resolver.definitions.collect(&krate));
 
-    time(sess.time_passes(),
-         "external crate/lib resolution",
-         || read_local_crates(sess, &cstore, &defs, &krate, crate_name, &sess.dep_graph));
+    time(sess.time_passes(), "external crate/lib resolution", || {
+        let defs = &resolver.definitions;
+        read_local_crates(sess, &cstore, defs, &krate, crate_name, &sess.dep_graph)
+    });
 
     time(sess.time_passes(),
          "early lint checks",
@@ -745,8 +745,14 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
          "AST validation",
          || ast_validation::check_crate(sess, &krate));
 
-    let (analysis, resolutions, hir_forest) =
-        lower_and_resolve(sess, crate_name, &mut defs, &krate, &sess.dep_graph, make_glob_map);
+    time(sess.time_passes(), "name resolution", || {
+        resolver.resolve_crate(&krate);
+    });
+
+    // Lower ast -> hir.
+    let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || {
+        hir_map::Forest::new(lower_crate(sess, &krate, &mut resolver), &sess.dep_graph)
+    });
 
     // Discard MTWT tables that aren't required past lowering to HIR.
     if !keep_mtwt_tables(sess) {
@@ -755,9 +761,20 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session,
 
     Ok(ExpansionResult {
         expanded_crate: krate,
-        defs: defs,
-        analysis: analysis,
-        resolutions: resolutions,
+        defs: resolver.definitions,
+        analysis: ty::CrateAnalysis {
+            export_map: resolver.export_map,
+            access_levels: AccessLevels::default(),
+            reachable: NodeSet(),
+            name: crate_name,
+            glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None },
+        },
+        resolutions: Resolutions {
+            def_map: resolver.def_map,
+            freevars: resolver.freevars,
+            trait_map: resolver.trait_map,
+            maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
+        },
         hir_forest: hir_forest
     })
 }
@@ -809,38 +826,6 @@ pub fn assign_node_ids(sess: &Session, krate: ast::Crate) -> ast::Crate {
     krate
 }
 
-pub fn lower_and_resolve<'a>(sess: &Session,
-                             id: &'a str,
-                             defs: &mut hir_map::Definitions,
-                             krate: &ast::Crate,
-                             dep_graph: &DepGraph,
-                             make_glob_map: resolve::MakeGlobMap)
-                             -> (ty::CrateAnalysis<'a>, Resolutions, hir_map::Forest) {
-    resolve::with_resolver(sess, defs, make_glob_map, |mut resolver| {
-        time(sess.time_passes(), "name resolution", || {
-            resolve::resolve_crate(&mut resolver, krate);
-        });
-
-        // Lower ast -> hir.
-        let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || {
-            hir_map::Forest::new(lower_crate(sess, krate, sess, &mut resolver), dep_graph)
-        });
-
-        (ty::CrateAnalysis {
-            export_map: resolver.export_map,
-            access_levels: AccessLevels::default(),
-            reachable: NodeSet(),
-            name: &id,
-            glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None },
-        }, Resolutions {
-            def_map: resolver.def_map,
-            freevars: resolver.freevars,
-            trait_map: resolver.trait_map,
-            maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
-        }, hir_forest)
-    })
-}
-
 /// Run the resolution, typechecking, region checking and other
 /// miscellaneous analysis passes on the crate. Return various
 /// structures carrying the results of the analysis.
diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs
index dc37bdf6322..7ef00b971c5 100644
--- a/src/librustc_metadata/astencode.rs
+++ b/src/librustc_metadata/astencode.rs
@@ -38,7 +38,6 @@ use rustc::ty::subst;
 use rustc::ty::{self, Ty, TyCtxt};
 
 use syntax::ast;
-use syntax::ast::NodeIdAssigner;
 use syntax::ptr::P;
 use syntax_pos;
 
@@ -56,7 +55,6 @@ use rustc_serialize::{Encodable, EncoderHelpers};
 
 #[cfg(test)] use std::io::Cursor;
 #[cfg(test)] use syntax::parse;
-#[cfg(test)] use syntax::ast::NodeId;
 #[cfg(test)] use rustc::hir::print as pprust;
 #[cfg(test)] use rustc::hir::lowering::{LoweringContext, DummyResolver};
 
@@ -1296,31 +1294,14 @@ impl FakeExtCtxt for parse::ParseSess {
 }
 
 #[cfg(test)]
-struct FakeNodeIdAssigner;
-
-#[cfg(test)]
-// It should go without saying that this may give unexpected results. Avoid
-// lowering anything which needs new nodes.
-impl NodeIdAssigner for FakeNodeIdAssigner {
-    fn next_node_id(&self) -> NodeId {
-        0
-    }
-
-    fn peek_node_id(&self) -> NodeId {
-        0
-    }
-}
-
-#[cfg(test)]
 fn mk_ctxt() -> parse::ParseSess {
     parse::ParseSess::new()
 }
 
 #[cfg(test)]
 fn with_testing_context<T, F: FnOnce(&mut LoweringContext) -> T>(f: F) -> T {
-    let assigner = FakeNodeIdAssigner;
     let mut resolver = DummyResolver;
-    let mut lcx = LoweringContext::testing_context(&assigner, &mut resolver);
+    let mut lcx = LoweringContext::testing_context(&mut resolver);
     f(&mut lcx)
 }
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 8ffa95ec7e9..9c9e3ff037b 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -47,7 +47,7 @@ use rustc::hir::{self, PrimTy, TyBool, TyChar, TyFloat, TyInt, TyUint, TyStr};
 use rustc::session::Session;
 use rustc::lint;
 use rustc::hir::def::*;
-use rustc::hir::def_id::DefId;
+use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
 use rustc::ty;
 use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace};
 use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
@@ -925,7 +925,7 @@ impl PrimitiveTypeTable {
 pub struct Resolver<'a> {
     session: &'a Session,
 
-    definitions: &'a mut Definitions,
+    pub definitions: Definitions,
 
     graph_root: Module<'a>,
 
@@ -1001,7 +1001,7 @@ pub struct Resolver<'a> {
     arenas: &'a ResolverArenas<'a>,
 }
 
-struct ResolverArenas<'a> {
+pub struct ResolverArenas<'a> {
     modules: arena::TypedArena<ModuleS<'a>>,
     local_modules: RefCell<Vec<Module<'a>>>,
     name_bindings: arena::TypedArena<NameBinding<'a>>,
@@ -1079,7 +1079,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
     }
 
     fn definitions(&mut self) -> Option<&mut Definitions> {
-        Some(self.definitions)
+        Some(&mut self.definitions)
     }
 }
 
@@ -1100,12 +1100,9 @@ impl Named for hir::PathSegment {
 }
 
 impl<'a> Resolver<'a> {
-    fn new(session: &'a Session,
-           definitions: &'a mut Definitions,
-           make_glob_map: MakeGlobMap,
-           arenas: &'a ResolverArenas<'a>)
-           -> Resolver<'a> {
-        let root_def_id = definitions.local_def_id(CRATE_NODE_ID);
+    pub fn new(session: &'a Session, make_glob_map: MakeGlobMap, arenas: &'a ResolverArenas<'a>)
+               -> Resolver<'a> {
+        let root_def_id = DefId::local(CRATE_DEF_INDEX);
         let graph_root =
             ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, arenas);
         let graph_root = arenas.alloc_module(graph_root);
@@ -1115,7 +1112,7 @@ impl<'a> Resolver<'a> {
         Resolver {
             session: session,
 
-            definitions: definitions,
+            definitions: Definitions::new(),
 
             // The outermost module has def ID 0; this is not reflected in the
             // AST.
@@ -1158,7 +1155,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    fn arenas() -> ResolverArenas<'a> {
+    pub fn arenas() -> ResolverArenas<'a> {
         ResolverArenas {
             modules: arena::TypedArena::new(),
             local_modules: RefCell::new(Vec::new()),
@@ -1168,6 +1165,27 @@ impl<'a> Resolver<'a> {
         }
     }
 
+    /// Entry point to crate resolution.
+    pub fn resolve_crate(&mut self, krate: &Crate) {
+        // Currently, we ignore the name resolution data structures for
+        // the purposes of dependency tracking. Instead we will run name
+        // resolution and include its output in the hash of each item,
+        // much like we do for macro expansion. In other words, the hash
+        // reflects not just its contents but the results of name
+        // resolution on those contents. Hopefully we'll push this back at
+        // some point.
+        let _ignore = self.session.dep_graph.in_ignore();
+
+        self.build_reduced_graph(krate);
+        resolve_imports::resolve_imports(self);
+
+        self.current_module = self.graph_root;
+        visit::walk_crate(self, krate);
+
+        check_unused::check_crate(self, krate);
+        self.report_privacy_errors();
+    }
+
     fn new_module(&self, parent_link: ParentLink<'a>, def: Option<Def>, external: bool)
                   -> Module<'a> {
         self.arenas.alloc_module(ModuleS::new(parent_link, def, external, self.arenas))
@@ -1568,12 +1586,6 @@ impl<'a> Resolver<'a> {
         None
     }
 
-    fn resolve_crate(&mut self, krate: &Crate) {
-        debug!("(resolving crate) starting");
-        self.current_module = self.graph_root;
-        visit::walk_crate(self, krate);
-    }
-
     fn resolve_item(&mut self, item: &Item) {
         let name = item.ident.name;
 
@@ -2287,24 +2299,25 @@ impl<'a> Resolver<'a> {
                 PatKind::Ident(bmode, ref ident, ref opt_pat) => {
                     // First try to resolve the identifier as some existing
                     // entity, then fall back to a fresh binding.
-                    let resolution = if let Ok(resolution) = self.resolve_path(pat.id,
-                                &Path::from_ident(ident.span, ident.node), 0, ValueNS) {
+                    let local_def = self.resolve_identifier(ident.node, ValueNS, true);
+                    let resolution = if let Some(LocalDef { def, .. }) = local_def {
                         let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
                                              bmode != BindingMode::ByValue(Mutability::Immutable);
-                        match resolution.base_def {
+                        match def {
                             Def::Struct(..) | Def::Variant(..) |
                             Def::Const(..) | Def::AssociatedConst(..) if !always_binding => {
                                 // A constant, unit variant, etc pattern.
-                                resolution
+                                PathResolution::new(def)
                             }
                             Def::Struct(..) | Def::Variant(..) |
                             Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => {
                                 // A fresh binding that shadows something unacceptable.
+                                let kind_name = PathResolution::new(def).kind_name();
                                 resolve_error(
                                     self,
                                     ident.span,
                                     ResolutionError::BindingShadowsSomethingUnacceptable(
-                                        pat_src.descr(), resolution.kind_name(), ident.node.name)
+                                        pat_src.descr(), kind_name, ident.node.name)
                                 );
                                 err_path_resolution()
                             }
@@ -3454,34 +3467,4 @@ pub enum MakeGlobMap {
     No,
 }
 
-/// Entry point to crate resolution.
-pub fn resolve_crate<'a, 'b>(resolver: &'b mut Resolver<'a>, krate: &'b Crate) {
-    // Currently, we ignore the name resolution data structures for
-    // the purposes of dependency tracking. Instead we will run name
-    // resolution and include its output in the hash of each item,
-    // much like we do for macro expansion. In other words, the hash
-    // reflects not just its contents but the results of name
-    // resolution on those contents. Hopefully we'll push this back at
-    // some point.
-    let _ignore = resolver.session.dep_graph.in_ignore();
-
-    resolver.build_reduced_graph(krate);
-    resolve_imports::resolve_imports(resolver);
-    resolver.resolve_crate(krate);
-
-    check_unused::check_crate(resolver, krate);
-    resolver.report_privacy_errors();
-}
-
-pub fn with_resolver<'a, T, F>(session: &'a Session,
-                               definitions: &'a mut Definitions,
-                               make_glob_map: MakeGlobMap,
-                               f: F) -> T
-    where F: for<'b> FnOnce(Resolver<'b>) -> T,
-{
-    let arenas = Resolver::arenas();
-    let resolver = Resolver::new(session, definitions, make_glob_map, &arenas);
-    f(resolver)
-}
-
 __build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index a352715b20b..cc033cec8b8 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -19,7 +19,6 @@ pub use util::ThinVec;
 use syntax_pos::{mk_sp, Span, DUMMY_SP, ExpnId};
 use codemap::{respan, Spanned};
 use abi::Abi;
-use errors;
 use parse::token::{self, keywords, InternedString};
 use print::pprust;
 use ptr::P;
@@ -362,15 +361,6 @@ pub const CRATE_NODE_ID: NodeId = 0;
 /// small, positive ids.
 pub const DUMMY_NODE_ID: NodeId = !0;
 
-pub trait NodeIdAssigner {
-    fn next_node_id(&self) -> NodeId;
-    fn peek_node_id(&self) -> NodeId;
-
-    fn diagnostic(&self) -> &errors::Handler {
-        panic!("this ID assigner cannot emit diagnostics")
-    }
-}
-
 /// The AST represents all type param bounds as types.
 /// typeck::collect::compute_bounds matches these against
 /// the "special" built-in traits (see middle::lang_items) and
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index da2967e306f..3c88fb8f670 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -839,7 +839,7 @@ impl HasAttrs for StmtKind {
     fn attrs(&self) -> &[Attribute] {
         match *self {
             StmtKind::Local(ref local) => local.attrs(),
-            StmtKind::Item(ref item) => item.attrs(),
+            StmtKind::Item(..) => &[],
             StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.attrs(),
             StmtKind::Mac(ref mac) => {
                 let (_, _, ref attrs) = **mac;
@@ -851,7 +851,7 @@ impl HasAttrs for StmtKind {
     fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
         match self {
             StmtKind::Local(local) => StmtKind::Local(local.map_attrs(f)),
-            StmtKind::Item(item) => StmtKind::Item(item.map_attrs(f)),
+            StmtKind::Item(..) => self,
             StmtKind::Expr(expr) => StmtKind::Expr(expr.map_attrs(f)),
             StmtKind::Semi(expr) => StmtKind::Semi(expr.map_attrs(f)),
             StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, style, attrs)| {
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 961763c6025..eaf82f5f43d 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -213,12 +213,7 @@ impl<'a> fold::Folder for StripUnconfigured<'a> {
     }
 
     fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
-        // avoid calling `visit_stmt_or_expr_attrs` on items
-        match stmt.node {
-            ast::StmtKind::Item(_) => {}
-            _ => self.visit_stmt_or_expr_attrs(stmt.attrs()),
-        }
-
+        self.visit_stmt_or_expr_attrs(stmt.attrs());
         self.configure(stmt).map(|stmt| fold::noop_fold_stmt(stmt, self))
                             .unwrap_or(SmallVector::zero())
     }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 757b039fcac..ca38ef068d0 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -443,6 +443,10 @@ impl MacResult for DummyResult {
             span: self.span,
         }))
     }
+
+    fn make_ty(self: Box<DummyResult>) -> Option<P<ast::Ty>> {
+        Some(DummyResult::raw_ty(self.span))
+    }
 }
 
 /// An enum representing the different kinds of syntax extensions.
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index a10d8900140..aca1fae6a3c 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -43,18 +43,19 @@ trait MacroGenerable: Sized {
     fn fold_with<F: Folder>(self, folder: &mut F) -> Self;
     fn visit_with<V: Visitor>(&self, visitor: &mut V);
 
-    // Return a placeholder expansion to allow compilation to continue after an erroring expansion.
-    fn dummy(span: Span) -> Self;
-
     // The user-friendly name of the node type (e.g. "expression", "item", etc.) for diagnostics.
     fn kind_name() -> &'static str;
+
+    // Return a placeholder expansion to allow compilation to continue after an erroring expansion.
+    fn dummy(span: Span) -> Self {
+        Self::make_with(DummyResult::any(span)).unwrap()
+    }
 }
 
 macro_rules! impl_macro_generable {
     ($($ty:ty: $kind_name:expr, .$make:ident,
                $(.$fold:ident)*  $(lift .$fold_elt:ident)*,
-               $(.$visit:ident)* $(lift .$visit_elt:ident)*,
-               |$span:ident| $dummy:expr;)*) => { $(
+               $(.$visit:ident)* $(lift .$visit_elt:ident)*;)*) => { $(
         impl MacroGenerable for $ty {
             fn kind_name() -> &'static str { $kind_name }
             fn make_with<'a>(result: Box<MacResult + 'a>) -> Option<Self> { result.$make() }
@@ -66,31 +67,24 @@ macro_rules! impl_macro_generable {
                 $( visitor.$visit(self) )*
                 $( for item in self.as_slice() { visitor. $visit_elt (item) } )*
             }
-            fn dummy($span: Span) -> Self { $dummy }
         }
     )* }
 }
 
 impl_macro_generable! {
-    P<ast::Pat>: "pattern", .make_pat, .fold_pat, .visit_pat, |span| P(DummyResult::raw_pat(span));
-    P<ast::Ty>:  "type",    .make_ty,  .fold_ty,  .visit_ty,  |span| DummyResult::raw_ty(span);
-    P<ast::Expr>:
-        "expression", .make_expr, .fold_expr, .visit_expr, |span| DummyResult::raw_expr(span);
-    SmallVector<ast::Stmt>:
-        "statement",  .make_stmts, lift .fold_stmt, lift .visit_stmt, |_span| SmallVector::zero();
-    SmallVector<P<ast::Item>>:
-        "item",       .make_items, lift .fold_item, lift .visit_item, |_span| SmallVector::zero();
+    P<ast::Expr>: "expression", .make_expr, .fold_expr, .visit_expr;
+    P<ast::Pat>:  "pattern",    .make_pat,  .fold_pat,  .visit_pat;
+    P<ast::Ty>:   "type",       .make_ty,   .fold_ty,   .visit_ty;
+    SmallVector<ast::Stmt>: "statement", .make_stmts, lift .fold_stmt, lift .visit_stmt;
+    SmallVector<P<ast::Item>>: "item",   .make_items, lift .fold_item, lift .visit_item;
     SmallVector<ast::TraitItem>:
-        "trait item", .make_trait_items, lift .fold_trait_item, lift .visit_trait_item,
-        |_span| SmallVector::zero();
+        "trait item", .make_trait_items, lift .fold_trait_item, lift .visit_trait_item;
     SmallVector<ast::ImplItem>:
-        "impl item",  .make_impl_items,  lift .fold_impl_item,  lift .visit_impl_item,
-        |_span| SmallVector::zero();
+        "impl item",  .make_impl_items,  lift .fold_impl_item,  lift .visit_impl_item;
 }
 
 impl MacroGenerable for Option<P<ast::Expr>> {
     fn kind_name() -> &'static str { "expression" }
-    fn dummy(_span: Span) -> Self { None }
     fn make_with<'a>(result: Box<MacResult + 'a>) -> Option<Self> {
         result.make_expr().map(Some)
     }