about summary refs log tree commit diff
path: root/src/librustc_driver
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_driver')
-rw-r--r--src/librustc_driver/driver.rs70
-rw-r--r--src/librustc_driver/lib.rs2
-rw-r--r--src/librustc_driver/pretty.rs272
-rw-r--r--src/librustc_driver/test.rs30
4 files changed, 273 insertions, 101 deletions
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index f08c962a1c2..d12a189e6b1 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use rustc::front;
+use rustc::front::map as hir_map;
 use rustc::session::Session;
 use rustc::session::config::{self, Input, OutputFilenames};
 use rustc::session::search_paths::PathKind;
-use rustc::ast_map;
 use rustc::lint;
 use rustc::metadata;
 use rustc::metadata::creader::LocalCrateReader;
@@ -28,6 +29,8 @@ use rustc_trans::back::write;
 use rustc_trans::trans;
 use rustc_typeck as typeck;
 use rustc_privacy;
+use rustc_front::hir;
+use rustc_front::lowering::lower_crate;
 use super::Compilation;
 
 use serialize::json;
@@ -41,6 +44,7 @@ use syntax::ast;
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
 use syntax::diagnostics;
+use syntax::fold::Folder;
 use syntax::parse;
 use syntax::parse::token;
 use syntax;
@@ -104,9 +108,13 @@ pub fn compile_input(sess: Session,
                                                                  &expanded_crate,
                                                                  &id[..]));
 
-        let mut forest = ast_map::Forest::new(expanded_crate);
+        let expanded_crate = assign_node_ids(&sess, expanded_crate);
+        // Lower ast -> hir.
+        let mut hir_forest = time(sess.time_passes(),
+                                  "lowering ast -> hir",
+                                  || hir_map::Forest::new(lower_crate(&expanded_crate)));
         let arenas = ty::CtxtArenas::new();
-        let ast_map = assign_node_ids_and_map(&sess, &mut forest);
+        let ast_map = make_map(&sess, &mut hir_forest);
 
         write_out_deps(&sess, input, &outputs, &id[..]);
 
@@ -116,11 +124,14 @@ pub fn compile_input(sess: Session,
                                                                      &sess,
                                                                      outdir,
                                                                      &ast_map,
+                                                                     &expanded_crate,
                                                                      &ast_map.krate(),
                                                                      &id[..]));
 
