about summary refs log tree commit diff
diff options
context:
space:
mode:
authorIgor Matuszewski <Xanewok@gmail.com>2019-01-13 13:06:26 +0100
committerIgor Matuszewski <Xanewok@gmail.com>2019-01-15 11:10:51 +0100
commitff19a53ef07566aa30860023f6eac6e75ffaf900 (patch)
treea929931a30157db943e9f92a40188c227c48338a
parent33e6df4b62237af312bf6e3f40a97f5bdc94949a (diff)
downloadrust-ff19a53ef07566aa30860023f6eac6e75ffaf900.tar.gz
rust-ff19a53ef07566aa30860023f6eac6e75ffaf900.zip
Querify entry_fn
-rw-r--r--src/librustc/dep_graph/dep_node.rs1
-rw-r--r--src/librustc/middle/dead.rs2
-rw-r--r--src/librustc/middle/entry.rs77
-rw-r--r--src/librustc/session/config.rs8
-rw-r--r--src/librustc/session/mod.rs4
-rw-r--r--src/librustc/ty/query/config.rs6
-rw-r--r--src/librustc/ty/query/mod.rs4
-rw-r--r--src/librustc/ty/query/plumbing.rs1
-rw-r--r--src/librustc_codegen_llvm/debuginfo/mod.rs7
-rw-r--r--src/librustc_codegen_ssa/back/symbol_export.rs2
-rw-r--r--src/librustc_codegen_ssa/base.rs8
-rw-r--r--src/librustc_codegen_utils/lib.rs9
-rw-r--r--src/librustc_driver/driver.rs9
-rw-r--r--src/librustc_mir/monomorphize/collector.rs23
-rw-r--r--src/librustc_mir/monomorphize/item.rs5
-rw-r--r--src/librustc_typeck/check/mod.rs28
-rw-r--r--src/librustc_typeck/lib.rs32
17 files changed, 116 insertions, 110 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 427fe51e6ff..9df41c981eb 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -583,6 +583,7 @@ define_dep_nodes!( <'tcx>
     [] CheckImplItemWellFormed(DefId),
     [] ReachableNonGenerics(CrateNum),
     [] NativeLibraries(CrateNum),
+    [] EntryFn(CrateNum),
     [] PluginRegistrarFn(CrateNum),
     [] ProcMacroDeclsStatic(CrateNum),
     [input] CrateDisambiguator(CrateNum),
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 0c769c91801..abbf0ae210c 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -409,7 +409,7 @@ fn create_and_seed_worklist<'a, 'tcx>(
         }
     }).chain(
         // Seed entry point
-        tcx.sess.entry_fn.borrow().map(|(id, _, _)| id)
+        tcx.entry_fn(LOCAL_CRATE).map(|(def_id, _)| tcx.hir().as_local_node_id(def_id).unwrap())
     ).collect::<Vec<_>>();
 
     // Seed implemented trait items
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index 6b593a1a9f9..218ca3b7553 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -1,5 +1,5 @@
 use hir::map as hir_map;
-use hir::def_id::{CRATE_DEF_INDEX};
+use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
 use session::{config, Session};
 use session::config::EntryFnType;
 use syntax::ast::NodeId;
@@ -8,6 +8,8 @@ use syntax::entry::EntryPointType;
 use syntax_pos::Span;
 use hir::{Item, ItemKind, ImplItem, TraitItem};
 use hir::itemlikevisit::ItemLikeVisitor;
+use ty::TyCtxt;
+use ty::query::Providers;
 
 struct EntryContext<'a, 'tcx: 'a> {
     session: &'a Session,
@@ -45,36 +47,34 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
     }
 }
 
