about summary refs log tree commit diff
path: root/src/librustc/middle
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 /src/librustc/middle
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.
Diffstat (limited to 'src/librustc/middle')
-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
5 files changed, 51 insertions, 75 deletions
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
     }