+
         phase_3_run_analysis_passes(sess,
                                     ast_map,
+                                    &expanded_crate,
                                     &arenas,
                                     id,
                                     control.make_glob_map,
@@ -130,6 +141,7 @@ pub fn compile_input(sess: Session,
                 let state = CompileState::state_after_analysis(input,
                                                                &tcx.sess,
                                                                outdir,
+                                                               &expanded_crate,
                                                                tcx.map.krate(),
                                                                &analysis,
                                                                tcx);
@@ -254,7 +266,8 @@ pub struct CompileState<'a, 'ast: 'a, 'tcx: 'a> {
     pub output_filenames: Option<&'a OutputFilenames>,
     pub out_dir: Option<&'a Path>,
     pub expanded_crate: Option<&'a ast::Crate>,
-    pub ast_map: Option<&'a ast_map::Map<'ast>>,
+    pub hir_crate: Option<&'a hir::Crate>,
+    pub ast_map: Option<&'a hir_map::Map<'ast>>,
     pub analysis: Option<&'a ty::CrateAnalysis>,
     pub tcx: Option<&'a ty::ctxt<'tcx>>,
     pub trans: Option<&'a trans::CrateTranslation>,
@@ -274,6 +287,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
             crate_name: None,
             output_filenames: None,
             expanded_crate: None,
+            hir_crate: None,
             ast_map: None,
             analysis: None,
             tcx: None,
@@ -308,14 +322,16 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
     fn state_after_write_deps(input: &'a Input,
                               session: &'a Session,
                               out_dir: &'a Option<PathBuf>,
-                              ast_map: &'a ast_map::Map<'ast>,
-                              expanded_crate: &'a ast::Crate,
+                              ast_map: &'a hir_map::Map<'ast>,
+                              krate: &'a ast::Crate,
+                              hir_crate: &'a hir::Crate,
                               crate_name: &'a str)
                               -> CompileState<'a, 'ast, 'tcx> {
         CompileState {
             crate_name: Some(crate_name),
             ast_map: Some(ast_map),
-            expanded_crate: Some(expanded_crate),
+            krate: Some(krate),
+            hir_crate: Some(hir_crate),
             .. CompileState::empty(input, session, out_dir)
         }
     }
@@ -323,14 +339,16 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
     fn state_after_analysis(input: &'a Input,
                             session: &'a Session,
                             out_dir: &'a Option<PathBuf>,
-                            expanded_crate: &'a ast::Crate,
+                            krate: &'a ast::Crate,
+                            hir_crate: &'a hir::Crate,
                             analysis: &'a ty::CrateAnalysis,
                             tcx: &'a ty::ctxt<'tcx>)
                             -> CompileState<'a, 'ast, 'tcx> {
         CompileState {
             analysis: Some(analysis),
             tcx: Some(tcx),
-            expanded_crate: Some(expanded_crate),
+            krate: Some(krate),
+            hir_crate: Some(hir_crate),
             .. CompileState::empty(input, session, out_dir)
         }
     }
@@ -582,27 +600,38 @@ pub fn phase_2_configure_and_expand(sess: &Session,
     Some(krate)
 }
 
-pub fn assign_node_ids_and_map<'ast>(sess: &Session,
-                                     forest: &'ast mut ast_map::Forest)
-                                     -> ast_map::Map<'ast> {
+pub fn assign_node_ids(sess: &Session,
+                       krate: ast::Crate) -> ast::Crate {
     struct NodeIdAssigner<'a> {
         sess: &'a Session
     }
 
-    impl<'a> ast_map::FoldOps for NodeIdAssigner<'a> {
-        fn new_id(&self, old_id: ast::NodeId) -> ast::NodeId {
+    impl<'a> Folder for NodeIdAssigner<'a> {
+        fn new_id(&mut self, old_id: ast::NodeId) -> ast::NodeId {
             assert_eq!(old_id, ast::DUMMY_NODE_ID);
             self.sess.next_node_id()
         }
     }
 
-    let map = time(sess.time_passes(), "assigning node ids and indexing ast", move ||
-                   ast_map::map_crate(forest, NodeIdAssigner { sess: sess }));
+    let krate = time(sess.time_passes(),
+                     "assigning node ids",
+                     || NodeIdAssigner { sess: sess }.fold_crate(krate));
 
     if sess.opts.debugging_opts.ast_json {
-        println!("{}", json::as_json(map.krate()));
+        println!("{}", json::as_json(&krate));
     }
 
+    krate
+}
+
+pub fn make_map<'ast>(sess: &Session,
+                      forest: &'ast mut front::map::Forest)
+                      -> front::map::Map<'ast> {
+    // Construct the 'ast'-map
+    let map = time(sess.time_passes(),
+                   "indexing hir",
+                   move || front::map::map_crate(forest));
+
     map
 }
 
@@ -610,14 +639,15 @@ pub fn assign_node_ids_and_map<'ast>(sess: &Session,
 /// miscellaneous analysis passes on the crate. Return various
 /// structures carrying the results of the analysis.
 pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
-                                               ast_map: ast_map::Map<'tcx>,
+                                               ast_map: front::map::Map<'tcx>,
+                                               ast_crate: &ast::Crate,
                                                arenas: &'tcx ty::CtxtArenas<'tcx>,
                                                name: String,
                                                make_glob_map: resolve::MakeGlobMap,
                                                f: F)
                                                -> (Session, R)
                                                where F: for<'a> FnOnce(&'a ty::ctxt<'tcx>,