-pub fn find_entry_point(session: &Session,
-                        hir_map: &hir_map::Map<'_>,
-                        crate_name: &str) {
-    let any_exe = session.crate_types.borrow().iter().any(|ty| {
+fn entry_fn(tcx: TyCtxt<'_, '_, '_>, cnum: CrateNum) -> Option<(DefId, EntryFnType)> {
+    assert_eq!(cnum, LOCAL_CRATE);
+
+    let any_exe = tcx.sess.crate_types.borrow().iter().any(|ty| {
         *ty == config::CrateType::Executable
     });
     if !any_exe {
         // No need to find a main function
-        session.entry_fn.set(None);
-        return
+        return None;
     }
 
     // If the user wants no main function at all, then stop here.
-    if attr::contains_name(&hir_map.krate().attrs, "no_main") {
-        session.entry_fn.set(None);
-        return
+    if attr::contains_name(&tcx.hir().krate().attrs, "no_main") {
+        return None;
     }
 
     let mut ctxt = EntryContext {
-        session,
-        map: hir_map,
+        session: tcx.sess,
+        map: tcx.hir(),
         main_fn: None,
         attr_main_fn: None,
         start_fn: None,
         non_main_fns: Vec::new(),
     };
 
-    hir_map.krate().visit_all_item_likes(&mut ctxt);
+    tcx.hir().krate().visit_all_item_likes(&mut ctxt);
 
-    configure_main(&mut ctxt, crate_name);
+    configure_main(tcx, &ctxt)
 }
 
 // Beware, this is duplicated in `libsyntax/entry.rs`, so make sure to keep
@@ -135,43 +135,58 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
                     .span_label(item.span, "multiple `start` functions")
                     .emit();
             }
-        },
-        EntryPointType::None => ()
+        }
+        EntryPointType::None => (),
     }
 }
 
