]> git.lizzy.rs Git - rust.git/commitdiff
Instrument a bunch of tasks that employ the HIR map in one way or
authorNiko Matsakis <niko@alum.mit.edu>
Fri, 29 Jan 2016 20:04:07 +0000 (15:04 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Fri, 5 Feb 2016 18:19:55 +0000 (13:19 -0500)
another and were not previously instrumented.

17 files changed:
src/librustc/dep_graph/mod.rs
src/librustc/middle/effect.rs
src/librustc/middle/entry.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/liveness.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc_driver/driver.rs
src/librustc_driver/pretty.rs
src/librustc_driver/test.rs
src/librustc_metadata/creader.rs
src/librustc_passes/loops.rs
src/librustc_passes/static_recursion.rs
src/librustc_plugin/build.rs
src/librustc_resolve/lib.rs
src/librustc_typeck/lib.rs

index d37a4acbcfb3a81201cca9f1bb2d9f5c3b40f667..faf97f5808e36b1b490431dfda73f633976e3e88 100644 (file)
@@ -40,8 +40,21 @@ pub enum DepNode {
     Hir(DefId),
 
     // Represents different phases in the compiler.
+    CrateReader,
+    CollectLanguageItems,
+    CheckStaticRecursion,
+    ResolveLifetimes,
+    RegionResolveCrate,
+    CheckLoops,
+    PluginRegistrar,
+    StabilityIndex,
     CollectItem(DefId),
     Coherence,
+    EffectCheck,
+    Liveness,
+    Resolve,
+    EntryPoint,
+    CheckEntryFn,
     CoherenceCheckImpl(DefId),
     CoherenceOverlapCheck(DefId),
     CoherenceOverlapCheckSpecial(DefId),
index 055beac5428440d3e4cd0943692de0cd8e489031..c27d029374affc8ebb07a04ad0824c57537dcaba 100644 (file)
@@ -12,6 +12,7 @@
 //! `unsafe`.
 use self::RootUnsafeContext::*;
 
+use dep_graph::DepNode;
 use middle::def::Def;
 use middle::ty::{self, Ty};
 use middle::ty::MethodCall;
@@ -182,6 +183,8 @@ fn visit_expr(&mut self, expr: &hir::Expr) {
 }
 
 pub fn check_crate(tcx: &ty::ctxt) {
+    let _task = tcx.dep_graph.in_task(DepNode::EffectCheck);
+
     let mut visitor = EffectCheckVisitor {
         tcx: tcx,
         unsafe_context: UnsafeContext::new(SafeContext),
index 2d096f66e09f6798e5e9358410bc36322c4fbdbc..67e96816abf96c49db7ed10f38de12a0c8298d02 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 
+use dep_graph::DepNode;
 use front::map as ast_map;
 use middle::def_id::{CRATE_DEF_INDEX};
 use session::{config, Session};
@@ -48,6 +49,8 @@ fn visit_item(&mut self, item: &'tcx Item) {
 }
 
 pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
+    let _task = ast_map.dep_graph.in_task(DepNode::EntryPoint);
+
     let any_exe = session.crate_types.borrow().iter().any(|ty| {
         *ty == config::CrateTypeExecutable
     });
index 6e57d5dd1ba8d5f906e5ff777dc415863a1ca847..f77ca10e88f0ed967350a7386ca8a82c0c58fa66 100644 (file)
@@ -21,6 +21,7 @@
 
 pub use self::LangItem::*;
 
+use dep_graph::DepNode;
 use front::map as hir_map;
 use session::Session;
 use middle::cstore::CrateStore;
@@ -234,6 +235,7 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<InternedString> {
 pub fn collect_language_items(session: &Session,
                               map: &hir_map::Map)
                               -> LanguageItems {
+    let _task = map.dep_graph.in_task(DepNode::CollectLanguageItems);
     let krate: &hir::Crate = map.krate();
     let mut collector = LanguageItemCollector::new(session, map);
     collector.collect(krate);
index 90fa148e0084eb43bed1e683d668f2e453da86bb..5fa9d45934571105dbb43418fe0ac542e7877c4c 100644 (file)
 use self::LiveNodeKind::*;
 use self::VarKind::*;
 
+use dep_graph::DepNode;
 use middle::def::*;
 use middle::pat_util;
 use middle::ty;
@@ -192,6 +193,7 @@ fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
 }
 
 pub fn check_crate(tcx: &ty::ctxt) {
+    let _task = tcx.dep_graph.in_task(DepNode::Liveness);
     tcx.map.krate().visit_all_items(&mut IrMaps::new(tcx));
     tcx.sess.abort_if_errors();
 }
index 1361fac5b161ba5f9bce27e7f887701926fd0b45..bf21b607b778d7f57dab82347ca0742dc520db36 100644 (file)
@@ -16,6 +16,7 @@
 //! Most of the documentation on regions can be found in
 //! `middle/infer/region_inference/README.md`
 
+use dep_graph::DepNode;
 use front::map as ast_map;
 use session::Session;
 use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
@@ -1224,7 +1225,10 @@ fn visit_local(&mut self, l: &Local) {
     }
 }
 
-pub fn resolve_crate(sess: &Session, krate: &hir::Crate) -> RegionMaps {
+pub fn resolve_crate(sess: &Session, map: &ast_map::Map) -> RegionMaps {
+    let _task = map.dep_graph.in_task(DepNode::RegionResolveCrate);
+    let krate = map.krate();
+
     let maps = RegionMaps {
         code_extents: RefCell::new(vec![]),
         code_extent_interner: RefCell::new(FnvHashMap()),
index 48955bd9a15af5278179897dbbc9fe255f1bb931..4bdf716e6370904dd4a01a9927e7650addbc848f 100644 (file)
@@ -18,6 +18,8 @@
 pub use self::DefRegion::*;
 use self::ScopeChain::*;
 
+use dep_graph::DepNode;
+use front::map::Map;
 use session::Session;
 use middle::def::{Def, DefMap};
 use middle::region;
@@ -94,9 +96,11 @@ enum ScopeChain<'a> {
 static ROOT_SCOPE: ScopeChain<'static> = RootScope;
 
 pub fn krate(sess: &Session,
-             krate: &hir::Crate,
+             hir_map: &Map,
              def_map: &DefMap)
              -> Result<NamedRegionMap, usize> {
+    let _task = hir_map.dep_graph.in_task(DepNode::ResolveLifetimes);
+    let krate = hir_map.krate();
     let mut named_region_map = NodeMap();
     try!(sess.track_errors(|| {
         krate.visit_all_items(&mut LifetimeContext {
index e0d38f1c76f6ceea10b7fd3a0c53d72a5388667c..7835f333f192e77efb8597f5a7c17d5e38358ca8 100644 (file)
@@ -14,6 +14,7 @@
 pub use self::StabilityLevel::*;
 
 use dep_graph::DepNode;
+use front::map as hir_map;
 use session::Session;
 use lint;
 use middle::cstore::{CrateStore, LOCAL_CRATE};
@@ -30,7 +31,7 @@
 use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap};
 
 use rustc_front::hir;
-use rustc_front::hir::{Crate, Item, Generics, StructField, Variant};
+use rustc_front::hir::{Item, Generics, StructField, Variant};
 use rustc_front::intravisit::{self, Visitor};
 
 use std::mem::replace;
@@ -278,7 +279,9 @@ fn visit_macro_def(&mut self, md: &'v hir::MacroDef) {
 
 impl<'tcx> Index<'tcx> {
     /// Construct the stability index for a crate being compiled.
-    pub fn build(&mut self, tcx: &ty::ctxt<'tcx>, krate: &Crate, access_levels: &AccessLevels) {
+    pub fn build(&mut self, tcx: &ty::ctxt<'tcx>, access_levels: &AccessLevels) {
+        let _task = tcx.dep_graph.in_task(DepNode::StabilityIndex);
+        let krate = tcx.map.krate();
         let mut annotator = Annotator {
             tcx: tcx,
             index: self,
@@ -291,7 +294,10 @@ pub fn build(&mut self, tcx: &ty::ctxt<'tcx>, krate: &Crate, access_levels: &Acc
                            |v| intravisit::walk_crate(v, krate));
     }
 
-    pub fn new(krate: &Crate) -> Index<'tcx> {
+    pub fn new(hir_map: &hir_map::Map) -> Index<'tcx> {
+        let _task = hir_map.dep_graph.in_task(DepNode::StabilityIndex);
+        let krate = hir_map.krate();
+
         let mut is_staged_api = false;
         for attr in &krate.attrs {
             if attr.name() == "stable" || attr.name() == "unstable" {
index c189df18a82e1ab93ec205a81ba33f4df04519eb..e506639932324ab0dc334b832bcacb8fadf58cc0 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use rustc::dep_graph::DepGraph;
 use rustc::front;
 use rustc::front::map as hir_map;
 use rustc_mir as mir;
@@ -115,9 +116,11 @@ macro_rules! controller_entry_point {
         let expanded_crate = assign_node_ids(sess, expanded_crate);
         // Lower ast -> hir.
         let lcx = LoweringContext::new(sess, Some(&expanded_crate));
+        let dep_graph = DepGraph::new(sess.opts.build_dep_graph);
         let mut hir_forest = time(sess.time_passes(),
                                   "lowering ast -> hir",
-                                  || hir_map::Forest::new(lower_crate(&lcx, &expanded_crate)));
+                                  || hir_map::Forest::new(lower_crate(&lcx, &expanded_crate),
+                                                          dep_graph));
 
         // Discard MTWT tables that aren't required past lowering to HIR.
         if !sess.opts.debugging_opts.keep_mtwt_tables &&
@@ -130,17 +133,20 @@ macro_rules! controller_entry_point {
 
         write_out_deps(sess, &outputs, &id);
 
-        controller_entry_point!(after_write_deps,
-                                sess,
-                                CompileState::state_after_write_deps(input,
-                                                                     sess,
-                                                                     outdir,
-                                                                     &hir_map,
-                                                                     &expanded_crate,
-                                                                     &hir_map.krate(),
-                                                                     &id[..],
-                                                                     &lcx),
-                                Ok(()));
+        {
+            let _ignore = hir_map.dep_graph.in_ignore();
+            controller_entry_point!(after_write_deps,
+                                    sess,
+                                    CompileState::state_after_write_deps(input,
+                                                                         sess,
+                                                                         outdir,
+                                                                         &hir_map,
+                                                                         &expanded_crate,
+                                                                         &hir_map.krate(),
+                                                                         &id[..],
+                                                                         &lcx),
+                                    Ok(()));
+        }
 
         time(sess.time_passes(), "attribute checking", || {
             front::check_attr::check_crate(sess, &expanded_crate);
@@ -166,6 +172,9 @@ macro_rules! controller_entry_point {
                                               control.make_glob_map,
                                               |tcx, mir_map, analysis, result| {
             {
+                // Eventually, we will want to track plugins.
+                let _ignore = tcx.dep_graph.in_ignore();
+
                 let state = CompileState::state_after_analysis(input,
                                                                &tcx.sess,
                                                                outdir,
@@ -735,11 +744,10 @@ macro_rules! try_with_f {
     }
 
     let time_passes = sess.time_passes();
-    let krate = hir_map.krate();
 
     time(time_passes,
          "external crate/lib resolution",
-         || LocalCrateReader::new(sess, cstore, &hir_map).read_crates(krate));
+         || LocalCrateReader::new(sess, cstore, &hir_map).read_crates());
 
     let lang_items = try!(time(time_passes, "language item collection", || {
         sess.track_errors(|| {
@@ -769,7 +777,7 @@ macro_rules! try_with_f {
     let named_region_map = try!(time(time_passes,
                                      "lifetime resolution",
                                      || middle::resolve_lifetime::krate(sess,
-                                                                        krate,
+                                                                        &hir_map,
                                                                         &def_map.borrow())));
 
     time(time_passes,
@@ -777,20 +785,22 @@ macro_rules! try_with_f {
          || middle::entry::find_entry_point(sess, &hir_map));
 
     sess.plugin_registrar_fn.set(time(time_passes, "looking for plugin registrar", || {
-        plugin::build::find_plugin_registrar(sess.diagnostic(), krate)
+        plugin::build::find_plugin_registrar(sess.diagnostic(), &hir_map)
     }));
 
     let region_map = time(time_passes,
                           "region resolution",
-                          || middle::region::resolve_crate(sess, krate));
+                          || middle::region::resolve_crate(sess, &hir_map));
 
     time(time_passes,
          "loop checking",
-         || loops::check_crate(sess, krate));
+         || loops::check_crate(sess, &hir_map));
 
     try!(time(time_passes,
               "static item recursion checking",
-              || static_recursion::check_crate(sess, krate, &def_map.borrow(), &hir_map)));
+              || static_recursion::check_crate(sess, &def_map.borrow(), &hir_map)));
+
+    let index = stability::Index::new(&hir_map);
 
     ty::ctxt::create_and_enter(sess,
                                arenas,
@@ -800,7 +810,7 @@ macro_rules! try_with_f {
                                freevars,
                                region_map,
                                lang_items,
-                               stability::Index::new(krate),
+                               index,
                                |tcx| {
         // passes are timed inside typeck
         try_with_f!(typeck::check_crate(tcx, trait_map), (tcx, None, analysis));
@@ -818,7 +828,7 @@ macro_rules! try_with_f {
 
         // Do not move this check past lint
         time(time_passes, "stability index", || {
-            tcx.stability.borrow_mut().build(tcx, krate, &analysis.access_levels)
+            tcx.stability.borrow_mut().build(tcx, &analysis.access_levels)
         });
 
         time(time_passes,
index 91af78a5bd4fbaaf92ac171aec970f67cb98bbde..58043f385fedf3ee716fa39bd2997179832b52cb 100644 (file)
@@ -19,6 +19,7 @@
 
 use {driver, abort_on_err};
 
+use rustc::dep_graph::DepGraph;
 use rustc::middle::ty;
 use rustc::middle::cfg;
 use rustc::middle::cfg::graphviz::LabelledCFG;
@@ -183,7 +184,7 @@ fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
                     sess: sess,
                     ast_map: Some(ast_map.clone()),
                 };
-                f(&annotation, payload, &ast_map.forest.krate)
+                f(&annotation, payload, ast_map.forest.krate())
             }
 
             PpmIdentified => {
@@ -191,7 +192,7 @@ fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
                     sess: sess,
                     ast_map: Some(ast_map.clone()),
                 };
-                f(&annotation, payload, &ast_map.forest.krate)
+                f(&annotation, payload, ast_map.forest.krate())
             }
             PpmTyped => {
                 abort_on_err(driver::phase_3_run_analysis_passes(sess,
@@ -207,7 +208,7 @@ fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
                     let _ignore = tcx.dep_graph.in_ignore();
                     f(&annotation,
                       payload,
-                      &ast_map.forest.krate)
+                      ast_map.forest.krate())
                 }), sess)
             }
             _ => panic!("Should use call_with_pp_support"),
@@ -706,8 +707,10 @@ pub fn pretty_print_input(sess: Session,
     let mut hir_forest;
     let lcx = LoweringContext::new(&sess, Some(&krate));
     let arenas = ty::CtxtArenas::new();
+    let dep_graph = DepGraph::new(false);
+    let _ignore = dep_graph.in_ignore();
     let ast_map = if compute_ast_map {
-        hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate));
+        hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone());
         let map = driver::make_map(&sess, &mut hir_forest);
         Some(map)
     } else {
index 3389992ebb860653726af14c478e0cced049fb04..3736e045bd19a57420b8f454959024ad4816c24a 100644 (file)
@@ -11,6 +11,7 @@
 //! # Standalone Tests for the Inference Module
 
 use driver;
+use rustc::dep_graph::DepGraph;
 use rustc_lint;
 use rustc_resolve as resolve;
 use rustc_typeck::middle::lang_items;
@@ -118,17 +119,19 @@ fn test_env<F>(source_string: &str,
 
     let krate = driver::assign_node_ids(&sess, krate);
     let lcx = LoweringContext::new(&sess, Some(&krate));
-    let mut hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate));
+    let dep_graph = DepGraph::new(false);
+    let _ignore = dep_graph.in_ignore();
+    let mut hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone());
     let arenas = ty::CtxtArenas::new();
     let ast_map = driver::make_map(&sess, &mut hir_forest);
-    let krate = ast_map.krate();
 
     // run just enough stuff to build a tcx:
     let lang_items = lang_items::collect_language_items(&sess, &ast_map);
     let resolve::CrateMap { def_map, freevars, .. } =
         resolve::resolve_crate(&sess, &ast_map, resolve::MakeGlobMap::No);
-    let named_region_map = resolve_lifetime::krate(&sess, krate, &def_map.borrow());
-    let region_map = region::resolve_crate(&sess, krate);
+    let named_region_map = resolve_lifetime::krate(&sess, &ast_map, &def_map.borrow());
+    let region_map = region::resolve_crate(&sess, &ast_map);
+    let index = stability::Index::new(&ast_map);
     ty::ctxt::create_and_enter(&sess,
                                &arenas,
                                def_map,
@@ -137,7 +140,7 @@ fn test_env<F>(source_string: &str,
                                freevars,
                                region_map,
                                lang_items,
-                               stability::Index::new(krate),
+                               index,
                                |tcx| {
                                    let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
                                    body(Env { infcx: &infcx });
index b569739c40cb9fb84990ac42757a5f4a610510a7..7b094a5900a05e158dff0327361a13075c458f5c 100644 (file)
@@ -18,6 +18,7 @@
 use loader::{self, CratePaths};
 
 use rustc::back::svh::Svh;
+use rustc::dep_graph::DepNode;
 use rustc::session::{config, Session};
 use rustc::session::search_paths::PathKind;
 use rustc::middle::cstore::{CrateStore, validate_crate_name};
@@ -723,7 +724,10 @@ pub fn new(sess: &'a Session, cstore: &'a CStore,
     // Traverses an AST, reading all the information about use'd crates and
     // extern libraries necessary for later resolving, typechecking, linking,
     // etc.
-    pub fn read_crates(&mut self, krate: &hir::Crate) {
+    pub fn read_crates(&mut self) {
+        let _task = self.ast_map.dep_graph.in_task(DepNode::CrateReader);
+        let krate = self.ast_map.krate();
+
         self.process_crate(krate);
         krate.visit_all_items(self);
         self.creader.inject_allocator_crate();
index eb2e445f9b09342d41677c468968d1061b19a903..bce18d3fe6eedfa72f3c14752c64d5d8b7beb57f 100644 (file)
 
 use rustc::session::Session;
 
-use syntax::codemap::Span;
+use rustc::dep_graph::DepNode;
+use rustc::front::map::Map;
 use rustc_front::intravisit::{self, Visitor};
 use rustc_front::hir;
+use syntax::codemap::Span;
 
 #[derive(Clone, Copy, PartialEq)]
 enum Context {
@@ -26,7 +28,9 @@ struct CheckLoopVisitor<'a> {
     cx: Context
 }
 
-pub fn check_crate(sess: &Session, krate: &hir::Crate) {
+pub fn check_crate(sess: &Session, map: &Map) {
+    let _task = map.dep_graph.in_task(DepNode::CheckLoops);
+    let krate = map.krate();
     krate.visit_all_items(&mut CheckLoopVisitor { sess: sess, cx: Normal });
 }
 
index 2d81354495d54567e57da17466f134a76837ec99..329ce21edbef40deaa2ed58ecb569641054c7e09 100644 (file)
@@ -11,6 +11,7 @@
 // This compiler pass detects constants that refer to themselves
 // recursively.
 
+use rustc::dep_graph::DepNode;
 use rustc::front::map as ast_map;
 use rustc::session::{Session, CompileResult};
 use rustc::middle::def::{Def, DefMap};
@@ -90,9 +91,11 @@ fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
 }
 
 pub fn check_crate<'ast>(sess: &Session,
-                         krate: &'ast hir::Crate,
                          def_map: &DefMap,
-                         ast_map: &ast_map::Map<'ast>) -> CompileResult {
+                         ast_map: &ast_map::Map<'ast>)
+                         -> CompileResult {
+    let _task = ast_map.dep_graph.in_task(DepNode::CheckStaticRecursion);
+
     let mut visitor = CheckCrateVisitor {
         sess: sess,
         def_map: def_map,
@@ -100,7 +103,7 @@ pub fn check_crate<'ast>(sess: &Session,
         discriminant_map: RefCell::new(NodeMap()),
     };
     sess.track_errors(|| {
-        krate.visit_all_items(&mut visitor);
+        ast_map.krate().visit_all_items(&mut visitor);
     })
 }
 
index 5adde4304f57c9541b56f76523f0be4655863cb1..fe83b609334497f1ff09e99382da95f897f21f7f 100644 (file)
@@ -14,6 +14,8 @@
 use syntax::attr;
 use syntax::codemap::Span;
 use syntax::errors;
+use rustc::dep_graph::DepNode;
+use rustc::front::map::Map;
 use rustc_front::intravisit::Visitor;
 use rustc_front::hir;
 
@@ -34,8 +36,11 @@ fn visit_item(&mut self, item: &hir::Item) {
 
 /// Find the function marked with `#[plugin_registrar]`, if any.
 pub fn find_plugin_registrar(diagnostic: &errors::Handler,
-                             krate: &hir::Crate)
+                             hir_map: &Map)
                              -> Option<ast::NodeId> {
+    let _task = hir_map.dep_graph.in_task(DepNode::PluginRegistrar);
+    let krate = hir_map.krate();
+
     let mut finder = RegistrarFinder { registrars: Vec::new() };
     krate.visit_all_items(&mut finder);
 
index 64973bd791634f11f92773320bf05b39296b1660..054aa1d5f555ba641cbbd703e5cf380c4c86ba5c 100644 (file)
@@ -47,6 +47,7 @@
 use self::ParentLink::*;
 use self::FallbackChecks::*;
 
+use rustc::dep_graph::DepNode;
 use rustc::front::map as hir_map;
 use rustc::session::Session;
 use rustc::lint;
@@ -3596,6 +3597,15 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
                                ast_map: &'a hir_map::Map<'tcx>,
                                make_glob_map: MakeGlobMap)
                                -> CrateMap {
+    // 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 _task = ast_map.dep_graph.in_task(DepNode::Resolve);
+
     let krate = ast_map.krate();
     let arenas = Resolver::arenas();
     let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, &arenas, None);
index cb0b4d0902c7ce4fc68469cbd04a6865be7ff52f..083eeff9f90c125cfc995ffca869b64f7ec413cc 100644 (file)
 pub use rustc::session;
 pub use rustc::util;
 
+use dep_graph::DepNode;
 use front::map as hir_map;
 use middle::def::Def;
 use middle::infer::{self, TypeOrigin};
@@ -312,6 +313,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
 
 fn check_for_entry_fn(ccx: &CrateCtxt) {
     let tcx = ccx.tcx;
+    let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn);
     match *tcx.sess.entry_fn.borrow() {
         Some((id, sp)) => match tcx.sess.entry_type.get() {
             Some(config::EntryMain) => check_main_fn_ty(ccx, id, sp),