-                                                               ty::CrateAnalysis) -> R
+                                                                       ty::CrateAnalysis) -> R
 {
     let time_passes = sess.time_passes();
     let krate = ast_map.krate();
@@ -731,7 +761,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
                 &tcx.sess, lib_features_used));
 
         time(time_passes, "lint checking", ||
-            lint::check_crate(tcx, &exported_items));
+            lint::check_crate(tcx, ast_crate, &exported_items));
 
         // The above three passes generate errors w/o aborting
         tcx.sess.abort_if_errors();
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index ed63b815354..bd2b536f907 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -42,6 +42,7 @@ extern crate libc;
 extern crate rustc;
 extern crate rustc_back;
 extern crate rustc_borrowck;
+extern crate rustc_front;
 extern crate rustc_lint;
 extern crate rustc_privacy;
 extern crate rustc_resolve;
@@ -389,6 +390,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
                 time(state.session.time_passes(),
                      "save analysis",
                      || save::process_crate(state.tcx.unwrap(),
+                                            state.krate.unwrap(),
                                             state.analysis.unwrap(),
                                             state.out_dir));
             };
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 818ce005d4c..53beb6d312d 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -19,7 +19,6 @@ use rustc_trans::back::link;
 
 use driver;
 
-use rustc::ast_map::{self, blocks, NodePrinter};
 use rustc::middle::ty;
 use rustc::middle::cfg;
 use rustc::middle::cfg::graphviz::LabelledCFG;
@@ -44,18 +43,23 @@ use std::option;
 use std::path::PathBuf;
 use std::str::FromStr;
 
+use rustc::front::map as hir_map;
+use rustc::front::map::{blocks, NodePrinter};
+use rustc_front::hir;
+use rustc_front::lowering::lower_crate;
+use rustc_front::print::pprust as pprust_hir;
+
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub enum PpSourceMode {
     PpmNormal,
     PpmEveryBodyLoops,
     PpmExpanded,
-    PpmTyped,
     PpmIdentified,
     PpmExpandedIdentified,
     PpmExpandedHygiene,
+    PpmTyped,
 }
 