-fn configure_main(this: &mut EntryContext<'_, '_>, crate_name: &str) {
-    if let Some((node_id, span)) = this.start_fn {
-        this.session.entry_fn.set(Some((node_id, span, EntryFnType::Start)));
-    } else if let Some((node_id, span)) = this.attr_main_fn {
-        this.session.entry_fn.set(Some((node_id, span, EntryFnType::Main)));
-    } else if let Some((node_id, span)) = this.main_fn {
-        this.session.entry_fn.set(Some((node_id, span, EntryFnType::Main)));
+fn configure_main(
+    tcx: TyCtxt<'_, '_, '_>,
+    visitor: &EntryContext<'_, '_>,
+) -> Option<(DefId, EntryFnType)> {
+    if let Some((node_id, _)) = visitor.start_fn {
+        Some((tcx.hir().local_def_id(node_id), EntryFnType::Start))
+    } else if let Some((node_id, _)) = visitor.attr_main_fn {
+        Some((tcx.hir().local_def_id(node_id), EntryFnType::Main))
+    } else if let Some((node_id, _)) = visitor.main_fn {
+        Some((tcx.hir().local_def_id(node_id), EntryFnType::Main))
     } else {
         // No main function
-        this.session.entry_fn.set(None);
-        let mut err = struct_err!(this.session, E0601,
-            "`main` function not found in crate `{}`", crate_name);
-        if !this.non_main_fns.is_empty() {
+        let mut err = struct_err!(tcx.sess, E0601,
+            "`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE));
+        if !visitor.non_main_fns.is_empty() {
             // There were some functions named 'main' though. Try to give the user a hint.
             err.note("the main function must be defined at the crate level \
                       but you have one or more functions named 'main' that are not \
                       defined at the crate level. Either move the definition or \
                       attach the `#[main]` attribute to override this behavior.");
-            for &(_, span) in &this.non_main_fns {
+            for &(_, span) in &visitor.non_main_fns {
                 err.span_note(span, "here is a function named 'main'");
             }
             err.emit();
-            this.session.abort_if_errors();
+            tcx.sess.abort_if_errors();
         } else {
-            if let Some(ref filename) = this.session.local_crate_source_file {
+            if let Some(ref filename) = tcx.sess.local_crate_source_file {
                 err.note(&format!("consider adding a `main` function to `{}`", filename.display()));
             }
-            if this.session.teach(&err.get_code().unwrap()) {
+            if tcx.sess.teach(&err.get_code().unwrap()) {
                 err.note("If you don't know the basics of Rust, you can go look to the Rust Book \
                           to get started: https://doc.rust-lang.org/book/");
             }
             err.emit();
         }
+
+        None
     }
 }
+
+pub fn find_entry_point(tcx: TyCtxt<'_, '_, '_>) -> Option<(DefId, EntryFnType)> {
+    tcx.entry_fn(LOCAL_CRATE)
+}
+
+pub fn provide(providers: &mut Providers<'_>) {
+    *providers = Providers {
+        entry_fn,
+        ..*providers
+    };
+}
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 42adc6a87fd..41e75aa32ef 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -649,15 +649,15 @@ impl Options {
     }
 }
 
-// The type of entry function, so
-// users can have their own entry
-// functions
-#[derive(Copy, Clone, PartialEq)]
+// The type of entry function, so users can have their own entry functions
+#[derive(Copy, Clone, PartialEq, Hash, Debug)]
 pub enum EntryFnType {
     Main,
     Start,
 }
 
+impl_stable_hash_via_hash!(EntryFnType);
+
 #[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)]
 pub enum CrateType {
     Executable,
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 7363b8b3a78..cf00bf330de 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -67,8 +67,6 @@ pub struct Session {
     /// This is `None` if the host and target are the same.
     pub target_tlib_path: Option<SearchPath>,
     pub parse_sess: ParseSess,
-    /// For a library crate, this is always none
-    pub entry_fn: Once<Option<(NodeId, Span, config::EntryFnType)>>,
     pub sysroot: PathBuf,
     /// The name of the root source file of the crate, in the local file system.
     /// `None` means that there is no source file.
@@ -1173,8 +1171,6 @@ pub fn build_session_(
         host_tlib_path,
         target_tlib_path,
         parse_sess: p_s,
-        // For a library crate, this is always none
-        entry_fn: Once::new(),
         sysroot,
         local_crate_source_file,
         working_dir,
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
index ca5d1f6bd32..38e90d6d823 100644
--- a/src/librustc/ty/query/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -629,6 +629,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::foreign_modules<'tcx> {
     }
 }
 
+impl<'tcx> QueryDescription<'tcx> for queries::entry_fn<'tcx> {
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up the entry function of a crate".into()
+    }
+}
+
 impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> {
     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
         "looking up the plugin registrar for a crate".into()
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index 39d76ceed95..ef5a98e6ecb 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -22,7 +22,7 @@ use mir::mono::CodegenUnit;
 use mir;
 use mir::interpret::GlobalId;
 use session::{CompileResult, CrateDisambiguator};
-use session::config::OutputFilenames;
+use session::config::{EntryFnType, OutputFilenames};
 use traits::{self, Vtable};
 use traits::query::{
     CanonicalPredicateGoal, CanonicalProjectionGoal,
@@ -476,6 +476,8 @@ define_queries! { <'tcx>
 
         [] fn foreign_modules: ForeignModules(CrateNum) -> Lrc<Vec<ForeignModule>>,
 
+        // For a library crate, this is always none
+        [] fn entry_fn: EntryFn(CrateNum) -> Option<(DefId, EntryFnType)>,
         [] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
         [] fn proc_macro_decls_static: ProcMacroDeclsStatic(CrateNum) -> Option<DefId>,
         [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator,
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index 562cd75a75f..bb47d9a9db9 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -1362,6 +1362,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         DepKind::CheckImplItemWellFormed => { force!(check_impl_item_well_formed, def_id!()); }
         DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); }
         DepKind::NativeLibraries => { force!(native_libraries, krate!()); }
+        DepKind::EntryFn => { force!(entry_fn, krate!()); }
         DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); }
         DepKind::ProcMacroDeclsStatic => { force!(proc_macro_decls_static, krate!()); }
         DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); }
diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs
index 2eab626ae8e..b504aa515fd 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/src/librustc_codegen_llvm/debuginfo/mod.rs
@@ -14,7 +14,7 @@ use llvm;
 use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilder, DISubprogram, DIArray, DIFlags,
     DILexicalBlock};
 use rustc::hir::CodegenFnAttrFlags;
-use rustc::hir::def_id::{DefId, CrateNum};
+use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
 use rustc::ty::subst::{Substs, UnpackedKind};
 
 use abi::Abi;
@@ -290,9 +290,8 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
 
         let mut flags = DIFlags::FlagPrototyped;
 
-        let local_id = self.tcx().hir().as_local_node_id(def_id);
-        if let Some((id, _, _)) = *self.sess().entry_fn.borrow() {
-            if local_id == Some(id) {
+        if let Some((id, _)) = self.tcx.entry_fn(LOCAL_CRATE) {
+            if id == def_id {
                 flags |= DIFlags::FlagMainSubprogram;
             }
         }
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index bf69089a254..c372892c521 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -194,7 +194,7 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  })
                                  .collect();
 
-    if tcx.sess.entry_fn.borrow().is_some() {
+    if tcx.entry_fn(LOCAL_CRATE).is_some() {
         let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new("main"));
 
         symbols.push((exported_symbol, SymbolExportLevel::C));
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index b88ec075653..38caacba4d0 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -441,10 +441,8 @@ pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
 pub fn maybe_create_entry_wrapper<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
     cx: &'a Bx::CodegenCx
 ) {
-    let (main_def_id, span) = match *cx.sess().entry_fn.borrow() {
-        Some((id, span, _)) => {
-            (cx.tcx().hir().local_def_id(id), span)
-        }
+    let (main_def_id, span) = match cx.tcx().entry_fn(LOCAL_CRATE) {
+        Some((def_id, _)) => { (def_id, cx.tcx().def_span(def_id)) },
         None => return,
     };
 
@@ -458,7 +456,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
 
     let main_llfn = cx.get_fn(instance);
 
-    let et = cx.sess().entry_fn.get().map(|e| e.2);
+    let et = cx.tcx().entry_fn(LOCAL_CRATE).map(|e| e.1);
     match et {
         Some(EntryFnType::Main) => create_entry_fn::<Bx>(cx, span, main_llfn, main_def_id, true),
         Some(EntryFnType::Start) => create_entry_fn::<Bx>(cx, span, main_llfn, main_def_id, false),
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index b59bca0ae0e..5f61852178d 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -31,6 +31,7 @@ extern crate syntax_pos;
 #[macro_use] extern crate rustc_data_structures;
 
 use rustc::ty::TyCtxt;
+use rustc::hir::def_id::LOCAL_CRATE;
 
 pub mod link;
 pub mod codegen_backend;
@@ -42,11 +43,9 @@ pub mod symbol_names_test;
 /// that actually test that compilation succeeds without
 /// reporting an error.
 pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
-    if let Some((id, span, _)) = *tcx.sess.entry_fn.borrow() {
-        let main_def_id = tcx.hir().local_def_id(id);
-
-        if tcx.has_attr(main_def_id, "rustc_error") {
-            tcx.sess.span_fatal(span, "compilation successful");
+    if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) {
+        if tcx.has_attr(def_id, "rustc_error") {
+            tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful");
         }
     }
 }
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 3b7de37ae4b..42441100723 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -1174,6 +1174,7 @@ pub fn default_provide(providers: &mut ty::query::Providers) {
     rustc_passes::provide(providers);
     rustc_traits::provide(providers);
     middle::region::provide(providers);
+    middle::entry::provide(providers);
     cstore::provide(providers);
     lint::provide(providers);
 }
@@ -1210,10 +1211,6 @@ where
         rustc_incremental::load_query_result_cache(sess)
     });
 
-    time(sess, "looking for entry point", || {
-        middle::entry::find_entry_point(sess, &hir_map, name)
-    });
-
     let mut local_providers = ty::query::Providers::default();
     default_provide(&mut local_providers);
     codegen_backend.provide(&mut local_providers);
@@ -1243,6 +1240,10 @@ where
             // tcx available.
             time(sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx));
 
+            time(sess, "looking for entry point", || {
+                middle::entry::find_entry_point(tcx)
+            });
+
             time(sess, "looking for plugin registrar", || {
                 plugin::build::find_plugin_registrar(tcx)
             });
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index a6a8fe5ade5..eb49547e9bf 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -177,13 +177,13 @@
 use rustc::hir::{self, CodegenFnAttrFlags};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 
-use rustc::hir::def_id::DefId;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::mir::interpret::{AllocId, ConstValue};
 use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind};
 use rustc::ty::adjustment::CustomCoerceUnsized;
-use rustc::session::config;
+use rustc::session::config::EntryFnType;
 use rustc::mir::{self, Location, Promoted};
 use rustc::mir::visit::Visitor as MirVisitor;
 use rustc::mir::mono::MonoItem;
@@ -321,9 +321,7 @@ fn collect_roots<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let mut roots = Vec::new();
 
     {
-        let entry_fn = tcx.sess.entry_fn.borrow().map(|(node_id, _, _)| {
-            tcx.hir().local_def_id(node_id)
-        });
+        let entry_fn = tcx.entry_fn(LOCAL_CRATE);
 
         debug!("collect_roots: entry_fn = {:?}", entry_fn);
 
@@ -924,7 +922,7 @@ struct RootCollector<'b, 'a: 'b, 'tcx: 'a + 'b> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     mode: MonoItemCollectionMode,
     output: &'b mut Vec<MonoItem<'tcx>>,
-    entry_fn: Option<DefId>,
+    entry_fn: Option<(DefId, EntryFnType)>,
 }
 
 impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
@@ -1023,7 +1021,7 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> {
                 true
             }
             MonoItemCollectionMode::Lazy => {
-                self.entry_fn == Some(def_id) ||
+                self.entry_fn.map(|(id, _)| id) == Some(def_id) ||
                 self.tcx.is_reachable_non_generic(def_id) ||
                 self.tcx.codegen_fn_attrs(def_id).flags.contains(
                     CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
@@ -1048,14 +1046,9 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> {
     /// the return type of `main`. This is not needed when
     /// the user writes their own `start` manually.
     fn push_extra_entry_roots(&mut self) {
-        if self.tcx.sess.entry_fn.get().map(|e| e.2) != Some(config::EntryFnType::Main) {
-            return
-        }
-
-        let main_def_id = if let Some(def_id) = self.entry_fn {
-            def_id
-        } else {
-            return
+        let main_def_id = match self.entry_fn {
+            Some((def_id, EntryFnType::Main)) => def_id,
+            _ => return,
         };
 
         let start_def_id = match self.tcx.lang_items().require(StartFnLangItem) {
diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs
index 7014f539d57..c831cbd9829 100644
--- a/src/librustc_mir/monomorphize/item.rs
+++ b/src/librustc_mir/monomorphize/item.rs
@@ -1,6 +1,6 @@
 use monomorphize::Instance;
 use rustc::hir;
-use rustc::hir::def_id::DefId;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::session::config::OptLevel;
 use rustc::ty::{self, Ty, TyCtxt, ClosureSubsts, GeneratorSubsts};
 use rustc::ty::subst::Substs;
@@ -75,8 +75,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug {
 
         match *self.as_mono_item() {
             MonoItem::Fn(ref instance) => {
-                let entry_def_id =
-                    tcx.sess.entry_fn.borrow().map(|(id, _, _)| tcx.hir().local_def_id(id));
+                let entry_def_id = tcx.entry_fn(LOCAL_CRATE).map(|(id, _)| id);
                 // If this function isn't inlined or otherwise has explicit
                 // linkage, then we'll be creating a globally shared version.
                 if self.explicit_linkage(tcx).is_some() ||
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 1b07385d4d1..cb7e8398587 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -132,7 +132,8 @@ use std::ops::{self, Deref};
 use std::slice;
 
 use require_c_abi_if_variadic;
-use session::{CompileIncomplete, config, Session};
+use session::{CompileIncomplete, Session};
+use session::config::EntryFnType;
 use TypeAndSubsts;
 use lint;
 use util::captures::Captures;
@@ -1163,19 +1164,18 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
 
     // Check that the main return type implements the termination trait.
     if let Some(term_id) = fcx.tcx.lang_items().termination() {
-        if let Some((id, _, entry_type)) = *fcx.tcx.sess.entry_fn.borrow() {
-            if id == fn_id {
-                if let config::EntryFnType::Main = entry_type {
-                    let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
-                    let trait_ref = ty::TraitRef::new(term_id, substs);
-                    let return_ty_span = decl.output.span();
-                    let cause = traits::ObligationCause::new(
-                        return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
-
-                    inherited.register_predicate(
-                        traits::Obligation::new(
-                            cause, param_env, trait_ref.to_predicate()));
-                }
+        if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) {
+            let main_id = fcx.tcx.hir().as_local_node_id(def_id).unwrap();
+            if main_id == fn_id {
+                let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
+                let trait_ref = ty::TraitRef::new(term_id, substs);
+                let return_ty_span = decl.output.span();
+                let cause = traits::ObligationCause::new(
+                    return_ty_span, fn_id, ObligationCauseCode::MainFunctionType);
+
+                inherited.register_predicate(
+                    traits::Obligation::new(
+                        cause, param_env, trait_ref.to_predicate()));
             }
         }
     }
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index c55a1258ce9..fb5b28c55da 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -104,23 +104,22 @@ mod namespace;
 mod outlives;
 mod variance;
 
-use hir::Node;
 use rustc_target::spec::abi::Abi;
-use rustc::hir;
+use rustc::hir::{self, Node};
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::infer::InferOk;
 use rustc::lint;
 use rustc::middle;
 use rustc::session;
-use rustc::session::config::nightly_options;
+use rustc::session::CompileIncomplete;
+use rustc::session::config::{EntryFnType, nightly_options};
 use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt};
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::query::Providers;
 use rustc::util;
 use rustc::util::profiling::ProfileCategory;
-use session::{CompileIncomplete, config};
 use syntax_pos::Span;
-use syntax::ast;
 use util::common::time;
 
 use std::iter;
@@ -185,10 +184,9 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     })
 }
 
-fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                              main_id: ast::NodeId,
-                              main_span: Span) {
-    let main_def_id = tcx.hir().local_def_id(main_id);
+fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, main_def_id: DefId) {
+    let main_id = tcx.hir().as_local_node_id(main_def_id).unwrap();
+    let main_span = tcx.def_span(main_def_id);
     let main_t = tcx.type_of(main_def_id);
     match main_t.sty {
         ty::FnDef(..) => {
@@ -251,10 +249,9 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 }
 
-fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                               start_id: ast::NodeId,
-                               start_span: Span) {
-    let start_def_id = tcx.hir().local_def_id(start_id);
+fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, start_def_id: DefId) {
+    let start_id = tcx.hir().as_local_node_id(start_def_id).unwrap();
+    let start_span = tcx.def_span(start_def_id);
     let start_t = tcx.type_of(start_def_id);
     match start_t.sty {
         ty::FnDef(..) => {
@@ -310,11 +307,10 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    if let Some((id, sp, entry_type)) = *tcx.sess.entry_fn.borrow() {
-        match entry_type {
-            config::EntryFnType::Main => check_main_fn_ty(tcx, id, sp),
-            config::EntryFnType::Start => check_start_fn_ty(tcx, id, sp),
-        }
+    match tcx.entry_fn(LOCAL_CRATE) {
+        Some((def_id, EntryFnType::Main)) => check_main_fn_ty(tcx, def_id),
+        Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id),
+        _ => {}
     }
 }