about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-08-31 08:57:41 -0700
committerAlex Crichton <alex@alexcrichton.com>2017-09-05 07:37:57 -0700
commita2e2aba07da5038ba13051a45de8f61d538d517a (patch)
treef498c867dccb87bcf880f89874f998702ac101e5
parent43ae38019167ef02e53cfc202df8b6be0f79c32d (diff)
downloadrust-a2e2aba07da5038ba13051a45de8f61d538d517a.tar.gz
rust-a2e2aba07da5038ba13051a45de8f61d538d517a.zip
rustc: Migrate lang items to a query
This commit moves the calculation of the `LanguageItems` structure into a
query rather than being calculated before the `TyCtxt` exists, with the eventual
end goal of removing some `CrateStore` methods.
-rw-r--r--src/librustc/dep_graph/dep_node.rs1
-rw-r--r--src/librustc/middle/dead.rs2
-rw-r--r--src/librustc/middle/expr_use_visitor.rs6
-rw-r--r--src/librustc/middle/lang_items.rs76
-rw-r--r--src/librustc/middle/reachable.rs2
-rw-r--r--src/librustc/middle/weak_lang_items.rs40
-rw-r--r--src/librustc/traits/error_reporting.rs2
-rw-r--r--src/librustc/traits/object_safety.rs2
-rw-r--r--src/librustc/traits/project.rs4
-rw-r--r--src/librustc/traits/select.rs24
-rw-r--r--src/librustc/ty/adjustment.rs4
-rw-r--r--src/librustc/ty/context.rs12
-rw-r--r--src/librustc/ty/layout.rs4
-rw-r--r--src/librustc/ty/maps.rs13
-rw-r--r--src/librustc/ty/mod.rs6
-rw-r--r--src/librustc/ty/util.rs2
-rw-r--r--src/librustc/util/ppaux.rs4
-rw-r--r--src/librustc_driver/driver.rs7
-rw-r--r--src/librustc_lint/builtin.rs2
-rw-r--r--src/librustc_metadata/encoder.rs7
-rw-r--r--src/librustc_mir/build/matches/test.rs2
-rw-r--r--src/librustc_mir/shim.rs4
-rw-r--r--src/librustc_mir/transform/generator.rs2
-rw-r--r--src/librustc_mir/transform/inline.rs2
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs4
-rw-r--r--src/librustc_mir/transform/type_check.rs2
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs2
-rw-r--r--src/librustc_passes/consts.rs2
-rw-r--r--src/librustc_trans/collector.rs4
-rw-r--r--src/librustc_trans/common.rs4
-rw-r--r--src/librustc_trans/context.rs4
-rw-r--r--src/librustc_trans/intrinsic.rs2
-rw-r--r--src/librustc_trans/mir/analyze.rs2
-rw-r--r--src/librustc_trans/mir/constant.rs2
-rw-r--r--src/librustc_trans/mir/rvalue.rs2
-rw-r--r--src/librustc_trans/monomorphize.rs10
-rw-r--r--src/librustc_typeck/astconv.rs6
-rw-r--r--src/librustc_typeck/check/autoderef.rs2
-rw-r--r--src/librustc_typeck/check/callee.rs8
-rw-r--r--src/librustc_typeck/check/closure.rs6
-rw-r--r--src/librustc_typeck/check/coercion.rs4
-rw-r--r--src/librustc_typeck/check/method/confirm.rs2
-rw-r--r--src/librustc_typeck/check/method/probe.rs39
-rw-r--r--src/librustc_typeck/check/method/suggest.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs8
-rw-r--r--src/librustc_typeck/check/op.rs2
-rw-r--r--src/librustc_typeck/check/wfcheck.rs2
-rw-r--r--src/librustc_typeck/coherence/builtin.rs10
-rw-r--r--src/librustc_typeck/coherence/inherent_impls.rs39
-rw-r--r--src/librustc_typeck/coherence/mod.rs2
-rw-r--r--src/librustc_typeck/collect.rs2
-rw-r--r--src/librustc_typeck/variance/terms.rs17
52 files changed, 207 insertions, 214 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index aa1a8726f9d..3d003b96583 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -560,6 +560,7 @@ define_dep_nodes!( <'tcx>
     [] CrateName(CrateNum),
     [] ItemChildren(DefId),
     [] ExternModStmtCnum(HirId),
+    [] GetLangItems,
 );
 
 trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index b8624722692..d79e90690ca 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -469,7 +469,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
     fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool {
         let field_type = self.tcx.type_of(self.tcx.hir.local_def_id(field.id));
         let is_marker_field = match field_type.ty_to_def_id() {
-            Some(def_id) => self.tcx.lang_items.items().iter().any(|item| *item == Some(def_id)),
+            Some(def_id) => self.tcx.lang_items().items().iter().any(|item| *item == Some(def_id)),
             _ => false
         };
         !field.is_positional()
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 374b02125a1..73f78477b0a 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -211,9 +211,9 @@ enum OverloadedCallType {
 impl OverloadedCallType {
     fn from_trait_id(tcx: TyCtxt, trait_id: DefId) -> OverloadedCallType {
         for &(maybe_function_trait, overloaded_call_type) in &[
-            (tcx.lang_items.fn_once_trait(), FnOnceOverloadedCall),
-            (tcx.lang_items.fn_mut_trait(), FnMutOverloadedCall),
-            (tcx.lang_items.fn_trait(), FnOverloadedCall)
+            (tcx.lang_items().fn_once_trait(), FnOnceOverloadedCall),
+            (tcx.lang_items().fn_mut_trait(), FnMutOverloadedCall),
+            (tcx.lang_items().fn_trait(), FnOverloadedCall)
         ] {
             match maybe_function_trait {
                 Some(function_trait) if function_trait == trait_id => {
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 351daa198e8..d08d7eb48b6 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -21,10 +21,8 @@
 
 pub use self::LangItem::*;
 
-use hir::map as hir_map;
-use session::Session;
 use hir::def_id::DefId;
-use ty;
+use ty::{self, TyCtxt};
 use middle::weak_lang_items;
 use util::nodemap::FxHashMap;
 
@@ -116,9 +114,7 @@ impl LanguageItems {
 struct LanguageItemCollector<'a, 'tcx: 'a> {
     items: LanguageItems,
 
-    hir_map: &'a hir_map::Map<'tcx>,
-
-    session: &'a Session,
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     item_refs: FxHashMap<&'static str, usize>,
 }
@@ -129,10 +125,11 @@ impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> {
             let item_index = self.item_refs.get(&*value.as_str()).cloned();
 
             if let Some(item_index) = item_index {
-                self.collect_item(item_index, self.hir_map.local_def_id(item.id))
+                let def_id = self.tcx.hir.local_def_id(item.id);
+                self.collect_item(item_index, def_id);
             } else {
-                let span = self.hir_map.span(item.id);
-                span_err!(self.session, span, E0522,
+                let span = self.tcx.hir.span(item.id);
+                span_err!(self.tcx.sess, span, E0522,
                           "definition of an unknown language item: `{}`.",
                           value);
             }
@@ -149,45 +146,41 @@ impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
-    pub fn new(session: &'a Session, hir_map: &'a hir_map::Map<'tcx>)
-               -> LanguageItemCollector<'a, 'tcx> {
+    fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItemCollector<'a, 'tcx> {
         let mut item_refs = FxHashMap();
 
         $( item_refs.insert($name, $variant as usize); )*
 
         LanguageItemCollector {
-            session,
-            hir_map,
+            tcx,
             items: LanguageItems::new(),
             item_refs,
         }
     }
 
-    pub fn collect_item(&mut self, item_index: usize,
-                        item_def_id: DefId) {
+    fn collect_item(&mut self, item_index: usize, item_def_id: DefId) {
         // Check for duplicates.
         match self.items.items[item_index] {
             Some(original_def_id) if original_def_id != item_def_id => {
-                let cstore = &self.session.cstore;
                 let name = LanguageItems::item_name(item_index);
-                let mut err = match self.hir_map.span_if_local(item_def_id) {
+                let mut err = match self.tcx.hir.span_if_local(item_def_id) {
                     Some(span) => struct_span_err!(
-                        self.session,
+                        self.tcx.sess,
                         span,
                         E0152,
                         "duplicate lang item found: `{}`.",
                         name),
-                    None => self.session.struct_err(&format!(
+                    None => self.tcx.sess.struct_err(&format!(
                             "duplicate lang item in crate `{}`: `{}`.",
-                            cstore.crate_name_untracked(item_def_id.krate),
+                            self.tcx.crate_name(item_def_id.krate),
                             name)),
                 };
-                if let Some(span) = self.hir_map.span_if_local(original_def_id) {
+                if let Some(span) = self.tcx.hir.span_if_local(original_def_id) {
                     span_note!(&mut err, span,
                                "first defined here.");
                 } else {
                     err.note(&format!("first defined in crate `{}`.",
-                                      cstore.crate_name_untracked(original_def_id.krate)));
+                                      self.tcx.crate_name(original_def_id.krate)));
                 }
                 err.emit();
             }
@@ -199,26 +192,6 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
         // Matched.
         self.items.items[item_index] = Some(item_def_id);
     }
-
-    pub fn collect_local_language_items(&mut self, krate: &hir::Crate) {
-        krate.visit_all_item_likes(self);
-    }
-
-    pub fn collect_external_language_items(&mut self) {
-        let cstore = &self.session.cstore;
-
-        for cnum in cstore.crates() {
-            for (index, item_index) in cstore.lang_items(cnum) {
-                let def_id = DefId { krate: cnum, index: index };
-                self.collect_item(item_index, def_id);
-            }
-        }
-    }
-
-    pub fn collect(&mut self, krate: &hir::Crate) {
-        self.collect_external_language_items();
-        self.collect_local_language_items(krate);
-    }
 }
 
 pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
@@ -233,14 +206,17 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
     return None;
 }
 
-pub fn collect_language_items(session: &Session,
-                              map: &hir_map::Map)
-                              -> LanguageItems {
-    let krate: &hir::Crate = map.krate();
-    let mut collector = LanguageItemCollector::new(session, map);
-    collector.collect(krate);
+pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems {
+    let mut collector = LanguageItemCollector::new(tcx);
+    for cnum in tcx.sess.cstore.crates() {
+        for (index, item_index) in tcx.sess.cstore.lang_items(cnum) {
+            let def_id = DefId { krate: cnum, index: index };
+            collector.collect_item(item_index, def_id);
+        }
+    }
+    tcx.hir.krate().visit_all_item_likes(&mut collector);
     let LanguageItemCollector { mut items, .. } = collector;
-    weak_lang_items::check_crate(krate, session, &mut items);
+    weak_lang_items::check_crate(tcx, &mut items);
     items
 }
 
@@ -366,7 +342,7 @@ language_item_table! {
 
 impl<'a, 'tcx, 'gcx> ty::TyCtxt<'a, 'tcx, 'gcx> {
     pub fn require_lang_item(&self, lang_item: LangItem) -> DefId {
-        self.lang_items.require(lang_item).unwrap_or_else(|msg| {
+        self.lang_items().require(lang_item).unwrap_or_else(|msg| {
             self.sess.fatal(&msg)
         })
     }
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 3efc696f2a5..33f4d4093fe 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -392,7 +392,7 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) ->
     for (id, _) in &access_levels.map {
         reachable_context.worklist.push(*id);
     }
-    for item in tcx.lang_items.items().iter() {
+    for item in tcx.lang_items().items().iter() {
         if let Some(did) = *item {
             if let Some(node_id) = tcx.hir.as_local_node_id(did) {
                 reachable_context.worklist.push(node_id);
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index acb506878e6..31114f8e302 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -11,7 +11,6 @@
 //! Validity checking for weak lang items
 
 use session::config;
-use session::Session;
 use middle::lang_items;
 
 use rustc_back::PanicStrategy;
@@ -21,38 +20,38 @@ use syntax_pos::Span;
 use hir::intravisit::{Visitor, NestedVisitorMap};
 use hir::intravisit;
 use hir;
+use ty::TyCtxt;
 
 use std::collections::HashSet;
 
 macro_rules! weak_lang_items {
     ($($name:ident, $item:ident, $sym:ident;)*) => (
 
-struct Context<'a> {
-    sess: &'a Session,
+struct Context<'a, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
     items: &'a mut lang_items::LanguageItems,
 }
 
 /// Checks the crate for usage of weak lang items, returning a vector of all the
 /// language items required by this crate, but not defined yet.
-pub fn check_crate(krate: &hir::Crate,
-                   sess: &Session,
-                   items: &mut lang_items::LanguageItems) {
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                             items: &mut lang_items::LanguageItems) {
     // These are never called by user code, they're generated by the compiler.
     // They will never implicitly be added to the `missing` array unless we do
     // so here.
     if items.eh_personality().is_none() {
         items.missing.push(lang_items::EhPersonalityLangItem);
     }
-    if sess.target.target.options.custom_unwind_resume &
+    if tcx.sess.target.target.options.custom_unwind_resume &
        items.eh_unwind_resume().is_none() {
         items.missing.push(lang_items::EhUnwindResumeLangItem);
     }
 
     {
-        let mut cx = Context { sess: sess, items: items };
-        krate.visit_all_item_likes(&mut cx.as_deep_visitor());
+        let mut cx = Context { tcx, items };
+        tcx.hir.krate().visit_all_item_likes(&mut cx.as_deep_visitor());
     }
-    verify(sess, items);
+    verify(tcx, items);
 }
 
 pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
@@ -65,10 +64,11 @@ pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
     })
 }
 
-fn verify(sess: &Session, items: &lang_items::LanguageItems) {
+fn verify<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                    items: &lang_items::LanguageItems) {
     // We only need to check for the presence of weak lang items if we're
     // emitting something that's not an rlib.
-    let needs_check = sess.crate_types.borrow().iter().any(|kind| {
+    let needs_check = tcx.sess.crate_types.borrow().iter().any(|kind| {
         match *kind {
             config::CrateTypeDylib |
             config::CrateTypeProcMacro |
@@ -83,8 +83,8 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
     }
 
     let mut missing = HashSet::new();
-    for cnum in sess.cstore.crates() {
-        for item in sess.cstore.missing_lang_items(cnum) {
+    for cnum in tcx.sess.cstore.crates() {
+        for item in tcx.sess.cstore.missing_lang_items(cnum) {
             missing.insert(item);
         }
     }
@@ -93,7 +93,7 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
     // symbols. Other panic runtimes ensure that the relevant symbols are
     // available to link things together, but they're never exercised.
     let mut whitelisted = HashSet::new();
-    if sess.panic_strategy() != PanicStrategy::Unwind {
+    if tcx.sess.panic_strategy() != PanicStrategy::Unwind {
         whitelisted.insert(lang_items::EhPersonalityLangItem);
         whitelisted.insert(lang_items::EhUnwindResumeLangItem);
     }
@@ -102,28 +102,28 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
         if missing.contains(&lang_items::$item) &&
            !whitelisted.contains(&lang_items::$item) &&
            items.$name().is_none() {
-            sess.err(&format!("language item required, but not found: `{}`",
-                              stringify!($name)));
+            tcx.sess.err(&format!("language item required, but not found: `{}`",
+                                  stringify!($name)));
 
         }
     )*
 }
 
-impl<'a> Context<'a> {
+impl<'a, 'tcx> Context<'a, 'tcx> {
     fn register(&mut self, name: &str, span: Span) {
         $(if name == stringify!($name) {
             if self.items.$name().is_none() {
                 self.items.missing.push(lang_items::$item);
             }
         } else)* {
-            span_err!(self.sess, span, E0264,
+            span_err!(self.tcx.sess, span, E0264,
                       "unknown external lang item: `{}`",
                       name);
         }
     }
 }
 
-impl<'a, 'v> Visitor<'v> for Context<'a> {
+impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
         NestedVisitorMap::None
     }
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index ce6da55fec3..498dc0cf255 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -919,7 +919,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 // anyway. In that case, why inundate the user.
                 if !self.tcx.sess.has_errors() {
                     if
-                        self.tcx.lang_items.sized_trait()
+                        self.tcx.lang_items().sized_trait()
                         .map_or(false, |sized_id| sized_id == trait_ref.def_id())
                     {
                         self.need_type_info(body_id, span, self_ty);
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 9c04c013c4b..fd6d5a86a7f 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -181,7 +181,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 
     fn generics_require_sized_self(self, def_id: DefId) -> bool {
-        let sized_def_id = match self.lang_items.sized_trait() {
+        let sized_def_id = match self.lang_items().sized_trait() {
             Some(def_id) => def_id,
             None => { return false; /* No Sized trait, can't require it! */ }
         };
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 512cfee12b0..1088ada667f 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -1155,7 +1155,7 @@ fn confirm_generator_candidate<'cx, 'gcx, 'tcx>(
 
     let tcx = selcx.tcx();
 
-    let gen_def_id = tcx.lang_items.gen_trait().unwrap();
+    let gen_def_id = tcx.lang_items().gen_trait().unwrap();
 
     // Note: we unwrap the binder here but re-create it below (1)
     let ty::Binder((trait_ref, yield_ty, return_ty)) =
@@ -1252,7 +1252,7 @@ fn confirm_callable_candidate<'cx, 'gcx, 'tcx>(
            fn_sig);
 
     // the `Output` associated type is declared on `FnOnce`
-    let fn_once_def_id = tcx.lang_items.fn_once_trait().unwrap();
+    let fn_once_def_id = tcx.lang_items().fn_once_trait().unwrap();
 
     // Note: we unwrap the binder here but re-create it below (1)
     let ty::Binder((trait_ref, ret_type)) =
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 726e5d83428..201395e6f90 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -1235,7 +1235,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         // and applicable impls. There is a certain set of precedence rules here.
 
         let def_id = obligation.predicate.def_id();
-        if self.tcx().lang_items.copy_trait() == Some(def_id) {
+        let lang_items = self.tcx().lang_items();
+        if lang_items.copy_trait() == Some(def_id) {
             debug!("obligation self ty is {:?}",
                    obligation.predicate.0.self_ty());
 
@@ -1246,16 +1247,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             // For other types, we'll use the builtin rules.
             let copy_conditions = self.copy_conditions(obligation);
             self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates)?;
-        } else if self.tcx().lang_items.sized_trait() == Some(def_id) {
+        } else if lang_items.sized_trait() == Some(def_id) {
             // Sized is never implementable by end-users, it is
             // always automatically computed.
             let sized_conditions = self.sized_conditions(obligation);
             self.assemble_builtin_bound_candidates(sized_conditions,
                                                    &mut candidates)?;
-         } else if self.tcx().lang_items.unsize_trait() == Some(def_id) {
+         } else if lang_items.unsize_trait() == Some(def_id) {
              self.assemble_candidates_for_unsizing(obligation, &mut candidates);
          } else {
-             if self.tcx().lang_items.clone_trait() == Some(def_id) {
+             if lang_items.clone_trait() == Some(def_id) {
                  // Same builtin conditions as `Copy`, i.e. every type which has builtin support
                  // for `Copy` also has builtin support for `Clone`, + tuples and arrays of `Clone`
                  // types have builtin support for `Clone`.
@@ -1453,7 +1454,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                                    candidates: &mut SelectionCandidateSet<'tcx>)
                                    -> Result<(),SelectionError<'tcx>>
     {
-        if self.tcx().lang_items.gen_trait() != Some(obligation.predicate.def_id()) {
+        if self.tcx().lang_items().gen_trait() != Some(obligation.predicate.def_id()) {
             return Ok(());
         }
 
@@ -1490,7 +1491,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                                    candidates: &mut SelectionCandidateSet<'tcx>)
                                    -> Result<(),SelectionError<'tcx>>
     {
-        let kind = match self.tcx().lang_items.fn_trait_kind(obligation.predicate.0.def_id()) {
+        let kind = match self.tcx().lang_items().fn_trait_kind(obligation.predicate.0.def_id()) {
             Some(k) => k,
             None => { return Ok(()); }
         };
@@ -1532,7 +1533,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                                       -> Result<(),SelectionError<'tcx>>
     {
         // We provide impl of all fn traits for fn pointers.
-        if self.tcx().lang_items.fn_trait_kind(obligation.predicate.def_id()).is_none() {
+        if self.tcx().lang_items().fn_trait_kind(obligation.predicate.def_id()).is_none() {
             return Ok(());
         }
 
@@ -2266,16 +2267,17 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         debug!("confirm_builtin_candidate({:?}, {:?})",
                obligation, has_nested);
 
+        let lang_items = self.tcx().lang_items();
         let obligations = if has_nested {
             let trait_def = obligation.predicate.def_id();
             let conditions = match trait_def {
-                _ if Some(trait_def) == self.tcx().lang_items.sized_trait() => {
+                _ if Some(trait_def) == lang_items.sized_trait() => {
                     self.sized_conditions(obligation)
                 }
-                _ if Some(trait_def) == self.tcx().lang_items.copy_trait() => {
+                _ if Some(trait_def) == lang_items.copy_trait() => {
                     self.copy_conditions(obligation)
                 }
-                _ if Some(trait_def) == self.tcx().lang_items.clone_trait() => {
+                _ if Some(trait_def) == lang_items.clone_trait() => {
                     self.copy_conditions(obligation)
                 }
                 _ => bug!("unexpected builtin trait {:?}", trait_def)
@@ -2578,7 +2580,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     {
         debug!("confirm_closure_candidate({:?})", obligation);
 
-        let kind = match self.tcx().lang_items.fn_trait_kind(obligation.predicate.0.def_id()) {
+        let kind = match self.tcx().lang_items().fn_trait_kind(obligation.predicate.0.def_id()) {
             Some(k) => k,
             None => bug!("closure candidate for non-fn trait {:?}", obligation)
         };
diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs
index 51436660779..349d77cfc1b 100644
--- a/src/librustc/ty/adjustment.rs
+++ b/src/librustc/ty/adjustment.rs
@@ -110,8 +110,8 @@ impl<'a, 'gcx, 'tcx> OverloadedDeref<'tcx> {
     pub fn method_call(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, source: Ty<'tcx>)
                        -> (DefId, &'tcx Substs<'tcx>) {
         let trait_def_id = match self.mutbl {
-            hir::MutImmutable => tcx.lang_items.deref_trait(),
-            hir::MutMutable => tcx.lang_items.deref_mut_trait()
+            hir::MutImmutable => tcx.lang_items().deref_trait(),
+            hir::MutMutable => tcx.lang_items().deref_mut_trait()
         };
         let method_def_id = tcx.associated_items(trait_def_id.unwrap())
             .find(|m| m.kind == ty::AssociatedKind::Method).unwrap().def_id;
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index dbd288c6f2d..c40edff8ed7 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -851,8 +851,6 @@ pub struct GlobalCtxt<'tcx> {
 
     pub inhabitedness_cache: RefCell<FxHashMap<Ty<'tcx>, DefIdForest>>,
 
-    pub lang_items: middle::lang_items::LanguageItems,
-
     /// Set of nodes which mark locals as mutable which end up getting used at
     /// some point. Local variable definitions not in this set can be warned
     /// about.
@@ -992,7 +990,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                                   resolutions: ty::Resolutions,
                                   named_region_map: resolve_lifetime::NamedRegionMap,
                                   hir: hir_map::Map<'tcx>,
-                                  lang_items: middle::lang_items::LanguageItems,
                                   stability: stability::Index<'tcx>,
                                   crate_name: &str,
                                   f: F) -> R
@@ -1079,7 +1076,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             rcache: RefCell::new(FxHashMap()),
             normalized_cache: RefCell::new(FxHashMap()),
             inhabitedness_cache: RefCell::new(FxHashMap()),
-            lang_items,
             used_mut_nodes: RefCell::new(NodeSet()),
             stability: RefCell::new(stability),
             selection_cache: traits::SelectionCache::new(),
@@ -1099,6 +1095,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         let cname = self.crate_name(LOCAL_CRATE).as_str();
         self.sess.consider_optimizing(&cname, msg)
     }
+
+    pub fn lang_items(self) -> Rc<middle::lang_items::LanguageItems> {
+        self.get_lang_items(LOCAL_CRATE)
+    }
 }
 
 impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> {
@@ -2004,4 +2004,8 @@ pub fn provide(providers: &mut ty::maps::Providers) {
         assert_eq!(id, LOCAL_CRATE);
         tcx.crate_name
     };
+    providers.get_lang_items = |tcx, id| {
+        assert_eq!(id, LOCAL_CRATE);
+        Rc::new(middle::lang_items::collect(tcx))
+    };
 }
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index cf21a66d515..2348c4ae767 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -1344,7 +1344,7 @@ impl<'a, 'tcx> Layout {
                     } else {
                         let st = Struct::new(dl, &fields, &def.repr,
                           kind, ty)?;
-                        let non_zero = Some(def.did) == tcx.lang_items.non_zero();
+                        let non_zero = Some(def.did) == tcx.lang_items().non_zero();
                         Univariant { variant: st, non_zero: non_zero }
                     };
                     return success(layout);
@@ -2043,7 +2043,7 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
                     if let Some(SizeSkeleton::Pointer { non_zero, tail }) = v0 {
                         return Ok(SizeSkeleton::Pointer {
                             non_zero: non_zero ||
-                                Some(def.did) == tcx.lang_items.non_zero(),
+                                Some(def.did) == tcx.lang_items().non_zero(),
                             tail,
                         });
                     } else {
diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs
index 762b35793de..16364500790 100644
--- a/src/librustc/ty/maps.rs
+++ b/src/librustc/ty/maps.rs
@@ -22,6 +22,7 @@ use middle::privacy::AccessLevels;
 use middle::region;
 use middle::region::RegionMaps;
 use middle::resolve_lifetime::{Region, ObjectLifetimeDefault};
+use middle::lang_items::LanguageItems;
 use mir;
 use mir::transform::{MirSuite, MirPassIndex};
 use session::CompileResult;
@@ -687,6 +688,12 @@ impl<'tcx> QueryDescription for queries::extern_mod_stmt_cnum<'tcx> {
     }
 }
 
+impl<'tcx> QueryDescription for queries::get_lang_items<'tcx> {
+    fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
+        format!("calculating the lang items map")
+    }
+}
+
 // If enabled, send a message to the profile-queries thread
 macro_rules! profq_msg {
     ($tcx:expr, $msg:expr) => {
@@ -1292,6 +1299,8 @@ define_maps! { <'tcx>
     [] crate_name: CrateName(CrateNum) -> Symbol,
     [] item_children: ItemChildren(DefId) -> Rc<Vec<Export>>,
     [] extern_mod_stmt_cnum: ExternModStmtCnum(HirId) -> Option<CrateNum>,
+
+    [] get_lang_items: get_lang_items_node(CrateNum) -> Rc<LanguageItems>,
 }
 
 fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
@@ -1381,3 +1390,7 @@ fn implementations_of_trait_node<'tcx>((krate, trait_id): (CrateNum, DefId))
 fn link_args_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
     DepConstructor::LinkArgs
 }
+
+fn get_lang_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
+    DepConstructor::GetLangItems
+}
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index c58d9814704..ad14a311c54 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1447,10 +1447,10 @@ impl<'a, 'gcx, 'tcx> AdtDef {
         if attr::contains_name(&attrs, "fundamental") {
             flags = flags | AdtFlags::IS_FUNDAMENTAL;
         }
-        if Some(did) == tcx.lang_items.phantom_data() {
+        if Some(did) == tcx.lang_items().phantom_data() {
             flags = flags | AdtFlags::IS_PHANTOM_DATA;
         }
-        if Some(did) == tcx.lang_items.owned_box() {
+        if Some(did) == tcx.lang_items().owned_box() {
             flags = flags | AdtFlags::IS_BOX;
         }
         match kind {
@@ -1746,7 +1746,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
                 // we know that `T` is Sized and do not need to check
                 // it on the impl.
 
-                let sized_trait = match tcx.lang_items.sized_trait() {
+                let sized_trait = match tcx.lang_items().sized_trait() {
                     Some(x) => x,
                     _ => return vec![ty]
                 };
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 4e4c7b107c4..f21fc8414e7 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -418,7 +418,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         adt_did: DefId,
         validate: &mut FnMut(Self, DefId) -> Result<(), ErrorReported>
     ) -> Option<ty::Destructor> {
-        let drop_trait = if let Some(def_id) = self.lang_items.drop_trait() {
+        let drop_trait = if let Some(def_id) = self.lang_items().drop_trait() {
             def_id
         } else {
             return None;
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index cc581b07de5..c48bd5ac5be 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -159,7 +159,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
         }
 
         write!(f, "{}", tcx.item_path_str(path_def_id))?;
-        Ok(tcx.lang_items.fn_trait_kind(path_def_id))
+        Ok(tcx.lang_items().fn_trait_kind(path_def_id))
     })?;
 
     if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
@@ -802,7 +802,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
                     for predicate in bounds.predicates {
                         if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() {
                             // Don't print +Sized, but rather +?Sized if absent.
-                            if Some(trait_ref.def_id()) == tcx.lang_items.sized_trait() {
+                            if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() {
                                 is_sized = true;
                                 continue;
                             }
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 10b591432ee..afd89f70992 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -913,12 +913,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
 
     let time_passes = sess.time_passes();
 
-    let lang_items = time(time_passes, "language item collection", || {
-        sess.track_errors(|| {
-            middle::lang_items::collect_language_items(&sess, &hir_map)
-        })
-    })?;
-
     let named_region_map = time(time_passes,
                                 "lifetime resolution",
                                 || middle::resolve_lifetime::krate(sess, &hir_map))?;
@@ -1028,7 +1022,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
                              resolutions,
                              named_region_map,
                              hir_map,
-                             lang_items,
                              index,
                              name,
                              |tcx| {
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 60d7a4ce87e..e0d82f3dafc 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -547,7 +547,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations {
             _ => return,
         }
 
-        let debug = match cx.tcx.lang_items.debug_trait() {
+        let debug = match cx.tcx.lang_items().debug_trait() {
             Some(debug) => debug,
             None => return,
         };
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 0893842eff0..d3b3396413c 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -991,7 +991,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
                 // "unsized info", else just store None
                 let coerce_unsized_info =
                     trait_ref.and_then(|t| {
-                        if Some(t.def_id) == tcx.lang_items.coerce_unsized_trait() {
+                        if Some(t.def_id) == tcx.lang_items().coerce_unsized_trait() {
                             Some(tcx.at(item.span).coerce_unsized_info(def_id))
                         } else {
                             None
@@ -1322,7 +1322,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
 
     fn encode_lang_items(&mut self, _: ()) -> LazySeq<(DefIndex, usize)> {
         let tcx = self.tcx;
-        let lang_items = tcx.lang_items.items().iter();
+        let lang_items = tcx.lang_items();
+        let lang_items = lang_items.items().iter();
         self.lazy_seq(lang_items.enumerate().filter_map(|(i, &opt_def_id)| {
             if let Some(def_id) = opt_def_id {
                 if def_id.is_local() {
@@ -1335,7 +1336,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
 
     fn encode_lang_items_missing(&mut self, _: ()) -> LazySeq<lang_items::LangItem> {
         let tcx = self.tcx;
-        self.lazy_seq_ref(&tcx.lang_items.missing)
+        self.lazy_seq_ref(&tcx.lang_items().missing)
     }
 
     /// Encodes an index, mapping each trait to its (local) implementations.
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index dc15163ecc1..0b91e08fc6d 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -299,7 +299,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 let fail = self.cfg.start_new_block();
                 if let ty::TyRef(_, mt) = ty.sty {
                     assert!(ty.is_slice());
-                    let eq_def_id = self.hir.tcx().lang_items.eq_trait().unwrap();
+                    let eq_def_id = self.hir.tcx().lang_items().eq_trait().unwrap();
                     let ty = mt.ty;
                     let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty]);
 
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index d3c886dab4e..023bec57b3f 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -47,7 +47,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
             bug!("item {:?} passed to make_shim", instance),
         ty::InstanceDef::FnPtrShim(def_id, ty) => {
             let trait_ = tcx.trait_of_item(def_id).unwrap();
-            let adjustment = match tcx.lang_items.fn_trait_kind(trait_) {
+            let adjustment = match tcx.lang_items().fn_trait_kind(trait_) {
                 Some(ty::ClosureKind::FnOnce) => Adjustment::Identity,
                 Some(ty::ClosureKind::FnMut) |
                 Some(ty::ClosureKind::Fn) => Adjustment::Deref,
@@ -82,7 +82,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
             )
         }
         ty::InstanceDef::ClosureOnceShim { call_once } => {
-            let fn_mut = tcx.lang_items.fn_mut_trait().unwrap();
+            let fn_mut = tcx.lang_items().fn_mut_trait().unwrap();
             let call_mut = tcx.global_tcx()
                 .associated_items(fn_mut)
                 .find(|it| it.kind == ty::AssociatedKind::Method)
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index d1e0465f555..0fb34c96b06 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -715,7 +715,7 @@ impl MirPass for StateTransform {
         let gen_ty = mir.local_decls.raw[1].ty;
 
         // Compute GeneratorState<yield_ty, return_ty>
-        let state_did = tcx.lang_items.gen_state().unwrap();
+        let state_did = tcx.lang_items().gen_state().unwrap();
         let state_adt_ref = tcx.adt_def(state_did);
         let state_substs = tcx.mk_substs([Kind::from(yield_ty),
             Kind::from(mir.return_ty)].iter());
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 3f8070fb3aa..46aa391897a 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -338,7 +338,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
             TerminatorKind::Call { args, destination: Some(destination), cleanup, .. } => {
                 debug!("Inlined {:?} into {:?}", callsite.callee, self.source);
 
-                let is_box_free = Some(callsite.callee) == self.tcx.lang_items.box_free_fn();
+                let is_box_free = Some(callsite.callee) == self.tcx.lang_items().box_free_fn();
 
                 let mut local_map = IndexVec::with_capacity(callee_mir.local_decls.len());
                 let mut scope_map = IndexVec::with_capacity(callee_mir.visibility_scopes.len());
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 415421757c5..3b36ff8ce57 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -252,7 +252,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
     }
 
     fn find_drop_implementation_method_span(&self) -> Option<Span> {
-        self.tcx.lang_items
+        self.tcx.lang_items()
             .drop_trait()
             .and_then(|drop_trait_id| {
                 let mut span = None;
@@ -795,7 +795,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                         self.deny_drop();
                     }
 
-                    if Some(def.did) == self.tcx.lang_items.unsafe_cell_type() {
+                    if Some(def.did) == self.tcx.lang_items().unsafe_cell_type() {
                         let ty = rvalue.ty(self.mir, self.tcx);
                         self.add_type(ty);
                         assert!(self.qualif.intersects(Qualif::MUTABLE_INTERIOR));
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs
index d4da14ea96e..7fbeb9610f4 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -575,7 +575,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                     value: ConstVal::Function(def_id, _), ..
                 }, ..
             }) => {
-                Some(def_id) == self.tcx().lang_items.box_free_fn()
+                Some(def_id) == self.tcx().lang_items().box_free_fn()
             }
             _ => false,
         }
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index f3b121f2eed..8ea47c29910 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -515,7 +515,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
     {
         debug!("destructor_call_block({:?}, {:?})", self, succ);
         let tcx = self.tcx();
-        let drop_trait = tcx.lang_items.drop_trait().unwrap();
+        let drop_trait = tcx.lang_items().drop_trait().unwrap();
         let drop_fn = tcx.associated_items(drop_trait).next().unwrap();
         let ty = self.lvalue_ty(self.lvalue);
         let substs = tcx.mk_substs(iter::once(Kind::from(ty)));
diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs
index b4f4f565191..6f2c448ceb6 100644
--- a/src/librustc_passes/consts.rs
+++ b/src/librustc_passes/consts.rs
@@ -401,7 +401,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
         hir::ExprStruct(..) => {
             if let ty::TyAdt(adt, ..) = v.tables.expr_ty(e).sty {
                 // unsafe_cell_type doesn't necessarily exist with no_core
-                if Some(adt.did) == v.tcx.lang_items.unsafe_cell_type() {
+                if Some(adt.did) == v.tcx.lang_items().unsafe_cell_type() {
                     v.promotable = false;
                 }
             }
diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs
index 8b864a7fdcf..b56fa34e348 100644
--- a/src/librustc_trans/collector.rs
+++ b/src/librustc_trans/collector.rs
@@ -432,7 +432,7 @@ fn check_recursion_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let recursion_depth = recursion_depths.get(&def_id).cloned().unwrap_or(0);
     debug!(" => recursion depth={}", recursion_depth);
 
-    let recursion_depth = if Some(def_id) == tcx.lang_items.drop_in_place_fn() {
+    let recursion_depth = if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
         // HACK: drop_in_place creates tight monomorphization loops. Give
         // it more margin.
         recursion_depth / 4
@@ -550,7 +550,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
             mir::Rvalue::NullaryOp(mir::NullOp::Box, _) => {
                 let tcx = self.scx.tcx();
                 let exchange_malloc_fn_def_id = tcx
-                    .lang_items
+                    .lang_items()
                     .require(ExchangeMallocFnLangItem)
                     .unwrap_or_else(|e| self.scx.sess().fatal(&e));
                 let instance = Instance::mono(tcx, exchange_malloc_fn_def_id);
diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs
index 261792735dc..d947cd8e719 100644
--- a/src/librustc_trans/common.rs
+++ b/src/librustc_trans/common.rs
@@ -423,7 +423,7 @@ pub fn langcall(tcx: TyCtxt,
                 msg: &str,
                 li: LangItem)
                 -> DefId {
-    match tcx.lang_items.require(li) {
+    match tcx.lang_items().require(li) {
         Ok(id) => id,
         Err(s) => {
             let msg = format!("{} {}", msg, s);
@@ -530,7 +530,7 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty);
 
             sig.map_bound(|sig| {
-                let state_did = tcx.lang_items.gen_state().unwrap();
+                let state_did = tcx.lang_items().gen_state().unwrap();
                 let state_adt_ref = tcx.adt_def(state_did);
                 let state_substs = tcx.mk_substs([Kind::from(sig.yield_ty),
                     Kind::from(sig.return_ty)].iter());
diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs
index f2b07cf6a58..a5830eb17ed 100644
--- a/src/librustc_trans/context.rs
+++ b/src/librustc_trans/context.rs
@@ -616,7 +616,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
             return llpersonality
         }
         let tcx = self.tcx();
-        let llfn = match tcx.lang_items.eh_personality() {
+        let llfn = match tcx.lang_items().eh_personality() {
             Some(def_id) if !base::wants_msvc_seh(self.sess()) => {
                 callee::resolve_and_get_fn(self, def_id, tcx.intern_substs(&[]))
             }
@@ -645,7 +645,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
 
         let tcx = self.tcx();
         assert!(self.sess().target.target.options.custom_unwind_resume);
-        if let Some(def_id) = tcx.lang_items.eh_unwind_resume() {
+        if let Some(def_id) = tcx.lang_items().eh_unwind_resume() {
             let llfn = callee::resolve_and_get_fn(self, def_id, tcx.intern_substs(&[]));
             unwresume.set(Some(llfn));
             return llfn;
diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs
index 9a3c8a5079a..53e24191255 100644
--- a/src/librustc_trans/intrinsic.rs
+++ b/src/librustc_trans/intrinsic.rs
@@ -822,7 +822,7 @@ fn trans_msvc_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
         catchswitch.add_handler(cs, catchpad.llbb());
 
         let tcx = ccx.tcx();
-        let tydesc = match tcx.lang_items.msvc_try_filter() {
+        let tydesc = match tcx.lang_items().msvc_try_filter() {
             Some(did) => ::consts::get_static(ccx, did),
             None => bug!("msvc_try_filter not defined"),
         };
diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs
index 95b76d32bf8..949b9fe71ca 100644
--- a/src/librustc_trans/mir/analyze.rs
+++ b/src/librustc_trans/mir/analyze.rs
@@ -114,7 +114,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
                     }, ..
                 }),
                 ref args, ..
-            } if Some(def_id) == self.cx.ccx.tcx().lang_items.box_free_fn() => {
+            } if Some(def_id) == self.cx.ccx.tcx().lang_items().box_free_fn() => {
                 // box_free(x) shares with `drop x` the property that it
                 // is not guaranteed to be statically dominated by the
                 // definition of x, so x must always be in an alloca.
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index 9987c9c3310..e8b1430b4b0 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -610,7 +610,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
                         match operand.ty.sty {
                             ty::TyClosure(def_id, substs) => {
                                 // Get the def_id for FnOnce::call_once
-                                let fn_once = tcx.lang_items.fn_once_trait().unwrap();
+                                let fn_once = tcx.lang_items().fn_once_trait().unwrap();
                                 let call_once = tcx
                                     .global_tcx().associated_items(fn_once)
                                     .find(|it| it.kind == ty::AssociatedKind::Method)
diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs
index 096f43e44ab..34dec57543a 100644
--- a/src/librustc_trans/mir/rvalue.rs
+++ b/src/librustc_trans/mir/rvalue.rs
@@ -482,7 +482,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
                 let box_ty = bcx.tcx().mk_box(content_ty);
 
                 // Allocate space:
-                let def_id = match bcx.tcx().lang_items.require(ExchangeMallocFnLangItem) {
+                let def_id = match bcx.tcx().lang_items().require(ExchangeMallocFnLangItem) {
                     Ok(id) => id,
                     Err(s) => {
                         bcx.sess().fatal(&format!("allocation of `{}` {}", box_ty, s));
diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs
index 4989ca8cc93..9a7f1524d20 100644
--- a/src/librustc_trans/monomorphize.rs
+++ b/src/librustc_trans/monomorphize.rs
@@ -31,7 +31,7 @@ fn fn_once_adapter_instance<'a, 'tcx>(
     debug!("fn_once_adapter_shim({:?}, {:?})",
            closure_did,
            substs);
-    let fn_once = tcx.lang_items.fn_once_trait().unwrap();
+    let fn_once = tcx.lang_items().fn_once_trait().unwrap();
     let call_once = tcx.associated_items(fn_once)
         .find(|it| it.kind == ty::AssociatedKind::Method)
         .unwrap().def_id;
@@ -132,7 +132,7 @@ fn resolve_associated_item<'a, 'tcx>(
             }
         }
         traits::VtableClosure(closure_data) => {
-            let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap();
+            let trait_closure_kind = tcx.lang_items().fn_trait_kind(trait_id).unwrap();
             resolve_closure(scx, closure_data.closure_def_id, closure_data.substs,
                             trait_closure_kind)
         }
@@ -149,7 +149,7 @@ fn resolve_associated_item<'a, 'tcx>(
                 substs: rcvr_substs
             }
         }
-        traits::VtableBuiltin(..) if Some(trait_id) == tcx.lang_items.clone_trait() => {
+        traits::VtableBuiltin(..) if Some(trait_id) == tcx.lang_items().clone_trait() => {
             Instance {
                 def: ty::InstanceDef::CloneShim(def_id, trait_ref.self_ty()),
                 substs: rcvr_substs
@@ -187,7 +187,7 @@ pub fn resolve<'a, 'tcx>(
                 ty::InstanceDef::Intrinsic(def_id)
             }
             _ => {
-                if Some(def_id) == scx.tcx().lang_items.drop_in_place_fn() {
+                if Some(def_id) == scx.tcx().lang_items().drop_in_place_fn() {
                     let ty = substs.type_at(0);
                     if glue::needs_drop_glue(scx, ty) {
                         debug!(" => nontrivial drop glue");
@@ -224,7 +224,7 @@ pub fn custom_coerce_unsize_info<'scx, 'tcx>(scx: &SharedCrateContext<'scx, 'tcx
                                              target_ty: Ty<'tcx>)
                                              -> CustomCoerceUnsized {
     let trait_ref = ty::Binder(ty::TraitRef {
-        def_id: scx.tcx().lang_items.coerce_unsized_trait().unwrap(),
+        def_id: scx.tcx().lang_items().coerce_unsized_trait().unwrap(),
         substs: scx.tcx().mk_substs_trait(source_ty, &[target_ty])
     });
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index f391c2f9279..2583d18652d 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1288,8 +1288,8 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
             Def::Trait(trait_did) => {
                 // Checks whether `trait_did` refers to one of the builtin
                 // traits, like `Send`, and adds it to `auto_traits` if so.
-                if Some(trait_did) == tcx.lang_items.send_trait() ||
-                    Some(trait_did) == tcx.lang_items.sync_trait() {
+                if Some(trait_did) == tcx.lang_items().send_trait() ||
+                    Some(trait_did) == tcx.lang_items().sync_trait() {
                     let segments = &bound.trait_ref.path.segments;
                     let parameters = &segments[segments.len() - 1].parameters;
                     if !parameters.types.is_empty() {
@@ -1402,7 +1402,7 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
 
         // If it could be sized, and is, add the sized predicate
         if self.implicitly_sized {
-            if let Some(sized) = tcx.lang_items.sized_trait() {
+            if let Some(sized) = tcx.lang_items().sized_trait() {
                 let trait_ref = ty::TraitRef {
                     def_id: sized,
                     substs: tcx.mk_substs_trait(param_ty, &[])
diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs
index e0e946a9c63..a25deb7685a 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/src/librustc_typeck/check/autoderef.rs
@@ -108,7 +108,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
 
         // <cur_ty as Deref>
         let trait_ref = TraitRef {
-            def_id: match tcx.lang_items.deref_trait() {
+            def_id: match tcx.lang_items().deref_trait() {
                 Some(f) => f,
                 None => return None,
             },
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 5b9d4af08e0..866949220b5 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -28,7 +28,7 @@ use rustc::hir;
 /// to `trait_id` (this only cares about the trait, not the specific
 /// method that is called)
 pub fn check_legal_trait_for_method_call(tcx: TyCtxt, span: Span, trait_id: DefId) {
-    if tcx.lang_items.drop_trait() == Some(trait_id) {
+    if tcx.lang_items().drop_trait() == Some(trait_id) {
         struct_span_err!(tcx.sess, span, E0040, "explicit use of destructor method")
             .span_label(span, "explicit destructor calls not allowed")
             .emit();
@@ -157,9 +157,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                              MethodCallee<'tcx>)> {
         // Try the options that are least restrictive on the caller first.
         for &(opt_trait_def_id, method_name, borrow) in
-            &[(self.tcx.lang_items.fn_trait(), Symbol::intern("call"), true),
-              (self.tcx.lang_items.fn_mut_trait(), Symbol::intern("call_mut"), true),
-              (self.tcx.lang_items.fn_once_trait(), Symbol::intern("call_once"), false)] {
+            &[(self.tcx.lang_items().fn_trait(), Symbol::intern("call"), true),
+              (self.tcx.lang_items().fn_mut_trait(), Symbol::intern("call_mut"), true),
+              (self.tcx.lang_items().fn_once_trait(), Symbol::intern("call_once"), false)] {
             let trait_def_id = match opt_trait_def_id {
                 Some(def_id) => def_id,
                 None => continue,
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index a768271f3b8..aa2b9c1e038 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -139,7 +139,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     })
                     .next();
                 let kind = object_type.principal()
-                    .and_then(|p| self.tcx.lang_items.fn_trait_kind(p.def_id()));
+                    .and_then(|p| self.tcx.lang_items().fn_trait_kind(p.def_id()));
                 (sig, kind)
             }
             ty::TyInfer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
@@ -204,7 +204,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     ty::Predicate::ClosureKind(..) => None,
                 };
                 opt_trait_ref.and_then(|tr| self.self_type_matches_expected_vid(tr, expected_vid))
-                    .and_then(|tr| self.tcx.lang_items.fn_trait_kind(tr.def_id()))
+                    .and_then(|tr| self.tcx.lang_items().fn_trait_kind(tr.def_id()))
             })
             .fold(None,
                   |best, cur| Some(best.map_or(cur, |best| cmp::min(best, cur))));
@@ -223,7 +223,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
         let trait_ref = projection.to_poly_trait_ref(tcx);
 
-        if tcx.lang_items.fn_trait_kind(trait_ref.def_id()).is_none() {
+        if tcx.lang_items().fn_trait_kind(trait_ref.def_id()).is_none() {
             return None;
         }
 
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index e406ce845a6..cfcdbcc1195 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -438,8 +438,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
     fn coerce_unsized(&self, source: Ty<'tcx>, target: Ty<'tcx>) -> CoerceResult<'tcx> {
         debug!("coerce_unsized(source={:?}, target={:?})", source, target);
 
-        let traits = (self.tcx.lang_items.unsize_trait(),
-                      self.tcx.lang_items.coerce_unsized_trait());
+        let traits = (self.tcx.lang_items().unsize_trait(),
+                      self.tcx.lang_items().coerce_unsized_trait());
         let (unsize_did, coerce_unsized_did) = if let (Some(u), Some(cu)) = traits {
             (u, cu)
         } else {
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 08ec3bf74a7..852134bbee3 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -540,7 +540,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
     fn predicates_require_illegal_sized_bound(&self,
                                               predicates: &ty::InstantiatedPredicates<'tcx>)
                                               -> bool {
-        let sized_def_id = match self.tcx.lang_items.sized_trait() {
+        let sized_def_id = match self.tcx.lang_items().sized_trait() {
             Some(def_id) => def_id,
             None => return false,
         };
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index ba74c902f55..3771d330f6d 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -393,6 +393,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
 
     fn assemble_probe(&mut self, self_ty: Ty<'tcx>) {
         debug!("assemble_probe: self_ty={:?}", self_ty);
+        let lang_items = self.tcx.lang_items();
 
         match self_ty.sty {
             ty::TyDynamic(ref data, ..) => {
@@ -408,79 +409,79 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
                 self.assemble_inherent_candidates_from_param(self_ty, p);
             }
             ty::TyChar => {
-                let lang_def_id = self.tcx.lang_items.char_impl();
+                let lang_def_id = lang_items.char_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyStr => {
-                let lang_def_id = self.tcx.lang_items.str_impl();
+                let lang_def_id = lang_items.str_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TySlice(_) => {
-                let lang_def_id = self.tcx.lang_items.slice_impl();
+                let lang_def_id = lang_items.slice_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
-                let lang_def_id = self.tcx.lang_items.const_ptr_impl();
+                let lang_def_id = lang_items.const_ptr_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => {
-                let lang_def_id = self.tcx.lang_items.mut_ptr_impl();
+                let lang_def_id = lang_items.mut_ptr_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyInt(ast::IntTy::I8) => {
-                let lang_def_id = self.tcx.lang_items.i8_impl();
+                let lang_def_id = lang_items.i8_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyInt(ast::IntTy::I16) => {
-                let lang_def_id = self.tcx.lang_items.i16_impl();
+                let lang_def_id = lang_items.i16_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyInt(ast::IntTy::I32) => {
-                let lang_def_id = self.tcx.lang_items.i32_impl();
+                let lang_def_id = lang_items.i32_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyInt(ast::IntTy::I64) => {
-                let lang_def_id = self.tcx.lang_items.i64_impl();
+                let lang_def_id = lang_items.i64_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyInt(ast::IntTy::I128) => {
-                let lang_def_id = self.tcx.lang_items.i128_impl();
+                let lang_def_id = lang_items.i128_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyInt(ast::IntTy::Is) => {
-                let lang_def_id = self.tcx.lang_items.isize_impl();
+                let lang_def_id = lang_items.isize_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyUint(ast::UintTy::U8) => {
-                let lang_def_id = self.tcx.lang_items.u8_impl();
+                let lang_def_id = lang_items.u8_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyUint(ast::UintTy::U16) => {
-                let lang_def_id = self.tcx.lang_items.u16_impl();
+                let lang_def_id = lang_items.u16_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyUint(ast::UintTy::U32) => {
-                let lang_def_id = self.tcx.lang_items.u32_impl();
+                let lang_def_id = lang_items.u32_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyUint(ast::UintTy::U64) => {
-                let lang_def_id = self.tcx.lang_items.u64_impl();
+                let lang_def_id = lang_items.u64_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyUint(ast::UintTy::U128) => {
-                let lang_def_id = self.tcx.lang_items.u128_impl();
+                let lang_def_id = lang_items.u128_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyUint(ast::UintTy::Us) => {
-                let lang_def_id = self.tcx.lang_items.usize_impl();
+                let lang_def_id = lang_items.usize_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyFloat(ast::FloatTy::F32) => {
-                let lang_def_id = self.tcx.lang_items.f32_impl();
+                let lang_def_id = lang_items.f32_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             ty::TyFloat(ast::FloatTy::F64) => {
-                let lang_def_id = self.tcx.lang_items.f64_impl();
+                let lang_def_id = lang_items.f64_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
             _ => {}
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 5c8f237b2a7..5b327566a13 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -45,7 +45,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             ty::TyFnPtr(_) => true,
             // If it's not a simple function, look for things which implement FnOnce
             _ => {
-                let fn_once = match tcx.lang_items.require(FnOnceTraitLangItem) {
+                let fn_once = match tcx.lang_items().require(FnOnceTraitLangItem) {
                     Ok(fn_once) => fn_once,
                     Err(..) => return false,
                 };
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 3f210ea1737..0a8d2129a89 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2296,13 +2296,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     fn resolve_lvalue_op(&self, op: LvalueOp, is_mut: bool) -> (Option<DefId>, Symbol) {
         let (tr, name) = match (op, is_mut) {
             (LvalueOp::Deref, false) =>
-                (self.tcx.lang_items.deref_trait(), "deref"),
+                (self.tcx.lang_items().deref_trait(), "deref"),
             (LvalueOp::Deref, true) =>
-                (self.tcx.lang_items.deref_mut_trait(), "deref_mut"),
+                (self.tcx.lang_items().deref_mut_trait(), "deref_mut"),
             (LvalueOp::Index, false) =>
-                (self.tcx.lang_items.index_trait(), "index"),
+                (self.tcx.lang_items().index_trait(), "index"),
             (LvalueOp::Index, true) =>
-                (self.tcx.lang_items.index_mut_trait(), "index_mut"),
+                (self.tcx.lang_items().index_mut_trait(), "index_mut"),
         };
         (tr, Symbol::intern(name))
     }
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index a4e1fdaf39e..a3dd81fddde 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -362,7 +362,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     fn lookup_op_method(&self, lhs_ty: Ty<'tcx>, other_tys: &[Ty<'tcx>], op: Op)
                         -> Result<MethodCallee<'tcx>, ()>
     {
-        let lang = &self.tcx.lang_items;
+        let lang = self.tcx.lang_items();
 
         let span = match op {
             Op::Binary(op, _) => op.span,
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 69f045ab4e9..9c19aef5992 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -539,7 +539,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
     {
         let mut err = error_392(self.tcx, span, param_name);
 
-        let suggested_marker_id = self.tcx.lang_items.phantom_data();
+        let suggested_marker_id = self.tcx.lang_items().phantom_data();
         match suggested_marker_id {
             Some(def_id) => {
                 err.help(
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index b421fdfe8d8..fedfa51d61d 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -28,9 +28,9 @@ use rustc::hir::{self, ItemImpl};
 
 pub fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_def_id: DefId) {
     Checker { tcx, trait_def_id }
-        .check(tcx.lang_items.drop_trait(), visit_implementation_of_drop)
-        .check(tcx.lang_items.copy_trait(), visit_implementation_of_copy)
-        .check(tcx.lang_items.coerce_unsized_trait(),
+        .check(tcx.lang_items().drop_trait(), visit_implementation_of_drop)
+        .check(tcx.lang_items().copy_trait(), visit_implementation_of_copy)
+        .check(tcx.lang_items().coerce_unsized_trait(),
                visit_implementation_of_coerce_unsized);
 }
 
@@ -176,9 +176,9 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      impl_did: DefId)
                                      -> CoerceUnsizedInfo {
     debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did);
-    let coerce_unsized_trait = tcx.lang_items.coerce_unsized_trait().unwrap();
+    let coerce_unsized_trait = tcx.lang_items().coerce_unsized_trait().unwrap();
 
-    let unsize_trait = match tcx.lang_items.require(UnsizeTraitLangItem) {
+    let unsize_trait = match tcx.lang_items().require(UnsizeTraitLangItem) {
         Ok(id) => id,
         Err(err) => {
             tcx.sess.fatal(&format!("`CoerceUnsized` implementation {}", err));
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
index e24d7660021..15e15abfb36 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/src/librustc_typeck/coherence/inherent_impls.rs
@@ -112,6 +112,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
 
         let def_id = self.tcx.hir.local_def_id(item.id);
         let self_ty = self.tcx.type_of(def_id);
+        let lang_items = self.tcx.lang_items();
         match self_ty.sty {
             ty::TyAdt(def, _) => {
                 self.check_def_id(item, def.did);
@@ -121,133 +122,133 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
             }
             ty::TyChar => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.char_impl(),
+                                          lang_items.char_impl(),
                                           "char",
                                           "char",
                                           item.span);
             }
             ty::TyStr => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.str_impl(),
+                                          lang_items.str_impl(),
                                           "str",
                                           "str",
                                           item.span);
             }
             ty::TySlice(_) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.slice_impl(),
+                                          lang_items.slice_impl(),
                                           "slice",
                                           "[T]",
                                           item.span);
             }
             ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.const_ptr_impl(),
+                                          lang_items.const_ptr_impl(),
                                           "const_ptr",
                                           "*const T",
                                           item.span);
             }
             ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.mut_ptr_impl(),
+                                          lang_items.mut_ptr_impl(),
                                           "mut_ptr",
                                           "*mut T",
                                           item.span);
             }
             ty::TyInt(ast::IntTy::I8) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.i8_impl(),
+                                          lang_items.i8_impl(),
                                           "i8",
                                           "i8",
                                           item.span);
             }
             ty::TyInt(ast::IntTy::I16) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.i16_impl(),
+                                          lang_items.i16_impl(),
                                           "i16",
                                           "i16",
                                           item.span);
             }
             ty::TyInt(ast::IntTy::I32) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.i32_impl(),
+                                          lang_items.i32_impl(),
                                           "i32",
                                           "i32",
                                           item.span);
             }
             ty::TyInt(ast::IntTy::I64) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.i64_impl(),
+                                          lang_items.i64_impl(),
                                           "i64",
                                           "i64",
                                           item.span);
             }
             ty::TyInt(ast::IntTy::I128) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.i128_impl(),
+                                          lang_items.i128_impl(),
                                           "i128",
                                           "i128",
                                           item.span);
             }
             ty::TyInt(ast::IntTy::Is) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.isize_impl(),
+                                          lang_items.isize_impl(),
                                           "isize",
                                           "isize",
                                           item.span);
             }
             ty::TyUint(ast::UintTy::U8) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.u8_impl(),
+                                          lang_items.u8_impl(),
                                           "u8",
                                           "u8",
                                           item.span);
             }
             ty::TyUint(ast::UintTy::U16) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.u16_impl(),
+                                          lang_items.u16_impl(),
                                           "u16",
                                           "u16",
                                           item.span);
             }
             ty::TyUint(ast::UintTy::U32) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.u32_impl(),
+                                          lang_items.u32_impl(),
                                           "u32",
                                           "u32",
                                           item.span);
             }
             ty::TyUint(ast::UintTy::U64) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.u64_impl(),
+                                          lang_items.u64_impl(),
                                           "u64",
                                           "u64",
                                           item.span);
             }
             ty::TyUint(ast::UintTy::U128) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.u128_impl(),
+                                          lang_items.u128_impl(),
                                           "u128",
                                           "u128",
                                           item.span);
             }
             ty::TyUint(ast::UintTy::Us) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.usize_impl(),
+                                          lang_items.usize_impl(),
                                           "usize",
                                           "usize",
                                           item.span);
             }
             ty::TyFloat(ast::FloatTy::F32) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.f32_impl(),
+                                          lang_items.f32_impl(),
                                           "f32",
                                           "f32",
                                           item.span);
             }
             ty::TyFloat(ast::FloatTy::F64) => {
                 self.check_primitive_impl(def_id,
-                                          self.tcx.lang_items.f64_impl(),
+                                          lang_items.f64_impl(),
                                           "f64",
                                           "f64",
                                           item.span);
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 165be49f760..6109fc57b0d 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -51,7 +51,7 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
 
 fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_def_id: DefId) {
     let did = Some(trait_def_id);
-    let li = &tcx.lang_items;
+    let li = tcx.lang_items();
 
     // Disallow *all* explicit impls of `Sized` and `Unsize` for now.
     if did == li.sized_trait() {
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 38b72677bc6..e4ca0f82ea1 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1309,7 +1309,7 @@ fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
         }
     }
 
-    let kind_id = tcx.lang_items.require(SizedTraitLangItem);
+    let kind_id = tcx.lang_items().require(SizedTraitLangItem);
     match unbound {
         Some(ref tpb) => {
             // FIXME(#8559) currently requires the unbound to be built-in.
diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs
index c624b11c5ec..6062ac96ada 100644
--- a/src/librustc_typeck/variance/terms.rs
+++ b/src/librustc_typeck/variance/terms.rs
@@ -94,17 +94,18 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>
 }
 
 fn lang_items(tcx: TyCtxt) -> Vec<(ast::NodeId, Vec<ty::Variance>)> {
+    let lang_items = tcx.lang_items();
     let all = vec![
-        (tcx.lang_items.phantom_data(), vec![ty::Covariant]),
-        (tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant]),
+        (lang_items.phantom_data(), vec![ty::Covariant]),
+        (lang_items.unsafe_cell_type(), vec![ty::Invariant]),
 
         // Deprecated:
-        (tcx.lang_items.covariant_type(), vec![ty::Covariant]),
-        (tcx.lang_items.contravariant_type(), vec![ty::Contravariant]),
-        (tcx.lang_items.invariant_type(), vec![ty::Invariant]),
-        (tcx.lang_items.covariant_lifetime(), vec![ty::Covariant]),
-        (tcx.lang_items.contravariant_lifetime(), vec![ty::Contravariant]),
-        (tcx.lang_items.invariant_lifetime(), vec![ty::Invariant]),
+        (lang_items.covariant_type(), vec![ty::Covariant]),
+        (lang_items.contravariant_type(), vec![ty::Contravariant]),
+        (lang_items.invariant_type(), vec![ty::Invariant]),
+        (lang_items.covariant_lifetime(), vec![ty::Covariant]),
+        (lang_items.contravariant_lifetime(), vec![ty::Contravariant]),
+        (lang_items.invariant_lifetime(), vec![ty::Invariant]),
 
         ];