-
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub enum PpFlowGraphMode {
     Default,
@@ -68,6 +72,7 @@ pub enum PpFlowGraphMode {
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub enum PpMode {
     PpmSource(PpSourceMode),
+    PpmHir(PpSourceMode),
     PpmFlowGraph(PpFlowGraphMode),
 }
 
@@ -79,25 +84,27 @@ pub fn parse_pretty(sess: &Session,
     let opt_second = split.next();
     let first = match (first, extended) {
         ("normal", _)       => PpmSource(PpmNormal),
+        ("identified", _)   => PpmSource(PpmIdentified),
         ("everybody_loops", true) => PpmSource(PpmEveryBodyLoops),
         ("expanded", _)     => PpmSource(PpmExpanded),
-        ("typed", _)        => PpmSource(PpmTyped),
         ("expanded,identified", _) => PpmSource(PpmExpandedIdentified),
         ("expanded,hygiene", _) => PpmSource(PpmExpandedHygiene),
-        ("identified", _)   => PpmSource(PpmIdentified),
+        ("hir", true)       => PpmHir(PpmNormal),
+        ("hir,identified", true) => PpmHir(PpmExpandedIdentified),
+        ("hir,typed", true)        => PpmHir(PpmTyped),
         ("flowgraph", true)    => PpmFlowGraph(PpFlowGraphMode::Default),
         ("flowgraph,unlabelled", true)    => PpmFlowGraph(PpFlowGraphMode::UnlabelledEdges),
         _ => {
             if extended {
                 sess.fatal(&format!(
                     "argument to `unpretty` must be one of `normal`, \
-                     `expanded`, `flowgraph[,unlabelled]=<nodeid>`, `typed`, `identified`, \
-                     `expanded,identified`, or `everybody_loops`; got {}", name));
+                     `expanded`, `flowgraph[,unlabelled]=<nodeid>`, `identified`, \
+                     `expanded,identified`, `everybody_loops`, `hir`, \
+                     `hir,identified`, or `hir,typed`; got {}", name));
             } else {
                 sess.fatal(&format!(
-                    "argument to `pretty` must be one of `normal`, \
-                     `expanded`, `typed`, `identified`, \
-                     or `expanded,identified`; got {}", name));
+                    "argument to `pretty` must be one of `normal`, `expanded`, \
+                     `identified`, or `expanded,identified`; got {}", name));
             }
         }
     };
@@ -124,9 +131,7 @@ impl PpSourceMode {
     /// Constructs a `PrinterSupport` object and passes it to `f`.
     fn call_with_pp_support<'tcx, A, B, F>(&self,
                                            sess: Session,
-                                           ast_map: Option<ast_map::Map<'tcx>>,
-                                           arenas: &'tcx ty::CtxtArenas<'tcx>,
-                                           id: String,
+                                           ast_map: Option<hir_map::Map<'tcx>>,
                                            payload: B,
                                            f: F) -> A where
         F: FnOnce(&PrinterSupport, B) -> A,
@@ -145,18 +150,45 @@ impl PpSourceMode {
                 let annotation = HygieneAnnotation { sess: sess, ast_map: ast_map };
                 f(&annotation, payload)
             }
+            _ => panic!("Should use call_with_pp_support_hir"),
+        }
+    }
+    fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
+                                               sess: Session,
+                                               ast_map: &hir_map::Map<'tcx>,
+                                               ast_crate: &ast::Crate,
+                                               arenas: &'tcx ty::CtxtArenas<'tcx>,
+                                               id: String,
+                                               payload: B,
+                                               f: F) -> A where
+        F: FnOnce(&HirPrinterSupport, B, &hir::Crate) -> A,
+    {
+        match *self {
+            PpmNormal => {
+                let annotation = NoAnn { sess: sess, ast_map: Some(ast_map.clone()) };
+                f(&annotation, payload, &ast_map.forest.krate)
+            }
+
+            PpmIdentified => {
+                let annotation = IdentifiedAnnotation {
+                    sess: sess,
+                    ast_map: Some(ast_map.clone())
+                };
+                f(&annotation, payload, &ast_map.forest.krate)
+            }
             PpmTyped => {
-                let ast_map = ast_map.expect("--pretty=typed missing ast_map");
                 driver::phase_3_run_analysis_passes(sess,
-                                                    ast_map,
+                                                    ast_map.clone(),
+                                                    ast_crate,
                                                     arenas,
                                                     id,
                                                     resolve::MakeGlobMap::No,
                                                     |tcx, _| {
                     let annotation = TypedAnnotation { tcx: tcx };
-                    f(&annotation, payload)
+                    f(&annotation, payload, &ast_map.forest.krate)
                 }).1
             }
+            _ => panic!("Should use call_with_pp_support"),
         }
     }
 }
@@ -167,8 +199,8 @@ trait PrinterSupport<'ast>: pprust::PpAnn {
     fn sess<'a>(&'a self) -> &'a Session;
 
     /// Provides a uniform interface for re-extracting a reference to an
-    /// `ast_map::Map` from a value that now owns it.
-    fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>>;
+    /// `hir_map::Map` from a value that now owns it.
+    fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>>;
 
     /// Produces the pretty-print annotation object.
     ///
@@ -177,32 +209,59 @@ trait PrinterSupport<'ast>: pprust::PpAnn {
     fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn;
 }
 
+trait HirPrinterSupport<'ast>: pprust_hir::PpAnn {
+    /// Provides a uniform interface for re-extracting a reference to a
+    /// `Session` from a value that now owns it.
+    fn sess<'a>(&'a self) -> &'a Session;
+
+    /// Provides a uniform interface for re-extracting a reference to an
+    /// `hir_map::Map` from a value that now owns it.
+    fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>>;
+
+    /// Produces the pretty-print annotation object.
+    ///
+    /// (Rust does not yet support upcasting from a trait object to
+    /// an object for one of its super-traits.)
+    fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn;
+}
+
 struct NoAnn<'ast> {
     sess: Session,
