Skip to content

Commit a2e2aba

Browse files
committed
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.
1 parent 43ae380 commit a2e2aba

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+207
-214
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ define_dep_nodes!( <'tcx>
560560
[] CrateName(CrateNum),
561561
[] ItemChildren(DefId),
562562
[] ExternModStmtCnum(HirId),
563+
[] GetLangItems,
563564
);
564565

565566
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {

src/librustc/middle/dead.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
469469
fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool {
470470
let field_type = self.tcx.type_of(self.tcx.hir.local_def_id(field.id));
471471
let is_marker_field = match field_type.ty_to_def_id() {
472-
Some(def_id) => self.tcx.lang_items.items().iter().any(|item| *item == Some(def_id)),
472+
Some(def_id) => self.tcx.lang_items().items().iter().any(|item| *item == Some(def_id)),
473473
_ => false
474474
};
475475
!field.is_positional()

src/librustc/middle/expr_use_visitor.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,9 @@ enum OverloadedCallType {
211211
impl OverloadedCallType {
212212
fn from_trait_id(tcx: TyCtxt, trait_id: DefId) -> OverloadedCallType {
213213
for &(maybe_function_trait, overloaded_call_type) in &[
214-
(tcx.lang_items.fn_once_trait(), FnOnceOverloadedCall),
215-
(tcx.lang_items.fn_mut_trait(), FnMutOverloadedCall),
216-
(tcx.lang_items.fn_trait(), FnOverloadedCall)
214+
(tcx.lang_items().fn_once_trait(), FnOnceOverloadedCall),
215+
(tcx.lang_items().fn_mut_trait(), FnMutOverloadedCall),
216+
(tcx.lang_items().fn_trait(), FnOverloadedCall)
217217
] {
218218
match maybe_function_trait {
219219
Some(function_trait) if function_trait == trait_id => {

src/librustc/middle/lang_items.rs

Lines changed: 26 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@
2121

2222
pub use self::LangItem::*;
2323

24-
use hir::map as hir_map;
25-
use session::Session;
2624
use hir::def_id::DefId;
27-
use ty;
25+
use ty::{self, TyCtxt};
2826
use middle::weak_lang_items;
2927
use util::nodemap::FxHashMap;
3028

@@ -116,9 +114,7 @@ impl LanguageItems {
116114
struct LanguageItemCollector<'a, 'tcx: 'a> {
117115
items: LanguageItems,
118116

119-
hir_map: &'a hir_map::Map<'tcx>,
120-
121-
session: &'a Session,
117+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
122118

123119
item_refs: FxHashMap<&'static str, usize>,
124120
}
@@ -129,10 +125,11 @@ impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> {
129125
let item_index = self.item_refs.get(&*value.as_str()).cloned();
130126

131127
if let Some(item_index) = item_index {
132-
self.collect_item(item_index, self.hir_map.local_def_id(item.id))
128+
let def_id = self.tcx.hir.local_def_id(item.id);
129+
self.collect_item(item_index, def_id);
133130
} else {
134-
let span = self.hir_map.span(item.id);
135-
span_err!(self.session, span, E0522,
131+
let span = self.tcx.hir.span(item.id);
132+
span_err!(self.tcx.sess, span, E0522,
136133
"definition of an unknown language item: `{}`.",
137134
value);
138135
}
@@ -149,45 +146,41 @@ impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> {
149146
}
150147

151148
impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
152-
pub fn new(session: &'a Session, hir_map: &'a hir_map::Map<'tcx>)
153-
-> LanguageItemCollector<'a, 'tcx> {
149+
fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItemCollector<'a, 'tcx> {
154150
let mut item_refs = FxHashMap();
155151

156152
$( item_refs.insert($name, $variant as usize); )*
157153

158154
LanguageItemCollector {
159-
session,
160-
hir_map,
155+
tcx,
161156
items: LanguageItems::new(),
162157
item_refs,
163158
}
164159
}
165160

166-
pub fn collect_item(&mut self, item_index: usize,
167-
item_def_id: DefId) {
161+
fn collect_item(&mut self, item_index: usize, item_def_id: DefId) {
168162
// Check for duplicates.
169163
match self.items.items[item_index] {
170164
Some(original_def_id) if original_def_id != item_def_id => {
171-
let cstore = &self.session.cstore;
172165
let name = LanguageItems::item_name(item_index);
173-
let mut err = match self.hir_map.span_if_local(item_def_id) {
166+
let mut err = match self.tcx.hir.span_if_local(item_def_id) {
174167
Some(span) => struct_span_err!(
175-
self.session,
168+
self.tcx.sess,
176169
span,
177170
E0152,
178171
"duplicate lang item found: `{}`.",
179172
name),
180-
None => self.session.struct_err(&format!(
173+
None => self.tcx.sess.struct_err(&format!(
181174
"duplicate lang item in crate `{}`: `{}`.",
182-
cstore.crate_name_untracked(item_def_id.krate),
175+
self.tcx.crate_name(item_def_id.krate),
183176
name)),
184177
};
185-
if let Some(span) = self.hir_map.span_if_local(original_def_id) {
178+
if let Some(span) = self.tcx.hir.span_if_local(original_def_id) {
186179
span_note!(&mut err, span,
187180
"first defined here.");
188181
} else {
189182
err.note(&format!("first defined in crate `{}`.",
190-
cstore.crate_name_untracked(original_def_id.krate)));
183+
self.tcx.crate_name(original_def_id.krate)));
191184
}
192185
err.emit();
193186
}
@@ -199,26 +192,6 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
199192
// Matched.
200193
self.items.items[item_index] = Some(item_def_id);
201194
}
202-
203-
pub fn collect_local_language_items(&mut self, krate: &hir::Crate) {
204-
krate.visit_all_item_likes(self);
205-
}
206-
207-
pub fn collect_external_language_items(&mut self) {
208-
let cstore = &self.session.cstore;
209-
210-
for cnum in cstore.crates() {
211-
for (index, item_index) in cstore.lang_items(cnum) {
212-
let def_id = DefId { krate: cnum, index: index };
213-
self.collect_item(item_index, def_id);
214-
}
215-
}
216-
}
217-
218-
pub fn collect(&mut self, krate: &hir::Crate) {
219-
self.collect_external_language_items();
220-
self.collect_local_language_items(krate);
221-
}
222195
}
223196

224197
pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
@@ -233,14 +206,17 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
233206
return None;
234207
}
235208

236-
pub fn collect_language_items(session: &Session,
237-
map: &hir_map::Map)
238-
-> LanguageItems {
239-
let krate: &hir::Crate = map.krate();
240-
let mut collector = LanguageItemCollector::new(session, map);
241-
collector.collect(krate);
209+
pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems {
210+
let mut collector = LanguageItemCollector::new(tcx);
211+
for cnum in tcx.sess.cstore.crates() {
212+
for (index, item_index) in tcx.sess.cstore.lang_items(cnum) {
213+
let def_id = DefId { krate: cnum, index: index };
214+
collector.collect_item(item_index, def_id);
215+
}
216+
}
217+
tcx.hir.krate().visit_all_item_likes(&mut collector);
242218
let LanguageItemCollector { mut items, .. } = collector;
243-
weak_lang_items::check_crate(krate, session, &mut items);
219+
weak_lang_items::check_crate(tcx, &mut items);
244220
items
245221
}
246222

@@ -366,7 +342,7 @@ language_item_table! {
366342

367343
impl<'a, 'tcx, 'gcx> ty::TyCtxt<'a, 'tcx, 'gcx> {
368344
pub fn require_lang_item(&self, lang_item: LangItem) -> DefId {
369-
self.lang_items.require(lang_item).unwrap_or_else(|msg| {
345+
self.lang_items().require(lang_item).unwrap_or_else(|msg| {
370346
self.sess.fatal(&msg)
371347
})
372348
}

src/librustc/middle/reachable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) ->
392392
for (id, _) in &access_levels.map {
393393
reachable_context.worklist.push(*id);
394394
}
395-
for item in tcx.lang_items.items().iter() {
395+
for item in tcx.lang_items().items().iter() {
396396
if let Some(did) = *item {
397397
if let Some(node_id) = tcx.hir.as_local_node_id(did) {
398398
reachable_context.worklist.push(node_id);

src/librustc/middle/weak_lang_items.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//! Validity checking for weak lang items
1212
1313
use session::config;
14-
use session::Session;
1514
use middle::lang_items;
1615

1716
use rustc_back::PanicStrategy;
@@ -21,38 +20,38 @@ use syntax_pos::Span;
2120
use hir::intravisit::{Visitor, NestedVisitorMap};
2221
use hir::intravisit;
2322
use hir;
23+
use ty::TyCtxt;
2424

2525
use std::collections::HashSet;
2626

2727
macro_rules! weak_lang_items {
2828
($($name:ident, $item:ident, $sym:ident;)*) => (
2929

30-
struct Context<'a> {
31-
sess: &'a Session,
30+
struct Context<'a, 'tcx: 'a> {
31+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
3232
items: &'a mut lang_items::LanguageItems,
3333
}
3434

3535
/// Checks the crate for usage of weak lang items, returning a vector of all the
3636
/// language items required by this crate, but not defined yet.
37-
pub fn check_crate(krate: &hir::Crate,
38-
sess: &Session,
39-
items: &mut lang_items::LanguageItems) {
37+
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
38+
items: &mut lang_items::LanguageItems) {
4039
// These are never called by user code, they're generated by the compiler.
4140
// They will never implicitly be added to the `missing` array unless we do
4241
// so here.
4342
if items.eh_personality().is_none() {
4443
items.missing.push(lang_items::EhPersonalityLangItem);
4544
}
46-
if sess.target.target.options.custom_unwind_resume &
45+
if tcx.sess.target.target.options.custom_unwind_resume &
4746
items.eh_unwind_resume().is_none() {
4847
items.missing.push(lang_items::EhUnwindResumeLangItem);
4948
}
5049

5150
{
52-
let mut cx = Context { sess: sess, items: items };
53-
krate.visit_all_item_likes(&mut cx.as_deep_visitor());
51+
let mut cx = Context { tcx, items };
52+
tcx.hir.krate().visit_all_item_likes(&mut cx.as_deep_visitor());
5453
}
55-
verify(sess, items);
54+
verify(tcx, items);
5655
}
5756

5857
pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
@@ -65,10 +64,11 @@ pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
6564
})
6665
}
6766

68-
fn verify(sess: &Session, items: &lang_items::LanguageItems) {
67+
fn verify<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
68+
items: &lang_items::LanguageItems) {
6969
// We only need to check for the presence of weak lang items if we're
7070
// emitting something that's not an rlib.
71-
let needs_check = sess.crate_types.borrow().iter().any(|kind| {
71+
let needs_check = tcx.sess.crate_types.borrow().iter().any(|kind| {
7272
match *kind {
7373
config::CrateTypeDylib |
7474
config::CrateTypeProcMacro |
@@ -83,8 +83,8 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
8383
}
8484

8585
let mut missing = HashSet::new();
86-
for cnum in sess.cstore.crates() {
87-
for item in sess.cstore.missing_lang_items(cnum) {
86+
for cnum in tcx.sess.cstore.crates() {
87+
for item in tcx.sess.cstore.missing_lang_items(cnum) {
8888
missing.insert(item);
8989
}
9090
}
@@ -93,7 +93,7 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
9393
// symbols. Other panic runtimes ensure that the relevant symbols are
9494
// available to link things together, but they're never exercised.
9595
let mut whitelisted = HashSet::new();
96-
if sess.panic_strategy() != PanicStrategy::Unwind {
96+
if tcx.sess.panic_strategy() != PanicStrategy::Unwind {
9797
whitelisted.insert(lang_items::EhPersonalityLangItem);
9898
whitelisted.insert(lang_items::EhUnwindResumeLangItem);
9999
}
@@ -102,28 +102,28 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
102102
if missing.contains(&lang_items::$item) &&
103103
!whitelisted.contains(&lang_items::$item) &&
104104
items.$name().is_none() {
105-
sess.err(&format!("language item required, but not found: `{}`",
106-
stringify!($name)));
105+
tcx.sess.err(&format!("language item required, but not found: `{}`",
106+
stringify!($name)));
107107

108108
}
109109
)*
110110
}
111111

112-
impl<'a> Context<'a> {
112+
impl<'a, 'tcx> Context<'a, 'tcx> {
113113
fn register(&mut self, name: &str, span: Span) {
114114
$(if name == stringify!($name) {
115115
if self.items.$name().is_none() {
116116
self.items.missing.push(lang_items::$item);
117117
}
118118
} else)* {
119-
span_err!(self.sess, span, E0264,
119+
span_err!(self.tcx.sess, span, E0264,
120120
"unknown external lang item: `{}`",
121121
name);
122122
}
123123
}
124124
}
125125

126-
impl<'a, 'v> Visitor<'v> for Context<'a> {
126+
impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
127127
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
128128
NestedVisitorMap::None
129129
}

src/librustc/traits/error_reporting.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
919919
// anyway. In that case, why inundate the user.
920920
if !self.tcx.sess.has_errors() {
921921
if
922-
self.tcx.lang_items.sized_trait()
922+
self.tcx.lang_items().sized_trait()
923923
.map_or(false, |sized_id| sized_id == trait_ref.def_id())
924924
{
925925
self.need_type_info(body_id, span, self_ty);

src/librustc/traits/object_safety.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
181181
}
182182

183183
fn generics_require_sized_self(self, def_id: DefId) -> bool {
184-
let sized_def_id = match self.lang_items.sized_trait() {
184+
let sized_def_id = match self.lang_items().sized_trait() {
185185
Some(def_id) => def_id,
186186
None => { return false; /* No Sized trait, can't require it! */ }
187187
};

src/librustc/traits/project.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,7 @@ fn confirm_generator_candidate<'cx, 'gcx, 'tcx>(
11551155

11561156
let tcx = selcx.tcx();
11571157

1158-
let gen_def_id = tcx.lang_items.gen_trait().unwrap();
1158+
let gen_def_id = tcx.lang_items().gen_trait().unwrap();
11591159

11601160
// Note: we unwrap the binder here but re-create it below (1)
11611161
let ty::Binder((trait_ref, yield_ty, return_ty)) =
@@ -1252,7 +1252,7 @@ fn confirm_callable_candidate<'cx, 'gcx, 'tcx>(
12521252
fn_sig);
12531253

12541254
// the `Output` associated type is declared on `FnOnce`
1255-
let fn_once_def_id = tcx.lang_items.fn_once_trait().unwrap();
1255+
let fn_once_def_id = tcx.lang_items().fn_once_trait().unwrap();
12561256

12571257
// Note: we unwrap the binder here but re-create it below (1)
12581258
let ty::Binder((trait_ref, ret_type)) =

0 commit comments

Comments
 (0)