-    ast_map: Option<ast_map::Map<'ast>>
+    ast_map: Option<hir_map::Map<'ast>>
 }
 
 impl<'ast> PrinterSupport<'ast> for NoAnn<'ast> {
     fn sess<'a>(&'a self) -> &'a Session { &self.sess }
 
-    fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>> {
+    fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
         self.ast_map.as_ref()
     }
 
     fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
 }
 
+impl<'ast> HirPrinterSupport<'ast> for NoAnn<'ast> {
+    fn sess<'a>(&'a self) -> &'a Session { &self.sess }
+
+    fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
+        self.ast_map.as_ref()
+    }
+
+    fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { self }
+}
+
 impl<'ast> pprust::PpAnn for NoAnn<'ast> {}
+impl<'ast> pprust_hir::PpAnn for NoAnn<'ast> {}
 
 struct IdentifiedAnnotation<'ast> {
     sess: Session,
-    ast_map: Option<ast_map::Map<'ast>>,
+    ast_map: Option<hir_map::Map<'ast>>,
 }
 
 impl<'ast> PrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
     fn sess<'a>(&'a self) -> &'a Session { &self.sess }
 
-    fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>> {
+    fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
         self.ast_map.as_ref()
     }
 
@@ -249,15 +308,65 @@ impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
     }
 }
 
+impl<'ast> HirPrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
+    fn sess<'a>(&'a self) -> &'a Session { &self.sess }
+
+    fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
+        self.ast_map.as_ref()
+    }
+
+    fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { self }
+}
+
+impl<'ast> pprust_hir::PpAnn for IdentifiedAnnotation<'ast> {
+    fn pre(&self,
+           s: &mut pprust_hir::State,
+           node: pprust_hir::AnnNode) -> io::Result<()> {
+        match node {
+            pprust_hir::NodeExpr(_) => s.popen(),
+            _ => Ok(())
+        }
+    }
+    fn post(&self,
+            s: &mut pprust_hir::State,
+            node: pprust_hir::AnnNode) -> io::Result<()> {
+        match node {
+            pprust_hir::NodeIdent(_) | pprust_hir::NodeName(_) => Ok(()),
+
+            pprust_hir::NodeItem(item) => {
+                try!(pp::space(&mut s.s));
+                s.synth_comment(item.id.to_string())
+            }
+            pprust_hir::NodeSubItem(id) => {
+                try!(pp::space(&mut s.s));
+                s.synth_comment(id.to_string())
+            }
+            pprust_hir::NodeBlock(blk) => {
+                try!(pp::space(&mut s.s));
+                s.synth_comment(format!("block {}", blk.id))
+            }
+            pprust_hir::NodeExpr(expr) => {
+                try!(pp::space(&mut s.s));
+                try!(s.synth_comment(expr.id.to_string()));
+                s.pclose()
+            }
+            pprust_hir::NodePat(pat) => {
+                try!(pp::space(&mut s.s));
+                s.synth_comment(format!("pat {}", pat.id))
+            }
+        }
+    }
+}
+
 struct HygieneAnnotation<'ast> {
     sess: Session,
-    ast_map: Option<ast_map::Map<'ast>>,
+    ast_map: Option<hir_map::Map<'ast>>,
 }
 
 impl<'ast> PrinterSupport<'ast> for HygieneAnnotation<'ast> {
     fn sess<'a>(&'a self) -> &'a Session { &self.sess }
 
-    fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>> {
+    fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
         self.ast_map.as_ref()
     }
 
@@ -289,30 +398,30 @@ struct TypedAnnotation<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
 }
 
-impl<'b, 'tcx> PrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> {
+impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> {
     fn sess<'a>(&'a self) -> &'a Session { &self.tcx.sess }
 
-    fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'tcx>> {
+    fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'tcx>> {
         Some(&self.tcx.map)
     }
 
-    fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
+    fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { self }
 }
 
-impl<'a, 'tcx> pprust::PpAnn for TypedAnnotation<'a, 'tcx> {
+impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> {
     fn pre(&self,
-           s: &mut pprust::State,
-           node: pprust::AnnNode) -> io::Result<()> {
+           s: &mut pprust_hir::State,
+           node: pprust_hir::AnnNode) -> io::Result<()> {
         match node {
-            pprust::NodeExpr(_) => s.popen(),
+            pprust_hir::NodeExpr(_) => s.popen(),
             _ => Ok(())
         }
     }
     fn post(&self,
-            s: &mut pprust::State,
-            node: pprust::AnnNode) -> io::Result<()> {
+            s: &mut pprust_hir::State,
+            node: pprust_hir::AnnNode) -> io::Result<()> {
         match node {
-            pprust::NodeExpr(expr) => {
+            pprust_hir::NodeExpr(expr) => {
                 try!(pp::space(&mut s.s));
                 try!(pp::word(&mut s.s, "as"));
                 try!(pp::space(&mut s.s));
@@ -360,7 +469,7 @@ impl FromStr for UserIdentifiedItem {
 
 enum NodesMatchingUII<'a, 'ast: 'a> {
     NodesMatchingDirect(option::IntoIter<ast::NodeId>),
-    NodesMatchingSuffix(ast_map::NodesMatchingSuffix<'a, 'ast>),
+    NodesMatchingSuffix(hir_map::NodesMatchingSuffix<'a, 'ast>),
 }
 
 impl<'a, 'ast> Iterator for NodesMatchingUII<'a, 'ast> {
@@ -382,7 +491,7 @@ impl UserIdentifiedItem {
         }
     }
 
-    fn all_matching_node_ids<'a, 'ast>(&'a self, map: &'a ast_map::Map<'ast>)
+    fn all_matching_node_ids<'a, 'ast>(&'a self, map: &'a hir_map::Map<'ast>)
                                        -> NodesMatchingUII<'a, 'ast> {
         match *self {
             ItemViaNode(node_id) =>
@@ -392,7 +501,7 @@ impl UserIdentifiedItem {
         }
     }
 
-    fn to_one_node_id(self, user_option: &str, sess: &Session, map: &ast_map::Map) -> ast::NodeId {
+    fn to_one_node_id(self, user_option: &str, sess: &Session, map: &hir_map::Map) -> ast::NodeId {
         let fail_because = |is_wrong_because| -> ast::NodeId {
             let message =
                 format!("{} needs NodeId (int) or unique \
@@ -430,8 +539,9 @@ fn needs_ast_map(ppm: &PpMode, opt_uii: &Option<UserIdentifiedItem>) -> bool {
         PpmSource(PpmExpanded) |
         PpmSource(PpmExpandedIdentified) |
         PpmSource(PpmExpandedHygiene) |
-        PpmSource(PpmTyped) |
-        PpmFlowGraph(_) => true
+        PpmHir(_) |
+        PpmFlowGraph(_) => true,
+        PpmSource(PpmTyped) => panic!("invalid state"),
     }
 }
 
@@ -444,8 +554,9 @@ fn needs_expansion(ppm: &PpMode) -> bool {
         PpmSource(PpmExpanded) |
         PpmSource(PpmExpandedIdentified) |
         PpmSource(PpmExpandedHygiene) |
-        PpmSource(PpmTyped) |
-        PpmFlowGraph(_) => true
+        PpmHir(_) |
+        PpmFlowGraph(_) => true,
+        PpmSource(PpmTyped) => panic!("invalid state"),
     }
 }
 
@@ -552,20 +663,22 @@ pub fn pretty_print_input(sess: Session,
     let krate = if compute_ast_map {
         match driver::phase_2_configure_and_expand(&sess, krate, &id[..], None) {
             None => return,
-            Some(k) => k
+            Some(k) => driver::assign_node_ids(&sess, k)
         }
     } else {
         krate
     };
 
-    let mut forest = ast_map::Forest::new(krate);
+    // There is some twisted, god-forsaken tangle of lifetimes here which makes
+    // the ordering of stuff super-finicky.
+    let mut hir_forest;
     let arenas = ty::CtxtArenas::new();
-
-    let (krate, ast_map) = if compute_ast_map {
-        let map = driver::assign_node_ids_and_map(&sess, &mut forest);
-        (map.krate(), Some(map))
+    let ast_map = if compute_ast_map {
+        hir_forest = hir_map::Forest::new(lower_crate(&krate));
+        let map = driver::make_map(&sess, &mut hir_forest);
+        Some(map)
     } else {
-        (forest.krate(), None)
+        None
     };
 
     let src_name = driver::source_name(input);
@@ -580,15 +693,16 @@ pub fn pretty_print_input(sess: Session,
     let mut out = Vec::new();
 
     match (ppm, opt_uii) {
-        (PpmSource(s), None) => {
+        (PpmSource(s), _) => {
+            // Silently ignores an identified node.
             let out: &mut Write = &mut out;
             s.call_with_pp_support(
-                sess, ast_map, &arenas, id, box out, |annotation, out| {
+                sess, ast_map, box out, |annotation, out| {
                     debug!("pretty printing source code {:?}", s);
                     let sess = annotation.sess();
                     pprust::print_crate(sess.codemap(),
                                         sess.diagnostic(),
-                                        krate,
+                                        &krate,
                                         src_name.to_string(),
                                         &mut rdr,
                                         out,
@@ -597,31 +711,52 @@ pub fn pretty_print_input(sess: Session,
             })
         }
 
-        (PpmSource(s), Some(uii)) => {
+        (PpmHir(s), None) => {
             let out: &mut Write = &mut out;
-            s.call_with_pp_support(
-                sess, ast_map, &arenas, id, (out,uii), |annotation, (out,uii)| {
+            s.call_with_pp_support_hir(
+                sess, &ast_map.unwrap(), &krate, &arenas, id, box out, |annotation, out, krate| {
                     debug!("pretty printing source code {:?}", s);
                     let sess = annotation.sess();
-                    let ast_map = annotation.ast_map()
-                        .expect("--pretty missing ast_map");
-                    let mut pp_state =
-                        pprust::State::new_from_input(sess.codemap(),
+                    pprust_hir::print_crate(sess.codemap(),
+                                            sess.diagnostic(),
+                                            krate,
+                                            src_name.to_string(),
+                                            &mut rdr,
+                                            out,
+                                            annotation.pp_ann(),
+                                            is_expanded)
+            })
+        }
+
+        (PpmHir(s), Some(uii)) => {
+            let out: &mut Write = &mut out;
+            s.call_with_pp_support_hir(sess,
+                                       &ast_map.unwrap(),
+                                       &krate,
+                                       &arenas,
+                                       id,
+                                       (out,uii),
+                                       |annotation, (out,uii), _| {
+                debug!("pretty printing source code {:?}", s);
+                let sess = annotation.sess();
+                let ast_map = annotation.ast_map().expect("--pretty missing ast_map");
+                let mut pp_state =
+                    pprust_hir::State::new_from_input(sess.codemap(),
                                                       sess.diagnostic(),
                                                       src_name.to_string(),
                                                       &mut rdr,
                                                       box out,
                                                       annotation.pp_ann(),
-                                                      is_expanded);
-                    for node_id in uii.all_matching_node_ids(ast_map) {
-                        let node = ast_map.get(node_id);
-                        try!(pp_state.print_node(&node));
-                        try!(pp::space(&mut pp_state.s));
-                        try!(pp_state.synth_comment(ast_map.path_to_string(node_id)));
-                        try!(pp::hardbreak(&mut pp_state.s));
-                    }
-                    pp::eof(&mut pp_state.s)
-                })
+                                                      true);
+                for node_id in uii.all_matching_node_ids(ast_map) {
+                    let node = ast_map.get(node_id);
+                    try!(pp_state.print_node(&node));
+                    try!(pp::space(&mut pp_state.s));
+                    try!(pp_state.synth_comment(ast_map.path_to_string(node_id)));
+                    try!(pp::hardbreak(&mut pp_state.s));
+                }
+                pp::eof(&mut pp_state.s)
+            })
         }
 
         (PpmFlowGraph(mode), opt_uii) => {
@@ -646,6 +781,7 @@ pub fn pretty_print_input(sess: Session,
                     let variants = gather_flowgraph_variants(&sess);
                     driver::phase_3_run_analysis_passes(sess,
                                                         ast_map,
+                                                        &krate,
                                                         &arenas,
                                                         id,
                                                         resolve::MakeGlobMap::No,
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 3277e07dfc1..c96495fcfc9 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -29,7 +29,7 @@ use rustc_typeck::middle::infer;
 use rustc_typeck::middle::infer::lub::Lub;
 use rustc_typeck::middle::infer::glb::Glb;
 use rustc_typeck::middle::infer::sub::Sub;
-use rustc::ast_map;
+use rustc::front::map as hir_map;
 use rustc::session::{self,config};
 use syntax::{abi, ast};
 use syntax::codemap;
@@ -38,6 +38,9 @@ use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note, He
 use syntax::parse::token;
 use syntax::feature_gate::UnstableFeatures;
 
+use rustc_front::lowering::lower_crate;
+use rustc_front::hir;
+
 struct Env<'a, 'tcx: 'a> {
     infcx: &'a infer::InferCtxt<'a, 'tcx>,
 }
@@ -120,9 +123,10 @@ fn test_env<F>(source_string: &str,
     let krate = driver::phase_2_configure_and_expand(&sess, krate, "test", None)
                     .expect("phase 2 aborted");
 
-    let mut forest = ast_map::Forest::new(krate);
+    let krate = driver::assign_node_ids(&sess, krate);
+    let mut hir_forest = hir_map::Forest::new(lower_crate(&krate));
     let arenas = ty::CtxtArenas::new();
-    let ast_map = driver::assign_node_ids_and_map(&sess, &mut forest);
+    let ast_map = driver::make_map(&sess, &mut hir_forest);
     let krate = ast_map.krate();
 
     // run just enough stuff to build a tcx:
@@ -185,7 +189,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
         };
 
         fn search_mod(this: &Env,
-                      m: &ast::Mod,
+                      m: &hir::Mod,
                       idx: usize,
                       names: &[String])
                       -> Option<ast::NodeId> {
@@ -199,7 +203,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
         }
 
         fn search(this: &Env,
-                  it: &ast::Item,
+                  it: &hir::Item,
                   idx: usize,
                   names: &[String])
                   -> Option<ast::NodeId> {
@@ -208,19 +212,19 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
             }
 
             return match it.node {
-                ast::ItemUse(..) | ast::ItemExternCrate(..) |
-                ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemFn(..) |
-                ast::ItemForeignMod(..) | ast::ItemTy(..) => {
+                hir::ItemUse(..) | hir::ItemExternCrate(..) |
+                hir::ItemConst(..) | hir::ItemStatic(..) | hir::ItemFn(..) |
+                hir::ItemForeignMod(..) | hir::ItemTy(..) => {
                     None
                 }
 
-                ast::ItemEnum(..) | ast::ItemStruct(..) |
-                ast::ItemTrait(..) | ast::ItemImpl(..) |
-                ast::ItemMac(..) | ast::ItemDefaultImpl(..) => {
+                hir::ItemEnum(..) | hir::ItemStruct(..) |
+                hir::ItemTrait(..) | hir::ItemImpl(..) |
+                hir::ItemDefaultImpl(..) => {
                     None
                 }
 
-                ast::ItemMod(ref m) => {
+                hir::ItemMod(ref m) => {
                     search_mod(this, m, idx, names)
                 }
             };
@@ -260,7 +264,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
         let input_args = input_tys.iter().cloned().collect();
         self.infcx.tcx.mk_fn(None,
             self.infcx.tcx.mk_bare_fn(ty::BareFnTy {
-                unsafety: ast::Unsafety::Normal,
+                unsafety: hir::Unsafety::Normal,
                 abi: abi::Rust,
                 sig: ty::Binder(ty::FnSig {
                     inputs: input_args,