Auto merge of #44142 - alexcrichton:dllimport-query, r=nikomatsakis

Migrate a slew of metadata methods to queries

This PR intends to make more progress on #41417, knocking off some low-hanging fruit.

Closes #44190
cc #44137
This commit is contained in:
bors 2017-09-08 09:47:58 +00:00
commit dead08cb33
114 changed files with 1857 additions and 1463 deletions

View File

@ -511,8 +511,8 @@ define_dep_nodes!( <'tcx>
[] ParamEnv(DefId),
[] DescribeDef(DefId),
[] DefSpan(DefId),
[] Stability(DefId),
[] Deprecation(DefId),
[] LookupStability(DefId),
[] LookupDeprecationEntry(DefId),
[] ItemBodyNestedBodies(DefId),
[] ConstIsRvaluePromotableToStatic(DefId),
[] ImplParent(DefId),
@ -521,16 +521,60 @@ define_dep_nodes!( <'tcx>
[] IsMirAvailable(DefId),
[] ItemAttrs(DefId),
[] FnArgNames(DefId),
[] DylibDepFormats(DefId),
[] IsAllocator(DefId),
[] IsPanicRuntime(DefId),
[] IsCompilerBuiltins(DefId),
[] HasGlobalAllocator(DefId),
[] DylibDepFormats(CrateNum),
[] IsPanicRuntime(CrateNum),
[] IsCompilerBuiltins(CrateNum),
[] HasGlobalAllocator(CrateNum),
[] ExternCrate(DefId),
[] LintLevels,
[] Specializes { impl1: DefId, impl2: DefId },
[] InScopeTraits(HirId),
[] ModuleExports(HirId),
[] IsSanitizerRuntime(CrateNum),
[] IsProfilerRuntime(CrateNum),
[] GetPanicStrategy(CrateNum),
[] IsNoBuiltins(CrateNum),
[] ImplDefaultness(DefId),
[] ExportedSymbols(CrateNum),
[] NativeLibraries(CrateNum),
[] PluginRegistrarFn(CrateNum),
[] DeriveRegistrarFn(CrateNum),
[] CrateDisambiguator(CrateNum),
[] CrateHash(CrateNum),
[] OriginalCrateName(CrateNum),
[] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId },
[] AllTraitImplementations(CrateNum),
[] IsDllimportForeignItem(DefId),
[] IsStaticallyIncludedForeignItem(DefId),
[] NativeLibraryKind(DefId),
[] LinkArgs,
[] NamedRegion(HirId),
[] IsLateBound(HirId),
[] ObjectLifetimeDefaults(HirId),
[] Visibility(DefId),
[] DepKind(CrateNum),
[] CrateName(CrateNum),
[] ItemChildren(DefId),
[] ExternModStmtCnum(HirId),
[] GetLangItems,
[] DefinedLangItems(CrateNum),
[] MissingLangItems(CrateNum),
[] ExternConstBody(DefId),
[] VisibleParentMap,
[] IsDirectExternCrate(CrateNum),
[] MissingExternCrateItem(CrateNum),
[] UsedCrateSource(CrateNum),
[] PostorderCnums,
[] Freevars(HirId),
[] MaybeUnusedTraitImport(HirId),
[] MaybeUnusedExternCrates,
[] StabilityIndex,
[] AllCrateNums,
);
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {

View File

@ -235,10 +235,13 @@ impl DepGraph {
debug_str_gen: F)
where F: FnOnce() -> String
{
let mut dep_node_debug = self.data.as_ref().unwrap().dep_node_debug.borrow_mut();
let dep_node_debug = &self.data.as_ref().unwrap().dep_node_debug;
dep_node_debug.entry(dep_node)
.or_insert_with(debug_str_gen);
if dep_node_debug.borrow().contains_key(&dep_node) {
return
}
let debug_str = debug_str_gen();
dep_node_debug.borrow_mut().insert(dep_node, debug_str);
}
pub(super) fn dep_node_debug_str(&self, dep_node: DepNode) -> Option<String> {

View File

@ -787,7 +787,7 @@ impl<'a> LoweringContext<'a> {
return n;
}
assert!(!def_id.is_local());
let n = self.sess.cstore.item_generics_cloned(def_id).regions.len();
let n = self.sess.cstore.item_generics_cloned_untracked(def_id).regions.len();
self.type_def_lifetime_params.insert(def_id, n);
n
});
@ -2863,7 +2863,7 @@ impl<'a> LoweringContext<'a> {
let parent_def = self.parent_def.unwrap();
let def_id = {
let defs = self.resolver.definitions();
let def_path_data = DefPathData::Binding(name);
let def_path_data = DefPathData::Binding(name.as_str());
let def_index = defs.create_def_with_parent(parent_def,
node_id,
def_path_data,

View File

@ -104,14 +104,14 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
DefPathData::Impl,
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Trait(..) |
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
DefPathData::TypeNs(i.ident.name),
DefPathData::TypeNs(i.ident.name.as_str()),
ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => {
return visit::walk_item(self, i);
}
ItemKind::Mod(..) => DefPathData::Module(i.ident.name),
ItemKind::Mod(..) => DefPathData::Module(i.ident.name.as_str()),
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
DefPathData::ValueNs(i.ident.name),
ItemKind::MacroDef(..) => DefPathData::MacroDef(i.ident.name),
DefPathData::ValueNs(i.ident.name.as_str()),
ItemKind::MacroDef(..) => DefPathData::MacroDef(i.ident.name.as_str()),
ItemKind::Mac(..) => return self.visit_macro_invoc(i.id, false),
ItemKind::GlobalAsm(..) => DefPathData::Misc,
ItemKind::Use(ref view_path) => {
@ -139,13 +139,15 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
for v in &enum_definition.variants {
let variant_def_index =
this.create_def(v.node.data.id(),
DefPathData::EnumVariant(v.node.name.name),
DefPathData::EnumVariant(v.node.name.name.as_str()),
REGULAR_SPACE);
this.with_parent(variant_def_index, |this| {
for (index, field) in v.node.data.fields().iter().enumerate() {
let name = field.ident.map(|ident| ident.name)
.unwrap_or_else(|| Symbol::intern(&index.to_string()));
this.create_def(field.id, DefPathData::Field(name), REGULAR_SPACE);
this.create_def(field.id,
DefPathData::Field(name.as_str()),
REGULAR_SPACE);
}
if let Some(ref expr) = v.node.disr_expr {
@ -165,7 +167,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
for (index, field) in struct_def.fields().iter().enumerate() {
let name = field.ident.map(|ident| ident.name)
.unwrap_or_else(|| Symbol::intern(&index.to_string()));
this.create_def(field.id, DefPathData::Field(name), REGULAR_SPACE);
this.create_def(field.id, DefPathData::Field(name.as_str()), REGULAR_SPACE);
}
}
_ => {}
@ -176,7 +178,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
let def = self.create_def(foreign_item.id,
DefPathData::ValueNs(foreign_item.ident.name),
DefPathData::ValueNs(foreign_item.ident.name.as_str()),
REGULAR_SPACE);
self.with_parent(def, |this| {
@ -187,7 +189,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
fn visit_generics(&mut self, generics: &'a Generics) {
for ty_param in generics.ty_params.iter() {
self.create_def(ty_param.id,
DefPathData::TypeParam(ty_param.ident.name),
DefPathData::TypeParam(ty_param.ident.name.as_str()),
REGULAR_SPACE);
}
@ -197,8 +199,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
fn visit_trait_item(&mut self, ti: &'a TraitItem) {
let def_data = match ti.node {
TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
DefPathData::ValueNs(ti.ident.name),
TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name),
DefPathData::ValueNs(ti.ident.name.as_str()),
TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name.as_str()),
TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false),
};
@ -215,8 +217,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
fn visit_impl_item(&mut self, ii: &'a ImplItem) {
let def_data = match ii.node {
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
DefPathData::ValueNs(ii.ident.name),
ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.name),
DefPathData::ValueNs(ii.ident.name.as_str()),
ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.name.as_str()),
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id, false),
};
@ -237,7 +239,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
PatKind::Mac(..) => return self.visit_macro_invoc(pat.id, false),
PatKind::Ident(_, id, _) => {
let def = self.create_def(pat.id,
DefPathData::Binding(id.node.name),
DefPathData::Binding(id.node.name.as_str()),
REGULAR_SPACE);
self.parent_def = Some(def);
}
@ -282,7 +284,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
fn visit_lifetime_def(&mut self, def: &'a LifetimeDef) {
self.create_def(def.lifetime.id,
DefPathData::LifetimeDef(def.lifetime.ident.name),
DefPathData::LifetimeDef(def.lifetime.ident.name.as_str()),
REGULAR_SPACE);
}

View File

@ -80,8 +80,10 @@ impl DefPathTable {
#[inline(always)]
pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
self.def_path_hashes[index.address_space().index()]
[index.as_array_index()]
let ret = self.def_path_hashes[index.address_space().index()]
[index.as_array_index()];
debug!("def_path_hash({:?}) = {:?}", index, ret);
return ret
}
pub fn add_def_path_hashes_to(&self,
@ -213,7 +215,7 @@ impl DefKey {
DefPathData::Binding(name) |
DefPathData::Field(name) |
DefPathData::GlobalMetaData(name) => {
(*name.as_str()).hash(&mut hasher);
name.hash(&mut hasher);
}
DefPathData::Impl |
@ -347,31 +349,31 @@ pub enum DefPathData {
/// An impl
Impl,
/// Something in the type NS
TypeNs(Symbol),
TypeNs(InternedString),
/// Something in the value NS
ValueNs(Symbol),
ValueNs(InternedString),
/// A module declaration
Module(Symbol),
Module(InternedString),
/// A macro rule
MacroDef(Symbol),
MacroDef(InternedString),
/// A closure expression
ClosureExpr,
// Subportions of items
/// A type parameter (generic parameter)
TypeParam(Symbol),
TypeParam(InternedString),
/// A lifetime definition
LifetimeDef(Symbol),
LifetimeDef(InternedString),
/// A variant of a enum
EnumVariant(Symbol),
EnumVariant(InternedString),
/// A struct field
Field(Symbol),
Field(InternedString),
/// Implicit ctor for a tuple-like struct
StructCtor,
/// Initializer for a const
Initializer,
/// Pattern binding
Binding(Symbol),
Binding(InternedString),
/// An `impl Trait` type node.
ImplTrait,
/// A `typeof` type node.
@ -380,7 +382,7 @@ pub enum DefPathData {
/// GlobalMetaData identifies a piece of crate metadata that is global to
/// a whole crate (as opposed to just one item). GlobalMetaData components
/// are only supposed to show up right below the crate root.
GlobalMetaData(Symbol)
GlobalMetaData(InternedString)
}
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
@ -601,7 +603,7 @@ impl Definitions {
}
impl DefPathData {
pub fn get_opt_name(&self) -> Option<Symbol> {
pub fn get_opt_name(&self) -> Option<InternedString> {
use self::DefPathData::*;
match *self {
TypeNs(name) |
@ -639,7 +641,7 @@ impl DefPathData {
Binding(name) |
Field(name) |
GlobalMetaData(name) => {
return name.as_str();
return name
}
// note that this does not show up in user printouts
@ -684,7 +686,7 @@ macro_rules! define_global_metadata_kind {
definitions.create_def_with_parent(
CRATE_DEF_INDEX,
ast::DUMMY_NODE_ID,
DefPathData::GlobalMetaData(instance.name()),
DefPathData::GlobalMetaData(instance.name().as_str()),
GLOBAL_MD_ADDRESS_SPACE,
Mark::root()
);
@ -698,7 +700,7 @@ macro_rules! define_global_metadata_kind {
let def_key = DefKey {
parent: Some(CRATE_DEF_INDEX),
disambiguated_data: DisambiguatedDefPathData {
data: DefPathData::GlobalMetaData(self.name()),
data: DefPathData::GlobalMetaData(self.name().as_str()),
disambiguator: 0,
}
};

View File

@ -878,7 +878,17 @@ impl<'hir> Map<'hir> {
Some(RootCrate(_)) => self.forest.krate.span,
Some(NotPresent) | None => {
bug!("hir::map::Map::span: id not in map: {:?}", id)
// Some nodes, notably macro definitions, are not
// present in the map for whatever reason, but
// they *do* have def-ids. So if we encounter an
// empty hole, check for that case.
if let Some(def_index) = self.definitions.opt_def_index(id) {
let def_path_hash = self.definitions.def_path_hash(def_index);
self.dep_graph.read(def_path_hash.to_dep_node(DepKind::Hir));
DUMMY_SP
} else {
bug!("hir::map::Map::span: id not in map: {:?}", id)
}
}
}
}

View File

@ -209,18 +209,19 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> {
match arg.node {
hir::TyRptr(ref lifetime, _) => {
match self.infcx.tcx.named_region_map.defs.get(&lifetime.id) {
let hir_id = self.infcx.tcx.hir.node_to_hir_id(lifetime.id);
match self.infcx.tcx.named_region(hir_id) {
// the lifetime of the TyRptr
Some(&rl::Region::LateBoundAnon(debruijn_index, anon_index)) => {
Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)) => {
if debruijn_index.depth == 1 && anon_index == br_index {
self.found_type = Some(arg);
return; // we can stop visiting now
}
}
Some(&rl::Region::Static) |
Some(&rl::Region::EarlyBound(_, _)) |
Some(&rl::Region::LateBound(_, _)) |
Some(&rl::Region::Free(_, _)) |
Some(rl::Region::Static) |
Some(rl::Region::EarlyBound(_, _)) |
Some(rl::Region::LateBound(_, _)) |
Some(rl::Region::Free(_, _)) |
None => {
debug!("no arg found");
}
@ -272,17 +273,18 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> {
_ => return,
};
match self.infcx.tcx.named_region_map.defs.get(&lifetime.id) {
let hir_id = self.infcx.tcx.hir.node_to_hir_id(lifetime.id);
match self.infcx.tcx.named_region(hir_id) {
// the lifetime of the TyPath!
Some(&rl::Region::LateBoundAnon(debruijn_index, anon_index)) => {
Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)) => {
if debruijn_index.depth == 1 && anon_index == br_index {
self.found_it = true;
}
}
Some(&rl::Region::Static) |
Some(&rl::Region::EarlyBound(_, _)) |
Some(&rl::Region::LateBound(_, _)) |
Some(&rl::Region::Free(_, _)) |
Some(rl::Region::Static) |
Some(rl::Region::EarlyBound(_, _)) |
Some(rl::Region::LateBound(_, _)) |
Some(rl::Region::Free(_, _)) |
None => {
debug!("no arg found");
}

View File

@ -357,7 +357,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// for imported and non-imported crates
if exp_path == found_path
|| exp_abs_path == found_abs_path {
let crate_name = self.tcx.sess.cstore.crate_name(did1.krate);
let crate_name = self.tcx.crate_name(did1.krate);
err.span_note(sp, &format!("Perhaps two different versions \
of crate `{}` are being used?",
crate_name));

View File

@ -23,16 +23,15 @@
//! probably get a better home if someone can find one.
use hir::def;
use hir::def_id::{CrateNum, DefId, DefIndex};
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
use hir::map as hir_map;
use hir::map::definitions::{Definitions, DefKey, DefPathTable};
use hir::svh::Svh;
use ich;
use middle::lang_items;
use ty::{self, TyCtxt};
use session::Session;
use session::search_paths::PathKind;
use util::nodemap::{NodeSet, DefIdMap};
use util::nodemap::NodeSet;
use std::any::Any;
use std::path::{Path, PathBuf};
@ -43,8 +42,6 @@ use syntax::ext::base::SyntaxExtension;
use syntax::symbol::Symbol;
use syntax_pos::Span;
use rustc_back::target::Target;
use hir;
use rustc_back::PanicStrategy;
pub use self::NativeLibraryKind::*;
@ -223,75 +220,44 @@ pub trait MetadataLoader {
/// A store of Rust crates, through with their metadata
/// can be accessed.
///
/// Note that this trait should probably not be expanding today. All new
/// functionality should be driven through queries instead!
///
/// If you find a method on this trait named `{name}_untracked` it signifies
/// that it's *not* tracked for dependency information throughout compilation
/// (it'd break incremental compilation) and should only be called pre-HIR (e.g.
/// during resolve)
pub trait CrateStore {
fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc<Any>;
// access to the metadata loader
fn metadata_loader(&self) -> &MetadataLoader;
// item info
fn visibility(&self, def: DefId) -> ty::Visibility;
fn visible_parent_map<'a>(&'a self, sess: &Session) -> ::std::cell::Ref<'a, DefIdMap<DefId>>;
fn item_generics_cloned(&self, def: DefId) -> ty::Generics;
// trait info
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
// impl info
fn impl_defaultness(&self, def: DefId) -> hir::Defaultness;
// trait/impl-item info
fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem;
// flags
fn is_dllimport_foreign_item(&self, def: DefId) -> bool;
fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool;
// crate metadata
fn dep_kind(&self, cnum: CrateNum) -> DepKind;
fn export_macros(&self, cnum: CrateNum);
fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>;
fn missing_lang_items(&self, cnum: CrateNum) -> Vec<lang_items::LangItem>;
fn is_compiler_builtins(&self, cnum: CrateNum) -> bool;
fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool;
fn is_profiler_runtime(&self, cnum: CrateNum) -> bool;
fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy;
/// The name of the crate as it is referred to in source code of the current
/// crate.
fn crate_name(&self, cnum: CrateNum) -> Symbol;
/// The name of the crate as it is stored in the crate's metadata.
fn original_crate_name(&self, cnum: CrateNum) -> Symbol;
fn crate_hash(&self, cnum: CrateNum) -> Svh;
fn crate_disambiguator(&self, cnum: CrateNum) -> Symbol;
fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>;
fn derive_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>;
fn native_libraries(&self, cnum: CrateNum) -> Vec<NativeLibrary>;
fn exported_symbols(&self, cnum: CrateNum) -> Vec<DefId>;
fn is_no_builtins(&self, cnum: CrateNum) -> bool;
// resolve
fn def_key(&self, def: DefId) -> DefKey;
fn def_path(&self, def: DefId) -> hir_map::DefPath;
fn def_path_hash(&self, def: DefId) -> hir_map::DefPathHash;
fn def_path_table(&self, cnum: CrateNum) -> Rc<DefPathTable>;
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
fn item_children(&self, did: DefId, sess: &Session) -> Vec<def::Export>;
fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro;
// misc. metadata
fn item_body<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> &'tcx hir::Body;
// "queries" used in resolve that aren't tracked for incremental compilation
fn visibility_untracked(&self, def: DefId) -> ty::Visibility;
fn export_macros_untracked(&self, cnum: CrateNum);
fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind;
fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
fn struct_field_names_untracked(&self, def: DefId) -> Vec<ast::Name>;
fn item_children_untracked(&self, did: DefId, sess: &Session) -> Vec<def::Export>;
fn load_macro_untracked(&self, did: DefId, sess: &Session) -> LoadedMacro;
fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
fn item_generics_cloned_untracked(&self, def: DefId) -> ty::Generics;
fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssociatedItem;
fn postorder_cnums_untracked(&self) -> Vec<CrateNum>;
// This is basically a 1-based range of ints, which is a little
// silly - I may fix that.
fn crates(&self) -> Vec<CrateNum>;
fn used_libraries(&self) -> Vec<NativeLibrary>;
fn used_link_args(&self) -> Vec<String>;
fn crates_untracked(&self) -> Vec<CrateNum>;
// utility functions
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
fn encode_metadata<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta,
@ -336,57 +302,18 @@ impl CrateStore for DummyCrateStore {
fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc<Any>
{ bug!("crate_data_as_rc_any") }
// item info
fn visibility(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
fn visible_parent_map<'a>(&'a self, session: &Session)
-> ::std::cell::Ref<'a, DefIdMap<DefId>>
{
bug!("visible_parent_map")
}
fn item_generics_cloned(&self, def: DefId) -> ty::Generics
fn visibility_untracked(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
fn item_generics_cloned_untracked(&self, def: DefId) -> ty::Generics
{ bug!("item_generics_cloned") }
// trait info
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }
// impl info
fn impl_defaultness(&self, def: DefId) -> hir::Defaultness { bug!("impl_defaultness") }
// trait/impl-item info
fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem
fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssociatedItem
{ bug!("associated_item_cloned") }
// flags
fn is_dllimport_foreign_item(&self, id: DefId) -> bool { false }
fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { false }
// crate metadata
fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>
{ bug!("lang_items") }
fn missing_lang_items(&self, cnum: CrateNum) -> Vec<lang_items::LangItem>
{ bug!("missing_lang_items") }
fn dep_kind(&self, cnum: CrateNum) -> DepKind { bug!("is_explicitly_linked") }
fn export_macros(&self, cnum: CrateNum) { bug!("export_macros") }
fn is_compiler_builtins(&self, cnum: CrateNum) -> bool { bug!("is_compiler_builtins") }
fn is_profiler_runtime(&self, cnum: CrateNum) -> bool { bug!("is_profiler_runtime") }
fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool { bug!("is_sanitizer_runtime") }
fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy {
bug!("panic_strategy")
}
fn crate_name(&self, cnum: CrateNum) -> Symbol { bug!("crate_name") }
fn original_crate_name(&self, cnum: CrateNum) -> Symbol {
bug!("original_crate_name")
}
fn crate_hash(&self, cnum: CrateNum) -> Svh { bug!("crate_hash") }
fn crate_disambiguator(&self, cnum: CrateNum)
-> Symbol { bug!("crate_disambiguator") }
fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
{ bug!("plugin_registrar_fn") }
fn derive_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
{ bug!("derive_registrar_fn") }
fn native_libraries(&self, cnum: CrateNum) -> Vec<NativeLibrary>
{ bug!("native_libraries") }
fn exported_symbols(&self, cnum: CrateNum) -> Vec<DefId> { bug!("exported_symbols") }
fn is_no_builtins(&self, cnum: CrateNum) -> bool { bug!("is_no_builtins") }
fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind { bug!("is_explicitly_linked") }
fn export_macros_untracked(&self, cnum: CrateNum) { bug!("export_macros") }
fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol { bug!("crate_name") }
// resolve
fn def_key(&self, def: DefId) -> DefKey { bug!("def_key") }
@ -399,29 +326,18 @@ impl CrateStore for DummyCrateStore {
fn def_path_table(&self, cnum: CrateNum) -> Rc<DefPathTable> {
bug!("def_path_table")
}
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
fn item_children(&self, did: DefId, sess: &Session) -> Vec<def::Export> {
fn struct_field_names_untracked(&self, def: DefId) -> Vec<ast::Name> {
bug!("struct_field_names")
}
fn item_children_untracked(&self, did: DefId, sess: &Session) -> Vec<def::Export> {
bug!("item_children")
}
fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro { bug!("load_macro") }
fn load_macro_untracked(&self, did: DefId, sess: &Session) -> LoadedMacro { bug!("load_macro") }
// misc. metadata
fn item_body<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> &'tcx hir::Body {
bug!("item_body")
}
// This is basically a 1-based range of ints, which is a little
// silly - I may fix that.
fn crates(&self) -> Vec<CrateNum> { vec![] }
fn used_libraries(&self) -> Vec<NativeLibrary> { vec![] }
fn used_link_args(&self) -> Vec<String> { vec![] }
fn crates_untracked(&self) -> Vec<CrateNum> { vec![] }
// utility functions
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
{ vec![] }
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None }
fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None }
fn encode_metadata<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta,
@ -430,6 +346,7 @@ impl CrateStore for DummyCrateStore {
bug!("encode_metadata")
}
fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
fn postorder_cnums_untracked(&self) -> Vec<CrateNum> { bug!("postorder_cnums_untracked") }
// access to the metadata loader
fn metadata_loader(&self) -> &MetadataLoader { bug!("metadata_loader") }
@ -439,3 +356,47 @@ pub trait CrateLoader {
fn process_item(&mut self, item: &ast::Item, defs: &Definitions);
fn postprocess(&mut self, krate: &ast::Crate);
}
// This method is used when generating the command line to pass through to
// system linker. The linker expects undefined symbols on the left of the
// command line to be defined in libraries on the right, not the other way
// around. For more info, see some comments in the add_used_library function
// below.
//
// In order to get this left-to-right dependency ordering, we perform a
// topological sort of all crates putting the leaves at the right-most
// positions.
pub fn used_crates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> {
let mut libs = tcx.crates()
.iter()
.cloned()
.filter_map(|cnum| {
if tcx.dep_kind(cnum).macros_only() {
return None
}
let source = tcx.used_crate_source(cnum);
let path = match prefer {
LinkagePreference::RequireDynamic => source.dylib.clone().map(|p| p.0),
LinkagePreference::RequireStatic => source.rlib.clone().map(|p| p.0),
};
let path = match path {
Some(p) => LibSource::Some(p),
None => {
if source.rmeta.is_some() {
LibSource::MetadataOnly
} else {
LibSource::None
}
}
};
Some((cnum, path))
})
.collect::<Vec<_>>();
let mut ordering = tcx.postorder_cnums(LOCAL_CRATE);
Rc::make_mut(&mut ordering).reverse();
libs.sort_by_key(|&(a, _)| {
ordering.iter().position(|x| *x == a)
});
libs
}

View File

@ -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()

View File

@ -66,7 +66,7 @@ use hir::def_id::CrateNum;
use session;
use session::config;
use ty::TyCtxt;
use middle::cstore::DepKind;
use middle::cstore::{self, DepKind};
use middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic};
use util::nodemap::FxHashMap;
use rustc_back::PanicStrategy;
@ -132,12 +132,12 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
if let Some(v) = attempt_static(tcx) {
return v;
}
for cnum in sess.cstore.crates() {
if sess.cstore.dep_kind(cnum).macros_only() { continue }
let src = sess.cstore.used_crate_source(cnum);
for &cnum in tcx.crates().iter() {
if tcx.dep_kind(cnum).macros_only() { continue }
let src = tcx.used_crate_source(cnum);
if src.rlib.is_some() { continue }
sess.err(&format!("dependency `{}` not found in rlib format",
sess.cstore.crate_name(cnum)));
tcx.crate_name(cnum)));
}
return Vec::new();
}
@ -165,24 +165,23 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Sweep all crates for found dylibs. Add all dylibs, as well as their
// dependencies, ensuring there are no conflicts. The only valid case for a
// dependency to be relied upon twice is for both cases to rely on a dylib.
for cnum in sess.cstore.crates() {
if sess.cstore.dep_kind(cnum).macros_only() { continue }
let name = sess.cstore.crate_name(cnum);
let src = sess.cstore.used_crate_source(cnum);
for &cnum in tcx.crates().iter() {
if tcx.dep_kind(cnum).macros_only() { continue }
let name = tcx.crate_name(cnum);
let src = tcx.used_crate_source(cnum);
if src.dylib.is_some() {
info!("adding dylib: {}", name);
add_library(sess, cnum, RequireDynamic, &mut formats);
let deps = tcx.dylib_dependency_formats(cnum.as_def_id());
add_library(tcx, cnum, RequireDynamic, &mut formats);
let deps = tcx.dylib_dependency_formats(cnum);
for &(depnum, style) in deps.iter() {
info!("adding {:?}: {}", style,
sess.cstore.crate_name(depnum));
add_library(sess, depnum, style, &mut formats);
info!("adding {:?}: {}", style, tcx.crate_name(depnum));
add_library(tcx, depnum, style, &mut formats);
}
}
}
// Collect what we've got so far in the return vector.
let last_crate = sess.cstore.crates().len();
let last_crate = tcx.crates().len();
let mut ret = (1..last_crate+1).map(|cnum| {
match formats.get(&CrateNum::new(cnum)) {
Some(&RequireDynamic) => Linkage::Dynamic,
@ -196,14 +195,14 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
//
// If the crate hasn't been included yet and it's not actually required
// (e.g. it's an allocator) then we skip it here as well.
for cnum in sess.cstore.crates() {
let src = sess.cstore.used_crate_source(cnum);
for &cnum in tcx.crates().iter() {
let src = tcx.used_crate_source(cnum);
if src.dylib.is_none() &&
!formats.contains_key(&cnum) &&
sess.cstore.dep_kind(cnum) == DepKind::Explicit {
tcx.dep_kind(cnum) == DepKind::Explicit {
assert!(src.rlib.is_some() || src.rmeta.is_some());
info!("adding staticlib: {}", sess.cstore.crate_name(cnum));
add_library(sess, cnum, RequireStatic, &mut formats);
info!("adding staticlib: {}", tcx.crate_name(cnum));
add_library(tcx, cnum, RequireStatic, &mut formats);
ret[cnum.as_usize() - 1] = Linkage::Static;
}
}
@ -215,7 +214,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Things like allocators and panic runtimes may not have been activated
// quite yet, so do so here.
activate_injected_dep(sess.injected_panic_runtime.get(), &mut ret,
&|cnum| tcx.is_panic_runtime(cnum.as_def_id()));
&|cnum| tcx.is_panic_runtime(cnum));
activate_injected_allocator(sess, &mut ret);
// When dylib B links to dylib A, then when using B we must also link to A.
@ -226,7 +225,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// making sure that everything is available in the requested format.
for (cnum, kind) in ret.iter().enumerate() {
let cnum = CrateNum::new(cnum + 1);
let src = sess.cstore.used_crate_source(cnum);
let src = tcx.used_crate_source(cnum);
match *kind {
Linkage::NotLinked |
Linkage::IncludedFromDylib => {}
@ -237,7 +236,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Linkage::Static => "rlib",
_ => "dylib",
};
let name = sess.cstore.crate_name(cnum);
let name = tcx.crate_name(cnum);
sess.err(&format!("crate `{}` required to be available in {}, \
but it was not available in this form",
name, kind));
@ -248,7 +247,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
return ret;
}
fn add_library(sess: &session::Session,
fn add_library(tcx: TyCtxt,
cnum: CrateNum,
link: LinkagePreference,
m: &mut FxHashMap<CrateNum, LinkagePreference>) {
@ -262,8 +261,8 @@ fn add_library(sess: &session::Session,
// This error is probably a little obscure, but I imagine that it
// can be refined over time.
if link2 != link || link == RequireStatic {
sess.struct_err(&format!("cannot satisfy dependencies so `{}` only \
shows up once", sess.cstore.crate_name(cnum)))
tcx.sess.struct_err(&format!("cannot satisfy dependencies so `{}` only \
shows up once", tcx.crate_name(cnum)))
.help("having upstream crates all available in one format \
will likely make this go away")
.emit();
@ -275,16 +274,16 @@ fn add_library(sess: &session::Session,
fn attempt_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<DependencyList> {
let sess = &tcx.sess;
let crates = sess.cstore.used_crates(RequireStatic);
let crates = cstore::used_crates(tcx, RequireStatic);
if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) {
return None
}
// All crates are available in an rlib format, so we're just going to link
// everything in explicitly so long as it's actually required.
let last_crate = sess.cstore.crates().len();
let last_crate = tcx.crates().len();
let mut ret = (1..last_crate+1).map(|cnum| {
if sess.cstore.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit {
if tcx.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit {
Linkage::Static
} else {
Linkage::NotLinked
@ -295,7 +294,7 @@ fn attempt_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<DependencyLis
// explicitly linked, which is the case for any injected dependency. Handle
// that here and activate them.
activate_injected_dep(sess.injected_panic_runtime.get(), &mut ret,
&|cnum| tcx.is_panic_runtime(cnum.as_def_id()));
&|cnum| tcx.is_panic_runtime(cnum));
activate_injected_allocator(sess, &mut ret);
Some(ret)
@ -355,15 +354,15 @@ fn verify_ok<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, list: &[Linkage]) {
}
let cnum = CrateNum::new(i + 1);
if tcx.is_panic_runtime(cnum.as_def_id()) {
if tcx.is_panic_runtime(cnum) {
if let Some((prev, _)) = panic_runtime {
let prev_name = sess.cstore.crate_name(prev);
let cur_name = sess.cstore.crate_name(cnum);
let prev_name = tcx.crate_name(prev);
let cur_name = tcx.crate_name(cnum);
sess.err(&format!("cannot link together two \
panic runtimes: {} and {}",
prev_name, cur_name));
}
panic_runtime = Some((cnum, sess.cstore.panic_strategy(cnum)));
panic_runtime = Some((cnum, tcx.panic_strategy(cnum)));
}
}
@ -379,7 +378,7 @@ fn verify_ok<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, list: &[Linkage]) {
sess.err(&format!("the linked panic runtime `{}` is \
not compiled with this crate's \
panic strategy `{}`",
sess.cstore.crate_name(cnum),
tcx.crate_name(cnum),
desired_strategy.desc()));
}
@ -395,8 +394,8 @@ fn verify_ok<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, list: &[Linkage]) {
continue
}
let cnum = CrateNum::new(i + 1);
let found_strategy = sess.cstore.panic_strategy(cnum);
let is_compiler_builtins = sess.cstore.is_compiler_builtins(cnum);
let found_strategy = tcx.panic_strategy(cnum);
let is_compiler_builtins = tcx.is_compiler_builtins(cnum);
if is_compiler_builtins || desired_strategy == found_strategy {
continue
}
@ -405,7 +404,7 @@ fn verify_ok<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, list: &[Linkage]) {
panic strategy `{}` which is \
incompatible with this crate's \
strategy of `{}`",
sess.cstore.crate_name(cnum),
tcx.crate_name(cnum),
found_strategy.desc(),
desired_strategy.desc()));
}

View File

@ -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 => {

View File

@ -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(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(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.crates().iter() {
for &(index, item_index) in tcx.defined_lang_items(cnum).iter() {
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)
})
}

View File

@ -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);

View File

@ -978,7 +978,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
} else {
let cstore = &self.sess.cstore;
self.xcrate_object_lifetime_defaults.entry(def_id).or_insert_with(|| {
cstore.item_generics_cloned(def_id).types.into_iter().map(|def| {
cstore.item_generics_cloned_untracked(def_id).types.into_iter().map(|def| {
def.object_lifetime_default
}).collect()
})

View File

@ -15,20 +15,19 @@ pub use self::StabilityLevel::*;
use lint;
use hir::def::Def;
use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, DefIndex, LOCAL_CRATE};
use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
use ty::{self, TyCtxt};
use middle::privacy::AccessLevels;
use session::Session;
use syntax::symbol::Symbol;
use syntax_pos::{Span, DUMMY_SP};
use syntax::ast;
use syntax::ast::{NodeId, Attribute};
use syntax::feature_gate::{GateIssue, emit_feature_err, find_lang_feature_accepted_version};
use syntax::attr::{self, Stability, Deprecation};
use util::nodemap::{DefIdMap, FxHashSet, FxHashMap};
use util::nodemap::{FxHashSet, FxHashMap};
use hir;
use hir::{Item, Generics, StructField, Variant};
use hir::{Item, Generics, StructField, Variant, HirId};
use hir::intravisit::{self, Visitor, NestedVisitorMap};
use std::mem::replace;
@ -63,19 +62,18 @@ pub struct DeprecationEntry {
pub attr: Deprecation,
/// The def id where the attr was originally attached. `None` for non-local
/// `DefId`'s.
origin: Option<DefIndex>,
origin: Option<HirId>,
}
impl DeprecationEntry {
fn local(attr: Deprecation, id: DefId) -> DeprecationEntry {
assert!(id.is_local());
fn local(attr: Deprecation, id: HirId) -> DeprecationEntry {
DeprecationEntry {
attr,
origin: Some(id.index),
origin: Some(id),
}
}
fn external(attr: Deprecation) -> DeprecationEntry {
pub fn external(attr: Deprecation) -> DeprecationEntry {
DeprecationEntry {
attr,
origin: None,
@ -94,17 +92,14 @@ impl DeprecationEntry {
pub struct Index<'tcx> {
/// This is mostly a cache, except the stabilities of local items
/// are filled by the annotator.
stab_map: DefIdMap<Option<&'tcx Stability>>,
depr_map: DefIdMap<Option<DeprecationEntry>>,
stab_map: FxHashMap<HirId, &'tcx Stability>,
depr_map: FxHashMap<HirId, DeprecationEntry>,
/// Maps for each crate whether it is part of the staged API.
staged_api: FxHashMap<CrateNum, bool>,
/// Features enabled for this crate.
active_features: FxHashSet<Symbol>,
/// Features used by this crate. Updated before and during typeck.
used_features: FxHashMap<Symbol, attr::StabilityLevel>
}
// A private tree-walker for producing an Index.
@ -178,8 +173,8 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
}
}
let def_id = self.tcx.hir.local_def_id(id);
self.index.stab_map.insert(def_id, Some(stab));
let hir_id = self.tcx.hir.node_to_hir_id(id);
self.index.stab_map.insert(hir_id, stab);
let orig_parent_stab = replace(&mut self.parent_stab, Some(stab));
visit_children(self);
@ -188,8 +183,8 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
debug!("annotate: not found, parent = {:?}", self.parent_stab);
if let Some(stab) = self.parent_stab {
if stab.level.is_unstable() {
let def_id = self.tcx.hir.local_def_id(id);
self.index.stab_map.insert(def_id, Some(stab));
let hir_id = self.tcx.hir.node_to_hir_id(id);
self.index.stab_map.insert(hir_id, stab);
}
}
visit_children(self);
@ -209,8 +204,8 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
// -Zforce-unstable-if-unmarked is set.
if let Some(stab) = self.parent_stab {
if stab.level.is_unstable() {
let def_id = self.tcx.hir.local_def_id(id);
self.index.stab_map.insert(def_id, Some(stab));
let hir_id = self.tcx.hir.node_to_hir_id(id);
self.index.stab_map.insert(hir_id, stab);
}
}
@ -220,16 +215,17 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
}
// `Deprecation` is just two pointers, no need to intern it
let def_id = self.tcx.hir.local_def_id(id);
let depr_entry = Some(DeprecationEntry::local(depr, def_id));
self.index.depr_map.insert(def_id, depr_entry.clone());
let hir_id = self.tcx.hir.node_to_hir_id(id);
let depr_entry = DeprecationEntry::local(depr, hir_id);
self.index.depr_map.insert(hir_id, depr_entry.clone());
let orig_parent_depr = replace(&mut self.parent_depr, depr_entry);
let orig_parent_depr = replace(&mut self.parent_depr,
Some(depr_entry));
visit_children(self);
self.parent_depr = orig_parent_depr;
} else if let parent_depr @ Some(_) = self.parent_depr.clone() {
let def_id = self.tcx.hir.local_def_id(id);
self.index.depr_map.insert(def_id, parent_depr);
} else if let Some(parent_depr) = self.parent_depr.clone() {
let hir_id = self.tcx.hir.node_to_hir_id(id);
self.index.depr_map.insert(hir_id, parent_depr);
visit_children(self);
} else {
visit_children(self);
@ -322,10 +318,10 @@ struct MissingStabilityAnnotations<'a, 'tcx: 'a> {
impl<'a, 'tcx: 'a> MissingStabilityAnnotations<'a, 'tcx> {
fn check_missing_stability(&self, id: NodeId, span: Span) {
let def_id = self.tcx.hir.local_def_id(id);
let stab = self.tcx.stability.borrow().stab_map.get(&def_id).cloned();
let hir_id = self.tcx.hir.node_to_hir_id(id);
let stab = self.tcx.stability().local_stability(hir_id);
let is_error = !self.tcx.sess.opts.test &&
(stab == None || stab == Some(None)) &&
stab.is_none() &&
self.access_levels.is_reachable(id);
if is_error {
self.tcx.sess.span_err(span, "This node does not have a stability attribute");
@ -386,60 +382,70 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> {
}
impl<'a, 'tcx> Index<'tcx> {
/// Construct the stability index for a crate being compiled.
pub fn build(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Index<'tcx> {
let is_staged_api =
tcx.sess.opts.debugging_opts.force_unstable_if_unmarked ||
tcx.sess.features.borrow().staged_api;
let mut staged_api = FxHashMap();
staged_api.insert(LOCAL_CRATE, is_staged_api);
let mut index = Index {
staged_api,
stab_map: FxHashMap(),
depr_map: FxHashMap(),
active_features: FxHashSet(),
};
let ref active_lib_features = tcx.sess.features.borrow().declared_lib_features;
// Put the active features into a map for quick lookup
self.active_features = active_lib_features.iter().map(|&(ref s, _)| s.clone()).collect();
index.active_features = active_lib_features.iter().map(|&(ref s, _)| s.clone()).collect();
let krate = tcx.hir.krate();
let mut annotator = Annotator {
tcx,
index: self,
parent_stab: None,
parent_depr: None,
in_trait_impl: false,
};
{
let krate = tcx.hir.krate();
let mut annotator = Annotator {
tcx,
index: &mut index,
parent_stab: None,
parent_depr: None,
in_trait_impl: false,
};
// If the `-Z force-unstable-if-unmarked` flag is passed then we provide
// a parent stability annotation which indicates that this is private
// with the `rustc_private` feature. This is intended for use when
// compiling librustc crates themselves so we can leverage crates.io
// while maintaining the invariant that all sysroot crates are unstable
// by default and are unable to be used.
if tcx.sess.opts.debugging_opts.force_unstable_if_unmarked {
let reason = "this crate is being loaded from the sysroot, and \
unstable location; did you mean to load this crate \
from crates.io via `Cargo.toml` instead?";
let stability = tcx.intern_stability(Stability {
level: attr::StabilityLevel::Unstable {
reason: Some(Symbol::intern(reason)),
issue: 27812,
},
feature: Symbol::intern("rustc_private"),
rustc_depr: None,
});
annotator.parent_stab = Some(stability);
// If the `-Z force-unstable-if-unmarked` flag is passed then we provide
// a parent stability annotation which indicates that this is private
// with the `rustc_private` feature. This is intended for use when
// compiling librustc crates themselves so we can leverage crates.io
// while maintaining the invariant that all sysroot crates are unstable
// by default and are unable to be used.
if tcx.sess.opts.debugging_opts.force_unstable_if_unmarked {
let reason = "this crate is being loaded from the sysroot, and \
unstable location; did you mean to load this crate \
from crates.io via `Cargo.toml` instead?";
let stability = tcx.intern_stability(Stability {
level: attr::StabilityLevel::Unstable {
reason: Some(Symbol::intern(reason)),
issue: 27812,
},
feature: Symbol::intern("rustc_private"),
rustc_depr: None,
});
annotator.parent_stab = Some(stability);
}
annotator.annotate(ast::CRATE_NODE_ID,
&krate.attrs,
krate.span,
AnnotationKind::Required,
|v| intravisit::walk_crate(v, krate));
}
annotator.annotate(ast::CRATE_NODE_ID, &krate.attrs, krate.span, AnnotationKind::Required,
|v| intravisit::walk_crate(v, krate));
return index
}
pub fn new(sess: &Session) -> Index<'tcx> {
let is_staged_api =
sess.opts.debugging_opts.force_unstable_if_unmarked ||
sess.features.borrow().staged_api;
let mut staged_api = FxHashMap();
staged_api.insert(LOCAL_CRATE, is_staged_api);
Index {
staged_api,
stab_map: DefIdMap(),
depr_map: DefIdMap(),
active_features: FxHashSet(),
used_features: FxHashMap(),
}
pub fn local_stability(&self, id: HirId) -> Option<&'tcx Stability> {
self.stab_map.get(&id).cloned()
}
pub fn local_deprecation_entry(&self, id: HirId) -> Option<DeprecationEntry> {
self.depr_map.get(&id).cloned()
}
}
@ -476,7 +482,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
_ => {}
}
let visibility = self.sess.cstore.visibility(def_id);
let visibility = self.visibility(def_id);
match visibility {
// must check stability for pub items.
@ -547,10 +553,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
return
}
if let Some(&Stability { ref level, ref feature, .. }) = stability {
self.stability.borrow_mut().used_features.insert(feature.clone(), level.clone());
}
// Issue 38412: private items lack stability markers.
if self.skip_stability_check_due_to_privacy(def_id) {
return
@ -558,7 +560,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
match stability {
Some(&Stability { level: attr::Unstable {ref reason, issue}, ref feature, .. }) => {
if self.stability.borrow().active_features.contains(feature) {
if self.stability().active_features.contains(feature) {
return
}
@ -610,7 +612,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
// compiler-generated `extern crate` items have a dummy span.
if item.span == DUMMY_SP { return }
let cnum = match self.tcx.sess.cstore.extern_mod_stmt_cnum(item.id) {
let hir_id = self.tcx.hir.node_to_hir_id(item.id);
let cnum = match self.tcx.extern_mod_stmt_cnum(hir_id) {
Some(cnum) => cnum,
None => return,
};
@ -671,49 +674,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
}
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// Lookup the stability for a node, loading external crate
/// metadata as necessary.
pub fn lookup_stability(self, id: DefId) -> Option<&'gcx Stability> {
if let Some(st) = self.stability.borrow().stab_map.get(&id) {
return *st;
}
let st = self.lookup_stability_uncached(id);
self.stability.borrow_mut().stab_map.insert(id, st);
st
}
pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
self.lookup_deprecation_entry(id).map(|depr| depr.attr)
}
pub fn lookup_deprecation_entry(self, id: DefId) -> Option<DeprecationEntry> {
if let Some(depr) = self.stability.borrow().depr_map.get(&id) {
return depr.clone();
}
let depr = self.lookup_deprecation_uncached(id);
self.stability.borrow_mut().depr_map.insert(id, depr.clone());
depr
}
fn lookup_stability_uncached(self, id: DefId) -> Option<&'gcx Stability> {
debug!("lookup(id={:?})", id);
if id.is_local() {
None // The stability cache is filled partially lazily
} else {
self.stability(id).map(|st| self.intern_stability(st))
}
}
fn lookup_deprecation_uncached(self, id: DefId) -> Option<DeprecationEntry> {
debug!("lookup(id={:?})", id);
if id.is_local() {
None // The stability cache is filled partially lazily
} else {
self.deprecation(id).map(DeprecationEntry::external)
}
}
}
/// Given the list of enabled features that were not language features (i.e. that
@ -724,7 +687,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
if tcx.stability.borrow().staged_api[&LOCAL_CRATE] {
if tcx.stability().staged_api[&LOCAL_CRATE] {
let krate = tcx.hir.krate();
let mut missing = MissingStabilityAnnotations {
tcx,
@ -740,10 +703,6 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
= declared_lib_features.clone().into_iter().collect();
remaining_lib_features.remove(&Symbol::intern("proc_macro"));
fn format_stable_since_msg(version: &str) -> String {
format!("this feature has been stable since {}. Attribute no longer needed", version)
}
for &(ref stable_lang_feature, span) in &sess.features.borrow().declared_stable_lang_features {
let version = find_lang_feature_accepted_version(&stable_lang_feature.as_str())
.expect("unexpectedly couldn't find version feature was stabilized");
@ -753,25 +712,23 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
&format_stable_since_msg(version));
}
let index = tcx.stability.borrow();
for (used_lib_feature, level) in &index.used_features {
match remaining_lib_features.remove(used_lib_feature) {
Some(span) => {
if let &attr::StabilityLevel::Stable { since: ref version } = level {
tcx.lint_node(lint::builtin::STABLE_FEATURES,
ast::CRATE_NODE_ID,
span,
&format_stable_since_msg(&version.as_str()));
}
}
None => ( /* used but undeclared, handled during the previous ast visit */ )
}
}
for &span in remaining_lib_features.values() {
tcx.lint_node(lint::builtin::UNUSED_FEATURES,
ast::CRATE_NODE_ID,
span,
"unused or unknown feature");
}
// FIXME(#44232) the `used_features` table no longer exists, so we don't
// lint about unknown or unused features. We should reenable
// this one day!
//
// let index = tcx.stability();
// for (used_lib_feature, level) in &index.used_features {
// remaining_lib_features.remove(used_lib_feature);
// }
//
// for &span in remaining_lib_features.values() {
// tcx.lint_node(lint::builtin::UNUSED_FEATURES,
// ast::CRATE_NODE_ID,
// span,
// "unused or unknown feature");
// }
}
fn format_stable_since_msg(version: &str) -> String {
format!("this feature has been stable since {}. Attribute no longer needed", version)
}

View File

@ -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.crates().iter() {
for &item in tcx.missing_lang_items(cnum).iter() {
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
}

View File

@ -348,7 +348,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
//
// Currently I'm leaving it for what I need for `try`.
if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
method = self.tcx.item_name(item).as_str();
method = self.tcx.item_name(item);
flags.push(("from_method", None));
flags.push(("from_method", Some(&*method)));
}
@ -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);

View File

@ -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! */ }
};

View File

@ -227,7 +227,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
span: Span)
-> Result<(), ErrorReported>
{
let name = tcx.item_name(trait_def_id).as_str();
let name = tcx.item_name(trait_def_id);
let generics = tcx.generics_of(trait_def_id);
let parser = Parser::new(&self.0);
let types = &generics.types;
@ -272,7 +272,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
trait_ref: ty::TraitRef<'tcx>)
-> String
{
let name = tcx.item_name(trait_ref.def_id).as_str();
let name = tcx.item_name(trait_ref.def_id);
let trait_str = tcx.item_path_str(trait_ref.def_id);
let generics = tcx.generics_of(trait_ref.def_id);
let generic_map = generics.types.iter().map(|param| {

View File

@ -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)) =

View File

@ -1315,7 +1315,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());
@ -1326,16 +1327,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`.
@ -1533,7 +1534,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(());
}
@ -1570,7 +1571,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(()); }
};
@ -1612,7 +1613,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(());
}
@ -2346,16 +2347,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)
@ -2658,7 +2660,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)
};

View File

@ -538,8 +538,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
None => {
self.global_tcx()
.sess
.cstore
.impl_defaultness(node_item_def_id)
.is_default()
}

View File

@ -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;

View File

@ -23,7 +23,7 @@ use lint::{self, Lint};
use ich::{self, StableHashingContext, NodeIdHashingMode};
use middle::free_region::FreeRegionMap;
use middle::lang_items;
use middle::resolve_lifetime;
use middle::resolve_lifetime::{self, ObjectLifetimeDefault};
use middle::stability;
use mir::Mir;
use mir::transform::Passes;
@ -33,7 +33,6 @@ use traits;
use ty::{self, Ty, TypeAndMut};
use ty::{TyS, TypeVariants, Slice};
use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorInterior, Region};
use hir::FreevarMap;
use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate};
use ty::RegionKind;
use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
@ -822,7 +821,7 @@ pub struct GlobalCtxt<'tcx> {
/// Export map produced by name resolution.
export_map: FxHashMap<HirId, Rc<Vec<Export>>>,
pub named_region_map: resolve_lifetime::NamedRegionMap,
named_region_map: NamedRegionMap,
pub hir: hir_map::Map<'tcx>,
@ -837,11 +836,11 @@ pub struct GlobalCtxt<'tcx> {
// Records the free variables refrenced by every closure
// expression. Do not track deps for this, just recompute it from
// scratch every time.
pub freevars: RefCell<FreevarMap>,
freevars: FxHashMap<HirId, Rc<Vec<hir::Freevar>>>,
pub maybe_unused_trait_imports: NodeSet,
maybe_unused_trait_imports: FxHashSet<HirId>,
pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
maybe_unused_extern_crates: Vec<(HirId, Span)>,
// Internal cache for metadata decoding. No need to track deps on this.
pub rcache: RefCell<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
@ -851,16 +850,11 @@ 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.
pub used_mut_nodes: RefCell<NodeSet>,
/// Maps any item's def-id to its stability index.
pub stability: RefCell<stability::Index<'tcx>>,
/// Caches the results of trait selection. This cache is used
/// for things that do not have to do with the parameters in scope.
pub selection_cache: traits::SelectionCache<'tcx>,
@ -909,30 +903,6 @@ impl<'tcx> GlobalCtxt<'tcx> {
}
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn crate_name(self, cnum: CrateNum) -> Symbol {
if cnum == LOCAL_CRATE {
self.crate_name
} else {
self.sess.cstore.crate_name(cnum)
}
}
pub fn original_crate_name(self, cnum: CrateNum) -> Symbol {
if cnum == LOCAL_CRATE {
self.crate_name.clone()
} else {
self.sess.cstore.original_crate_name(cnum)
}
}
pub fn crate_disambiguator(self, cnum: CrateNum) -> Symbol {
if cnum == LOCAL_CRATE {
self.sess.local_crate_disambiguator()
} else {
self.sess.cstore.crate_disambiguator(cnum)
}
}
pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics {
self.global_arenas.generics.alloc(generics)
}
@ -1016,8 +986,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
where F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'tcx>) -> R
@ -1026,14 +994,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
let interners = CtxtInterners::new(arena);
let common_types = CommonTypes::new(&interners);
let dep_graph = hir.dep_graph.clone();
let max_cnum = s.cstore.crates().iter().map(|c| c.as_usize()).max().unwrap_or(0);
let max_cnum = s.cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0);
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
providers[LOCAL_CRATE] = local_providers;
let def_path_hash_to_def_id = if s.opts.build_dep_graph() {
let upstream_def_path_tables: Vec<(CrateNum, Rc<_>)> = s
.cstore
.crates()
.crates_untracked()
.iter()
.map(|&cnum| (cnum, s.cstore.def_path_table(cnum)))
.collect();
@ -1070,26 +1038,50 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
global_interners: interners,
dep_graph: dep_graph.clone(),
types: common_types,
named_region_map,
named_region_map: NamedRegionMap {
defs:
named_region_map.defs
.into_iter()
.map(|(k, v)| (hir.node_to_hir_id(k), v))
.collect(),
late_bound:
named_region_map.late_bound
.into_iter()
.map(|k| hir.node_to_hir_id(k))
.collect(),
object_lifetime_defaults:
named_region_map.object_lifetime_defaults
.into_iter()
.map(|(k, v)| (hir.node_to_hir_id(k), Rc::new(v)))
.collect(),
},
trait_map: resolutions.trait_map.into_iter().map(|(k, v)| {
(hir.node_to_hir_id(k), Rc::new(v))
}).collect(),
export_map: resolutions.export_map.into_iter().map(|(k, v)| {
(hir.node_to_hir_id(k), Rc::new(v))
}).collect(),
freevars: resolutions.freevars.into_iter().map(|(k, v)| {
(hir.node_to_hir_id(k), Rc::new(v))
}).collect(),
maybe_unused_trait_imports:
resolutions.maybe_unused_trait_imports
.into_iter()
.map(|id| hir.node_to_hir_id(id))
.collect(),
maybe_unused_extern_crates:
resolutions.maybe_unused_extern_crates
.into_iter()
.map(|(id, sp)| (hir.node_to_hir_id(id), sp))
.collect(),
hir,
def_path_hash_to_def_id,
maps: maps::Maps::new(providers),
mir_passes,
freevars: RefCell::new(resolutions.freevars),
maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports,
maybe_unused_extern_crates: resolutions.maybe_unused_extern_crates,
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(),
evaluation_cache: traits::EvaluationCache::new(),
rvalue_promotable_to_static: RefCell::new(NodeMap()),
@ -1107,6 +1099,32 @@ 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> {
// FIXME(#42293) Right now we insert a `with_ignore` node in the dep
// graph here to ignore the fact that `get_lang_items` below depends on
// the entire crate. For now this'll prevent false positives of
// recompiling too much when anything changes.
//
// Once red/green incremental compilation lands we should be able to
// remove this because while the crate changes often the lint level map
// will change rarely.
self.dep_graph.with_ignore(|| {
self.get_lang_items(LOCAL_CRATE)
})
}
pub fn stability(self) -> Rc<stability::Index<'tcx>> {
// FIXME(#42293) we should actually track this, but fails too many tests
// today.
self.dep_graph.with_ignore(|| {
self.stability_index(LOCAL_CRATE)
})
}
pub fn crates(self) -> Rc<Vec<CrateNum>> {
self.all_crate_nums(LOCAL_CRATE)
}
}
impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> {
@ -1994,19 +2012,52 @@ impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
}
}
fn in_scope_traits<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: HirId)
-> Option<Rc<Vec<TraitCandidate>>>
{
tcx.gcx.trait_map.get(&id).cloned()
}
fn module_exports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: HirId)
-> Option<Rc<Vec<Export>>>
{
tcx.gcx.export_map.get(&id).cloned()
struct NamedRegionMap {
defs: FxHashMap<HirId, resolve_lifetime::Region>,
late_bound: FxHashSet<HirId>,
object_lifetime_defaults: FxHashMap<HirId, Rc<Vec<ObjectLifetimeDefault>>>,
}
pub fn provide(providers: &mut ty::maps::Providers) {
providers.in_scope_traits = in_scope_traits;
providers.module_exports = module_exports;
// FIXME(#44234) - almost all of these queries have no sub-queries and
// therefore no actual inputs, they're just reading tables calculated in
// resolve! Does this work? Unsure! That's what the issue is about
providers.in_scope_traits = |tcx, id| tcx.gcx.trait_map.get(&id).cloned();
providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).cloned();
providers.named_region = |tcx, id| tcx.gcx.named_region_map.defs.get(&id).cloned();
providers.is_late_bound = |tcx, id| tcx.gcx.named_region_map.late_bound.contains(&id);
providers.object_lifetime_defaults = |tcx, id| {
tcx.gcx.named_region_map.object_lifetime_defaults.get(&id).cloned()
};
providers.crate_name = |tcx, id| {
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))
};
providers.freevars = |tcx, id| tcx.gcx.freevars.get(&id).cloned();
providers.maybe_unused_trait_import = |tcx, id| {
tcx.maybe_unused_trait_imports.contains(&id)
};
providers.maybe_unused_extern_crates = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
Rc::new(tcx.maybe_unused_extern_crates.clone())
};
providers.stability_index = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
Rc::new(stability::Index::new(tcx))
};
providers.lookup_stability = |tcx, id| {
assert_eq!(id.krate, LOCAL_CRATE);
let id = tcx.hir.definitions().def_index_to_hir_id(id.index);
tcx.stability().local_stability(id)
};
providers.lookup_deprecation_entry = |tcx, id| {
assert_eq!(id.krate, LOCAL_CRATE);
let id = tcx.hir.definitions().def_index_to_hir_id(id.index);
tcx.stability().local_deprecation_entry(id)
};
}

View File

@ -13,6 +13,7 @@ use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use ty::{self, Ty, TyCtxt};
use syntax::ast;
use syntax::symbol::Symbol;
use syntax::symbol::InternedString;
use std::cell::Cell;
@ -128,9 +129,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn try_push_visible_item_path<T>(self, buffer: &mut T, external_def_id: DefId) -> bool
where T: ItemPathBuffer
{
let visible_parent_map = self.sess.cstore.visible_parent_map(self.sess);
let visible_parent_map = self.visible_parent_map(LOCAL_CRATE);
let (mut cur_def, mut cur_path) = (external_def_id, Vec::<ast::Name>::new());
let (mut cur_def, mut cur_path) = (external_def_id, Vec::<InternedString>::new());
loop {
// If `cur_def` is a direct or injected extern crate, push the path to the crate
// followed by the path to the item within the crate and return.
@ -138,12 +139,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
match *self.extern_crate(cur_def) {
Some(ref extern_crate) if extern_crate.direct => {
self.push_item_path(buffer, extern_crate.def_id);
cur_path.iter().rev().map(|segment| buffer.push(&segment.as_str())).count();
cur_path.iter().rev().map(|segment| buffer.push(&segment)).count();
return true;
}
None => {
buffer.push(&self.crate_name(cur_def.krate).as_str());
cur_path.iter().rev().map(|segment| buffer.push(&segment.as_str())).count();
cur_path.iter().rev().map(|segment| buffer.push(&segment)).count();
return true;
}
_ => {},
@ -152,7 +153,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
cur_path.push(self.sess.cstore.def_key(cur_def)
.disambiguated_data.data.get_opt_name().unwrap_or_else(||
Symbol::intern("<unnamed>")));
Symbol::intern("<unnamed>").as_str()));
match visible_parent_map.get(&cur_def) {
Some(&def) => cur_def = def,
None => return false,

View File

@ -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 {

View File

@ -10,14 +10,19 @@
use dep_graph::{DepConstructor, DepNode, DepNodeIndex};
use errors::{Diagnostic, DiagnosticBuilder};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE, DefIndex};
use hir::def::{Def, Export};
use hir::{self, TraitCandidate, HirId};
use hir::svh::Svh;
use lint;
use middle::const_val;
use middle::cstore::{ExternCrate, LinkagePreference};
use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary};
use middle::cstore::{NativeLibraryKind, DepKind, CrateSource};
use middle::privacy::AccessLevels;
use middle::region;
use middle::resolve_lifetime::{Region, ObjectLifetimeDefault};
use middle::stability::{self, DeprecationEntry};
use middle::lang_items::{LanguageItems, LangItem};
use mir;
use mir::transform::{MirSuite, MirPassIndex};
use session::CompileResult;
@ -28,10 +33,11 @@ use ty::item_path;
use ty::steal::Steal;
use ty::subst::Substs;
use ty::fast_reject::SimplifiedType;
use util::nodemap::{DefIdSet, NodeSet};
use util::nodemap::{DefIdSet, NodeSet, DefIdMap};
use util::common::{profq_msg, ProfileQueriesMsg};
use rustc_data_structures::indexed_set::IdxSetBuf;
use rustc_back::PanicStrategy;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::fx::FxHashMap;
use std::cell::{RefCell, RefMut, Cell};
@ -428,13 +434,13 @@ impl<'tcx> QueryDescription for queries::def_span<'tcx> {
}
impl<'tcx> QueryDescription for queries::stability<'tcx> {
impl<'tcx> QueryDescription for queries::lookup_stability<'tcx> {
fn describe(_: TyCtxt, _: DefId) -> String {
bug!("stability")
}
}
impl<'tcx> QueryDescription for queries::deprecation<'tcx> {
impl<'tcx> QueryDescription for queries::lookup_deprecation_entry<'tcx> {
fn describe(_: TyCtxt, _: DefId) -> String {
bug!("deprecation")
}
@ -509,31 +515,25 @@ impl<'tcx> QueryDescription for queries::is_const_fn<'tcx> {
}
impl<'tcx> QueryDescription for queries::dylib_dependency_formats<'tcx> {
fn describe(_: TyCtxt, _: DefId) -> String {
fn describe(_: TyCtxt, _: CrateNum) -> String {
"dylib dependency formats of crate".to_string()
}
}
impl<'tcx> QueryDescription for queries::is_allocator<'tcx> {
fn describe(_: TyCtxt, _: DefId) -> String {
"checking if the crate is_allocator".to_string()
}
}
impl<'tcx> QueryDescription for queries::is_panic_runtime<'tcx> {
fn describe(_: TyCtxt, _: DefId) -> String {
fn describe(_: TyCtxt, _: CrateNum) -> String {
"checking if the crate is_panic_runtime".to_string()
}
}
impl<'tcx> QueryDescription for queries::is_compiler_builtins<'tcx> {
fn describe(_: TyCtxt, _: DefId) -> String {
fn describe(_: TyCtxt, _: CrateNum) -> String {
"checking if the crate is_compiler_builtins".to_string()
}
}
impl<'tcx> QueryDescription for queries::has_global_allocator<'tcx> {
fn describe(_: TyCtxt, _: DefId) -> String {
fn describe(_: TyCtxt, _: CrateNum) -> String {
"checking if the crate has_global_allocator".to_string()
}
}
@ -568,6 +568,198 @@ impl<'tcx> QueryDescription for queries::module_exports<'tcx> {
}
}
impl<'tcx> QueryDescription for queries::is_no_builtins<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("test whether a crate has #![no_builtins]")
}
}
impl<'tcx> QueryDescription for queries::panic_strategy<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("query a crate's configured panic strategy")
}
}
impl<'tcx> QueryDescription for queries::is_profiler_runtime<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("query a crate is #![profiler_runtime]")
}
}
impl<'tcx> QueryDescription for queries::is_sanitizer_runtime<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("query a crate is #![sanitizer_runtime]")
}
}
impl<'tcx> QueryDescription for queries::exported_symbols<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up the exported symbols of a crate")
}
}
impl<'tcx> QueryDescription for queries::native_libraries<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up the native libraries of a linked crate")
}
}
impl<'tcx> QueryDescription for queries::plugin_registrar_fn<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up the plugin registrar for a crate")
}
}
impl<'tcx> QueryDescription for queries::derive_registrar_fn<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up the derive registrar for a crate")
}
}
impl<'tcx> QueryDescription for queries::crate_disambiguator<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up the disambiguator a crate")
}
}
impl<'tcx> QueryDescription for queries::crate_hash<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up the hash a crate")
}
}
impl<'tcx> QueryDescription for queries::original_crate_name<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up the original name a crate")
}
}
impl<'tcx> QueryDescription for queries::implementations_of_trait<'tcx> {
fn describe(_tcx: TyCtxt, _: (CrateNum, DefId)) -> String {
format!("looking up implementations of a trait in a crate")
}
}
impl<'tcx> QueryDescription for queries::all_trait_implementations<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up all (?) trait implementations")
}
}
impl<'tcx> QueryDescription for queries::link_args<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up link arguments for a crate")
}
}
impl<'tcx> QueryDescription for queries::named_region<'tcx> {
fn describe(_tcx: TyCtxt, _: HirId) -> String {
format!("fetching info about a named region")
}
}
impl<'tcx> QueryDescription for queries::is_late_bound<'tcx> {
fn describe(_tcx: TyCtxt, _: HirId) -> String {
format!("testing whether a lifetime is late bound")
}
}
impl<'tcx> QueryDescription for queries::object_lifetime_defaults<'tcx> {
fn describe(_tcx: TyCtxt, _: HirId) -> String {
format!("fetching a list of ObjectLifetimeDefault for a lifetime")
}
}
impl<'tcx> QueryDescription for queries::dep_kind<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("fetching what a dependency looks like")
}
}
impl<'tcx> QueryDescription for queries::crate_name<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("fetching what a crate is named")
}
}
impl<'tcx> QueryDescription for queries::extern_mod_stmt_cnum<'tcx> {
fn describe(_tcx: TyCtxt, _: HirId) -> String {
format!("looking up the CrateNum for an `extern mod` statement")
}
}
impl<'tcx> QueryDescription for queries::get_lang_items<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("calculating the lang items map")
}
}
impl<'tcx> QueryDescription for queries::defined_lang_items<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("calculating the lang items defined in a crate")
}
}
impl<'tcx> QueryDescription for queries::missing_lang_items<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("calculating the missing lang items in a crate")
}
}
impl<'tcx> QueryDescription for queries::visible_parent_map<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("calculating the visible parent map")
}
}
impl<'tcx> QueryDescription for queries::missing_extern_crate_item<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("seeing if we're missing an `extern crate` item for this crate")
}
}
impl<'tcx> QueryDescription for queries::used_crate_source<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking at the source for a crate")
}
}
impl<'tcx> QueryDescription for queries::postorder_cnums<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("generating a postorder list of CrateNums")
}
}
impl<'tcx> QueryDescription for queries::freevars<'tcx> {
fn describe(_tcx: TyCtxt, _: HirId) -> String {
format!("looking up free variables for a node")
}
}
impl<'tcx> QueryDescription for queries::maybe_unused_trait_import<'tcx> {
fn describe(_tcx: TyCtxt, _: HirId) -> String {
format!("testing if a trait import is unused")
}
}
impl<'tcx> QueryDescription for queries::maybe_unused_extern_crates<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up all possibly unused extern crates")
}
}
impl<'tcx> QueryDescription for queries::stability_index<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("calculating the stability index for the local crate")
}
}
impl<'tcx> QueryDescription for queries::all_crate_nums<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("fetching all foreign CrateNum instances")
}
}
// If enabled, send a message to the profile-queries thread
macro_rules! profq_msg {
($tcx:expr, $msg:expr) => {
@ -1092,8 +1284,8 @@ define_maps! { <'tcx>
[] fn describe_def: DescribeDef(DefId) -> Option<Def>,
[] fn def_span: DefSpan(DefId) -> Span,
[] fn stability: Stability(DefId) -> Option<attr::Stability>,
[] fn deprecation: Deprecation(DefId) -> Option<attr::Deprecation>,
[] fn lookup_stability: LookupStability(DefId) -> Option<&'tcx attr::Stability>,
[] fn lookup_deprecation_entry: LookupDeprecationEntry(DefId) -> Option<DeprecationEntry>,
[] fn item_attrs: ItemAttrs(DefId) -> Rc<[ast::Attribute]>,
[] fn fn_arg_names: FnArgNames(DefId) -> Vec<ast::Name>,
[] fn impl_parent: ImplParent(DefId) -> Option<DefId>,
@ -1125,21 +1317,72 @@ define_maps! { <'tcx>
[] fn layout_raw: layout_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
-> Result<&'tcx Layout, LayoutError<'tcx>>,
[] fn dylib_dependency_formats: DylibDepFormats(DefId)
[] fn dylib_dependency_formats: DylibDepFormats(CrateNum)
-> Rc<Vec<(CrateNum, LinkagePreference)>>,
[] fn is_allocator: IsAllocator(DefId) -> bool,
[] fn is_panic_runtime: IsPanicRuntime(DefId) -> bool,
[] fn is_compiler_builtins: IsCompilerBuiltins(DefId) -> bool,
[] fn has_global_allocator: HasGlobalAllocator(DefId) -> bool,
[] fn is_panic_runtime: IsPanicRuntime(CrateNum) -> bool,
[] fn is_compiler_builtins: IsCompilerBuiltins(CrateNum) -> bool,
[] fn has_global_allocator: HasGlobalAllocator(CrateNum) -> bool,
[] fn is_sanitizer_runtime: IsSanitizerRuntime(CrateNum) -> bool,
[] fn is_profiler_runtime: IsProfilerRuntime(CrateNum) -> bool,
[] fn panic_strategy: GetPanicStrategy(CrateNum) -> PanicStrategy,
[] fn is_no_builtins: IsNoBuiltins(CrateNum) -> bool,
[] fn extern_crate: ExternCrate(DefId) -> Rc<Option<ExternCrate>>,
[] fn lint_levels: lint_levels(CrateNum) -> Rc<lint::LintLevelMap>,
[] fn specializes: specializes_node((DefId, DefId)) -> bool,
[] fn in_scope_traits: InScopeTraits(HirId) -> Option<Rc<Vec<TraitCandidate>>>,
[] fn module_exports: ModuleExports(HirId) -> Option<Rc<Vec<Export>>>,
[] fn lint_levels: lint_levels_node(CrateNum) -> Rc<lint::LintLevelMap>,
[] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness,
[] fn exported_symbols: ExportedSymbols(CrateNum) -> Rc<Vec<DefId>>,
[] fn native_libraries: NativeLibraries(CrateNum) -> Rc<Vec<NativeLibrary>>,
[] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
[] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option<DefId>,
[] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> Symbol,
[] fn crate_hash: CrateHash(CrateNum) -> Svh,
[] fn original_crate_name: OriginalCrateName(CrateNum) -> Symbol,
[] fn implementations_of_trait: implementations_of_trait_node((CrateNum, DefId))
-> Rc<Vec<DefId>>,
[] fn all_trait_implementations: AllTraitImplementations(CrateNum)
-> Rc<Vec<DefId>>,
[] fn is_dllimport_foreign_item: IsDllimportForeignItem(DefId) -> bool,
[] fn is_statically_included_foreign_item: IsStaticallyIncludedForeignItem(DefId) -> bool,
[] fn native_library_kind: NativeLibraryKind(DefId)
-> Option<NativeLibraryKind>,
[] fn link_args: link_args_node(CrateNum) -> Rc<Vec<String>>,
[] fn named_region: NamedRegion(HirId) -> Option<Region>,
[] fn is_late_bound: IsLateBound(HirId) -> bool,
[] fn object_lifetime_defaults: ObjectLifetimeDefaults(HirId)
-> Option<Rc<Vec<ObjectLifetimeDefault>>>,
[] fn visibility: Visibility(DefId) -> ty::Visibility,
[] fn dep_kind: DepKind(CrateNum) -> DepKind,
[] fn crate_name: CrateName(CrateNum) -> Symbol,
[] fn item_children: ItemChildren(DefId) -> Rc<Vec<Export>>,
[] fn extern_mod_stmt_cnum: ExternModStmtCnum(HirId) -> Option<CrateNum>,
[] fn get_lang_items: get_lang_items_node(CrateNum) -> Rc<LanguageItems>,
[] fn defined_lang_items: DefinedLangItems(CrateNum) -> Rc<Vec<(DefIndex, usize)>>,
[] fn missing_lang_items: MissingLangItems(CrateNum) -> Rc<Vec<LangItem>>,
[] fn extern_const_body: ExternConstBody(DefId) -> &'tcx hir::Body,
[] fn visible_parent_map: visible_parent_map_node(CrateNum)
-> Rc<DefIdMap<DefId>>,
[] fn missing_extern_crate_item: MissingExternCrateItem(CrateNum) -> bool,
[] fn used_crate_source: UsedCrateSource(CrateNum) -> Rc<CrateSource>,
[] fn postorder_cnums: postorder_cnums_node(CrateNum) -> Rc<Vec<CrateNum>>,
[] fn freevars: Freevars(HirId) -> Option<Rc<Vec<hir::Freevar>>>,
[] fn maybe_unused_trait_import: MaybeUnusedTraitImport(HirId) -> bool,
[] fn maybe_unused_extern_crates: maybe_unused_extern_crates_node(CrateNum)
-> Rc<Vec<(HirId, Span)>>,
[] fn stability_index: stability_index_node(CrateNum) -> Rc<stability::Index<'tcx>>,
[] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Rc<Vec<CrateNum>>,
}
fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
@ -1212,10 +1455,44 @@ fn layout_dep_node<'tcx>(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'
DepConstructor::Layout
}
fn lint_levels<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
fn lint_levels_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::LintLevels
}
fn specializes_node<'tcx>((a, b): (DefId, DefId)) -> DepConstructor<'tcx> {
DepConstructor::Specializes { impl1: a, impl2: b }
}
fn implementations_of_trait_node<'tcx>((krate, trait_id): (CrateNum, DefId))
-> DepConstructor<'tcx>
{
DepConstructor::ImplementationsOfTrait { krate, trait_id }
}
fn link_args_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::LinkArgs
}
fn get_lang_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::GetLangItems
}
fn visible_parent_map_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::VisibleParentMap
}
fn postorder_cnums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::PostorderCnums
}
fn maybe_unused_extern_crates_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::MaybeUnusedExternCrates
}
fn stability_index_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::StabilityIndex
}
fn all_crate_nums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::AllCrateNums
}

View File

@ -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]
};
@ -2206,11 +2206,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}
pub fn item_name(self, id: DefId) -> ast::Name {
pub fn item_name(self, id: DefId) -> InternedString {
if let Some(id) = self.hir.as_local_node_id(id) {
self.hir.name(id)
self.hir.name(id).as_str()
} else if id.index == CRATE_DEF_INDEX {
self.sess.cstore.original_crate_name(id.krate)
self.original_crate_name(id.krate).as_str()
} else {
let def_key = self.sess.cstore.def_key(id);
// The name of a StructCtor is that of its struct parent.
@ -2315,7 +2315,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
let node_id = self.hir.as_local_node_id(impl_did).unwrap();
Ok(self.hir.span(node_id))
} else {
Err(self.sess.cstore.crate_name(impl_did.krate))
Err(self.crate_name(impl_did.krate))
}
}
@ -2340,9 +2340,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn with_freevars<T, F>(self, fid: NodeId, f: F) -> T where
F: FnOnce(&[hir::Freevar]) -> T,
{
match self.freevars.borrow().get(&fid) {
let hir_id = self.hir.node_to_hir_id(fid);
match self.freevars(hir_id) {
None => f(&[]),
Some(d) => f(&d[..])
Some(d) => f(&d),
}
}
}
@ -2510,6 +2511,18 @@ fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
}
fn crate_disambiguator<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
crate_num: CrateNum) -> Symbol {
assert_eq!(crate_num, LOCAL_CRATE);
tcx.sess.local_crate_disambiguator()
}
fn original_crate_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
crate_num: CrateNum) -> Symbol {
assert_eq!(crate_num, LOCAL_CRATE);
tcx.crate_name.clone()
}
pub fn provide(providers: &mut ty::maps::Providers) {
util::provide(providers);
context::provide(providers);
@ -2521,6 +2534,8 @@ pub fn provide(providers: &mut ty::maps::Providers) {
def_span,
param_env,
trait_of_item,
crate_disambiguator,
original_crate_name,
trait_impls_of: trait_def::trait_impls_of_provider,
..*providers
};

View File

@ -141,13 +141,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
trait_id: DefId)
-> Rc<TraitImpls> {
let remote_impls = if trait_id.is_local() {
// Traits defined in the current crate can't have impls in upstream
// crates, so we don't bother querying the cstore.
Vec::new()
} else {
tcx.sess.cstore.implementations_of_trait(Some(trait_id))
};
let mut remote_impls = Vec::new();
// Traits defined in the current crate can't have impls in upstream
// crates, so we don't bother querying the cstore.
if !trait_id.is_local() {
for &cnum in tcx.crates().iter() {
let impls = tcx.implementations_of_trait((cnum, trait_id));
remote_impls.extend(impls.iter().cloned());
}
}
let mut blanket_impls = Vec::new();
let mut non_blanket_impls = FxHashMap();

View File

@ -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;

View File

@ -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;
}

View File

@ -327,7 +327,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
ConstEvalErr { span: e.span, kind: LayoutError(err) }
})
};
match &tcx.item_name(def_id).as_str()[..] {
match &tcx.item_name(def_id)[..] {
"size_of" => {
let size = layout_of(substs.type_at(0))?.size(tcx);
return Ok(Integral(Usize(ConstUsize::new(size.bytes(),
@ -354,7 +354,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
}
} else {
if tcx.is_const_fn(def_id) {
tcx.sess.cstore.item_body(tcx, def_id)
tcx.extern_const_body(def_id)
} else {
signal!(e, TypeckError)
}
@ -774,7 +774,7 @@ fn const_eval<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
tcx.mir_const_qualif(def_id);
tcx.hir.body(tcx.hir.body_owned_by(id))
} else {
tcx.sess.cstore.item_body(tcx, def_id)
tcx.extern_const_body(def_id)
};
ConstContext::new(tcx, key.param_env.and(substs), tables).eval(&body.value)
}

View File

@ -609,7 +609,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
let body = if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
self.tcx.hir.body(self.tcx.hir.body_owned_by(id))
} else {
self.tcx.sess.cstore.item_body(self.tcx, def_id)
self.tcx.extern_const_body(def_id)
};
let pat = self.lower_const_expr(&body.value, pat_id, span);
self.tables = old_tables;

View File

@ -694,7 +694,6 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
// this back at some point.
let _ignore = sess.dep_graph.in_ignore();
let mut crate_loader = CrateLoader::new(sess, &cstore, crate_name);
crate_loader.preprocess(&krate);
let resolver_arenas = Resolver::arenas();
let mut resolver = Resolver::new(sess,
&krate,
@ -914,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))?;
@ -941,8 +934,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
"static item recursion checking",
|| static_recursion::check_crate(sess, &hir_map))?;
let index = stability::Index::new(&sess);
let mut local_providers = ty::maps::Providers::default();
borrowck::provide(&mut local_providers);
mir::provide(&mut local_providers);
@ -1029,8 +1020,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| {
let incremental_hashes_map =
@ -1042,10 +1031,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
"load_dep_graph",
|| rustc_incremental::load_dep_graph(tcx, &incremental_hashes_map));
time(time_passes, "stability index", || {
tcx.stability.borrow_mut().build(tcx)
});
time(time_passes,
"stability checking",
|| stability::check_unstable_api_usage(tcx));

View File

@ -15,11 +15,9 @@ use rustc::dep_graph::DepGraph;
use rustc_lint;
use rustc_resolve::MakeGlobMap;
use rustc_trans;
use rustc::middle::lang_items;
use rustc::middle::free_region::FreeRegionMap;
use rustc::middle::region;
use rustc::middle::resolve_lifetime;
use rustc::middle::stability;
use rustc::ty::subst::{Kind, Subst};
use rustc::traits::{ObligationCause, Reveal};
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
@ -140,9 +138,7 @@ fn test_env<F>(source_string: &str,
let hir_map = hir_map::map_crate(&mut hir_forest, defs);
// run just enough stuff to build a tcx:
let lang_items = lang_items::collect_language_items(&sess, &hir_map);
let named_region_map = resolve_lifetime::krate(&sess, &hir_map);
let index = stability::Index::new(&sess);
TyCtxt::create_and_enter(&sess,
ty::maps::Providers::default(),
ty::maps::Providers::default(),
@ -152,8 +148,6 @@ fn test_env<F>(source_string: &str,
resolutions,
named_region_map.unwrap(),
hir_map,
lang_items,
index,
"test_crate",
|tcx| {
tcx.infer_ctxt().enter(|infcx| {

View File

@ -632,7 +632,7 @@ pub fn find_metadata_hashes_for(tcx: TyCtxt, cnum: CrateNum) -> Option<PathBuf>
}
};
let target_svh = tcx.sess.cstore.crate_hash(cnum);
let target_svh = tcx.crate_hash(cnum);
let target_svh = base_n::encode(target_svh.as_u64(), INT_ENCODE_BASE);
let sub_dir = find_metadata_hashes_iter(&target_svh, dir_entries.filter_map(|e| {

View File

@ -133,7 +133,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
fn load_data(&mut self, cnum: CrateNum) {
debug!("load_data(cnum={})", cnum);
let svh = self.tcx.sess.cstore.crate_hash(cnum);
let svh = self.tcx.crate_hash(cnum);
let old = self.crate_hashes.insert(cnum, svh);
debug!("load_data: svh={}", svh);
assert!(old.is_none(), "loaded data for crate {:?} twice", cnum);

View File

@ -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,
};
@ -1063,8 +1063,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PluginAsLibrary {
_ => return,
};
let prfn = match cx.sess().cstore.extern_mod_stmt_cnum(it.id) {
Some(cnum) => cx.sess().cstore.plugin_registrar_fn(cnum),
let hir_id = cx.tcx.hir.node_to_hir_id(it.id);
let prfn = match cx.tcx.extern_mod_stmt_cnum(hir_id) {
Some(cnum) => cx.tcx.plugin_registrar_fn(cnum),
None => {
// Probably means we aren't linking the crate for some reason.
//

View File

@ -12,6 +12,7 @@
use cstore::{self, CStore, CrateSource, MetadataBlob};
use locator::{self, CratePaths};
use native_libs::relevant_lib;
use schema::{CrateRoot, Tracked};
use rustc::hir::def_id::{CrateNum, DefIndex};
@ -23,10 +24,9 @@ use rustc::session::config::{Sanitizer, self};
use rustc_back::PanicStrategy;
use rustc::session::search_paths::PathKind;
use rustc::middle;
use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate};
use rustc::middle::cstore::{validate_crate_name, ExternCrate};
use rustc::util::common::record_time;
use rustc::util::nodemap::FxHashSet;
use rustc::middle::cstore::NativeLibrary;
use rustc::hir::map::Definitions;
use std::cell::{RefCell, Cell};
@ -36,10 +36,8 @@ use std::rc::Rc;
use std::{cmp, fs};
use syntax::ast;
use syntax::abi::Abi;
use syntax::attr;
use syntax::ext::base::SyntaxExtension;
use syntax::feature_gate::{self, GateIssue};
use syntax::symbol::Symbol;
use syntax::visit;
use syntax_pos::{Span, DUMMY_SP};
@ -81,56 +79,6 @@ struct ExternCrateInfo {
dep_kind: DepKind,
}
fn register_native_lib(sess: &Session,
cstore: &CStore,
span: Option<Span>,
lib: NativeLibrary) {
if lib.name.as_str().is_empty() {
match span {
Some(span) => {
struct_span_err!(sess, span, E0454,
"#[link(name = \"\")] given with empty name")
.span_label(span, "empty name given")
.emit();
}
None => {
sess.err("empty library name given via `-l`");
}
}
return
}
let is_osx = sess.target.target.options.is_like_osx;
if lib.kind == cstore::NativeFramework && !is_osx {
let msg = "native frameworks are only available on macOS targets";
match span {
Some(span) => span_err!(sess, span, E0455, "{}", msg),
None => sess.err(msg),
}
}
if lib.cfg.is_some() && !sess.features.borrow().link_cfg {
feature_gate::emit_feature_err(&sess.parse_sess,
"link_cfg",
span.unwrap(),
GateIssue::Language,
"is feature gated");
}
if lib.kind == cstore::NativeStaticNobundle && !sess.features.borrow().static_nobundle {
feature_gate::emit_feature_err(&sess.parse_sess,
"static_nobundle",
span.unwrap(),
GateIssue::Language,
"kind=\"static-nobundle\" is feature gated");
}
cstore.add_used_library(lib);
}
fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool {
match lib.cfg {
Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, None),
None => true,
}
}
// Extra info about a crate loaded for plugins or exported macros.
struct ExtensionCrate {
metadata: PMDSource,
@ -218,7 +166,7 @@ impl<'a> CrateLoader<'a> {
// We're also sure to compare *paths*, not actual byte slices. The
// `source` stores paths which are normalized which may be different
// from the strings on the command line.
let source = self.cstore.used_crate_source(cnum);
let source = &self.cstore.get_crate_data(cnum).source;
if let Some(locs) = self.sess.opts.externs.get(&*name.as_str()) {
let found = locs.iter().any(|l| {
let l = fs::canonicalize(l).ok();
@ -721,33 +669,6 @@ impl<'a> CrateLoader<'a> {
}
}
fn get_foreign_items_of_kind(&self, kind: cstore::NativeLibraryKind) -> Vec<DefIndex> {
let mut items = vec![];
let libs = self.cstore.get_used_libraries();
for lib in libs.borrow().iter() {
if relevant_lib(self.sess, lib) && lib.kind == kind {
items.extend(&lib.foreign_items);
}
}
items
}
fn register_statically_included_foreign_items(&mut self) {
for id in self.get_foreign_items_of_kind(cstore::NativeStatic) {
self.cstore.add_statically_included_foreign_item(id);
}
for id in self.get_foreign_items_of_kind(cstore::NativeStaticNobundle) {
self.cstore.add_statically_included_foreign_item(id);
}
}
fn register_dllimport_foreign_items(&mut self) {
let mut dllimports = self.cstore.dllimport_foreign_items.borrow_mut();
for id in self.get_foreign_items_of_kind(cstore::NativeUnknown) {
dllimports.insert(id);
}
}
fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
// If we're only compiling an rlib, then there's no need to select a
// panic runtime, so we just skip this section entirely.
@ -1152,84 +1073,6 @@ impl<'a> CrateLoader<'a> {
}
}
impl<'a> CrateLoader<'a> {
pub fn preprocess(&mut self, krate: &ast::Crate) {
for attr in &krate.attrs {
if attr.path == "link_args" {
if let Some(linkarg) = attr.value_str() {
self.cstore.add_used_link_args(&linkarg.as_str());
}
}
}
}
fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod,
definitions: &Definitions) {
if fm.abi == Abi::Rust || fm.abi == Abi::RustIntrinsic || fm.abi == Abi::PlatformIntrinsic {
return;
}
// First, add all of the custom #[link_args] attributes
for m in i.attrs.iter().filter(|a| a.check_name("link_args")) {
if let Some(linkarg) = m.value_str() {
self.cstore.add_used_link_args(&linkarg.as_str());
}
}
// Next, process all of the #[link(..)]-style arguments
for m in i.attrs.iter().filter(|a| a.check_name("link")) {
let items = match m.meta_item_list() {
Some(item) => item,
None => continue,
};
let kind = items.iter().find(|k| {
k.check_name("kind")
}).and_then(|a| a.value_str()).map(Symbol::as_str);
let kind = match kind.as_ref().map(|s| &s[..]) {
Some("static") => cstore::NativeStatic,
Some("static-nobundle") => cstore::NativeStaticNobundle,
Some("dylib") => cstore::NativeUnknown,
Some("framework") => cstore::NativeFramework,
Some(k) => {
struct_span_err!(self.sess, m.span, E0458,
"unknown kind: `{}`", k)
.span_label(m.span, "unknown kind").emit();
cstore::NativeUnknown
}
None => cstore::NativeUnknown
};
let n = items.iter().find(|n| {
n.check_name("name")
}).and_then(|a| a.value_str());
let n = match n {
Some(n) => n,
None => {
struct_span_err!(self.sess, m.span, E0459,
"#[link(...)] specified without `name = \"foo\"`")
.span_label(m.span, "missing `name` argument").emit();
Symbol::intern("foo")
}
};
let cfg = items.iter().find(|k| {
k.check_name("cfg")
}).and_then(|a| a.meta_item_list());
let cfg = cfg.map(|list| {
list[0].meta_item().unwrap().clone()
});
let foreign_items = fm.items.iter()
.map(|it| definitions.opt_def_index(it.id).unwrap())
.collect();
let lib = NativeLibrary {
name: n,
kind,
cfg,
foreign_items,
};
register_native_lib(self.sess, self.cstore, Some(m.span), lib);
}
}
}
impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
fn postprocess(&mut self, krate: &ast::Crate) {
// inject the sanitizer runtime before the allocator runtime because all
@ -1242,72 +1085,10 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
if log_enabled!(log::LogLevel::Info) {
dump_crates(&self.cstore);
}
// Process libs passed on the command line
// First, check for errors
let mut renames = FxHashSet();
for &(ref name, ref new_name, _) in &self.sess.opts.libs {
if let &Some(ref new_name) = new_name {
if new_name.is_empty() {
self.sess.err(
&format!("an empty renaming target was specified for library `{}`",name));
} else if !self.cstore.get_used_libraries().borrow().iter()
.any(|lib| lib.name == name as &str) {
self.sess.err(&format!("renaming of the library `{}` was specified, \
however this crate contains no #[link(...)] \
attributes referencing this library.", name));
} else if renames.contains(name) {
self.sess.err(&format!("multiple renamings were specified for library `{}` .",
name));
} else {
renames.insert(name);
}
}
}
// Update kind and, optionally, the name of all native libaries
// (there may be more than one) with the specified name.
for &(ref name, ref new_name, kind) in &self.sess.opts.libs {
let mut found = false;
for lib in self.cstore.get_used_libraries().borrow_mut().iter_mut() {
if lib.name == name as &str {
let mut changed = false;
if let Some(k) = kind {
lib.kind = k;
changed = true;
}
if let &Some(ref new_name) = new_name {
lib.name = Symbol::intern(new_name);
changed = true;
}
if !changed {
self.sess.warn(&format!("redundant linker flag specified for library `{}`",
name));
}
found = true;
}
}
if !found {
// Add if not found
let new_name = new_name.as_ref().map(|s| &**s); // &Option<String> -> Option<&str>
let lib = NativeLibrary {
name: Symbol::intern(new_name.unwrap_or(name)),
kind: if let Some(k) = kind { k } else { cstore::NativeUnknown },
cfg: None,
foreign_items: Vec::new(),
};
register_native_lib(self.sess, self.cstore, None, lib);
}
}
self.register_statically_included_foreign_items();
self.register_dllimport_foreign_items();
}
fn process_item(&mut self, item: &ast::Item, definitions: &Definitions) {
match item.node {
ast::ItemKind::ForeignMod(ref fm) => {
self.process_foreign_mod(item, fm, definitions)
},
ast::ItemKind::ExternCrate(_) => {
let info = self.extract_crate_info(item).unwrap();
let (cnum, ..) = self.resolve_crate(

View File

@ -14,13 +14,13 @@
use schema::{self, Tracked};
use rustc::dep_graph::DepGraph;
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefIndex, DefId};
use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex, DefId};
use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
use rustc::hir::svh::Svh;
use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
use rustc_back::PanicStrategy;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap, DefIdMap};
use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap};
use std::cell::{RefCell, Cell};
use std::rc::Rc;
@ -95,11 +95,6 @@ pub struct CStore {
metas: RefCell<FxHashMap<CrateNum, Rc<CrateMetadata>>>,
/// Map from NodeId's of local extern crate statements to crate numbers
extern_mod_crate_map: RefCell<NodeMap<CrateNum>>,
used_libraries: RefCell<Vec<NativeLibrary>>,
used_link_args: RefCell<Vec<String>>,
statically_included_foreign_items: RefCell<FxHashSet<DefIndex>>,
pub dllimport_foreign_items: RefCell<FxHashSet<DefIndex>>,
pub visible_parent_map: RefCell<DefIdMap<DefId>>,
pub metadata_loader: Box<MetadataLoader>,
}
@ -109,11 +104,6 @@ impl CStore {
dep_graph: dep_graph.clone(),
metas: RefCell::new(FxHashMap()),
extern_mod_crate_map: RefCell::new(FxHashMap()),
used_libraries: RefCell::new(Vec::new()),
used_link_args: RefCell::new(Vec::new()),
statically_included_foreign_items: RefCell::new(FxHashSet()),
dllimport_foreign_items: RefCell::new(FxHashSet()),
visible_parent_map: RefCell::new(FxHashMap()),
metadata_loader,
}
}
@ -126,10 +116,6 @@ impl CStore {
self.metas.borrow().get(&cnum).unwrap().clone()
}
pub fn get_crate_hash(&self, cnum: CrateNum) -> Svh {
self.get_crate_data(cnum).hash()
}
pub fn set_crate_data(&self, cnum: CrateNum, data: Rc<CrateMetadata>) {
self.metas.borrow_mut().insert(cnum, data);
}
@ -164,86 +150,18 @@ impl CStore {
ordering.push(krate);
}
// This method is used when generating the command line to pass through to
// system linker. The linker expects undefined symbols on the left of the
// command line to be defined in libraries on the right, not the other way
// around. For more info, see some comments in the add_used_library function
// below.
//
// In order to get this left-to-right dependency ordering, we perform a
// topological sort of all crates putting the leaves at the right-most
// positions.
pub fn do_get_used_crates(&self,
prefer: LinkagePreference)
-> Vec<(CrateNum, LibSource)> {
pub fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
let mut ordering = Vec::new();
for (&num, _) in self.metas.borrow().iter() {
self.push_dependencies_in_postorder(&mut ordering, num);
}
info!("topological ordering: {:?}", ordering);
ordering.reverse();
let mut libs = self.metas
.borrow()
.iter()
.filter_map(|(&cnum, data)| {
if data.dep_kind.get().macros_only() { return None; }
let path = match prefer {
LinkagePreference::RequireDynamic => data.source.dylib.clone().map(|p| p.0),
LinkagePreference::RequireStatic => data.source.rlib.clone().map(|p| p.0),
};
let path = match path {
Some(p) => LibSource::Some(p),
None => {
if data.source.rmeta.is_some() {
LibSource::MetadataOnly
} else {
LibSource::None
}
}
};
Some((cnum, path))
})
.collect::<Vec<_>>();
libs.sort_by(|&(a, _), &(b, _)| {
let a = ordering.iter().position(|x| *x == a);
let b = ordering.iter().position(|x| *x == b);
a.cmp(&b)
});
libs
}
pub fn add_used_library(&self, lib: NativeLibrary) {
assert!(!lib.name.as_str().is_empty());
self.used_libraries.borrow_mut().push(lib);
}
pub fn get_used_libraries(&self) -> &RefCell<Vec<NativeLibrary>> {
&self.used_libraries
}
pub fn add_used_link_args(&self, args: &str) {
for s in args.split(' ').filter(|s| !s.is_empty()) {
self.used_link_args.borrow_mut().push(s.to_string());
}
}
pub fn get_used_link_args<'a>(&'a self) -> &'a RefCell<Vec<String>> {
&self.used_link_args
return ordering
}
pub fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) {
self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum);
}
pub fn add_statically_included_foreign_item(&self, id: DefIndex) {
self.statically_included_foreign_items.borrow_mut().insert(id);
}
pub fn do_is_statically_included_foreign_item(&self, def_id: DefId) -> bool {
assert!(def_id.krate == LOCAL_CRATE);
self.statically_included_foreign_items.borrow().contains(&def_id.index)
}
pub fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
}

View File

@ -10,24 +10,25 @@
use cstore;
use encoder;
use link_args;
use native_libs;
use schema;
use rustc::ty::maps::QueryConfig;
use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind,
NativeLibrary, MetadataLoader, LinkMeta,
LinkagePreference, LoadedMacro, EncodedMetadata,
EncodedMetadataHashes};
use rustc::middle::cstore::{CrateStore, DepKind,
MetadataLoader, LinkMeta,
LoadedMacro, EncodedMetadata,
EncodedMetadataHashes, NativeLibraryKind};
use rustc::middle::stability::DeprecationEntry;
use rustc::hir::def;
use rustc::middle::lang_items;
use rustc::session::Session;
use rustc::ty::{self, TyCtxt};
use rustc::ty::maps::Providers;
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX};
use rustc::hir::map::{DefKey, DefPath, DefPathHash};
use rustc::hir::map::blocks::FnLikeNode;
use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
use rustc::util::nodemap::{NodeSet, DefIdMap};
use rustc_back::PanicStrategy;
use std::any::Any;
use std::rc::Rc;
@ -39,15 +40,19 @@ use syntax::parse::filemap_to_stream;
use syntax::symbol::Symbol;
use syntax_pos::{Span, NO_EXPANSION};
use rustc_data_structures::indexed_set::IdxSetBuf;
use rustc::hir::svh::Svh;
use rustc::hir;
macro_rules! provide {
(<$lt:tt> $tcx:ident, $def_id:ident, $cdata:ident, $($name:ident => $compute:block)*) => {
(<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
$($name:ident => $compute:block)*) => {
pub fn provide<$lt>(providers: &mut Providers<$lt>) {
$(fn $name<'a, $lt:$lt>($tcx: TyCtxt<'a, $lt, $lt>, $def_id: DefId)
$(fn $name<'a, $lt:$lt, T>($tcx: TyCtxt<'a, $lt, $lt>, def_id_arg: T)
-> <ty::queries::$name<$lt> as
QueryConfig>::Value {
QueryConfig>::Value
where T: IntoArgs,
{
#[allow(unused_variables)]
let ($def_id, $other) = def_id_arg.into_args();
assert!(!$def_id.is_local());
let def_path_hash = $tcx.def_path_hash($def_id);
@ -69,7 +74,25 @@ macro_rules! provide {
}
}
provide! { <'tcx> tcx, def_id, cdata,
// small trait to work around different signature queries all being defined via
// the macro above.
trait IntoArgs {
fn into_args(self) -> (DefId, DefId);
}
impl IntoArgs for DefId {
fn into_args(self) -> (DefId, DefId) { (self, self) }
}
impl IntoArgs for CrateNum {
fn into_args(self) -> (DefId, DefId) { (self.as_def_id(), self.as_def_id()) }
}
impl IntoArgs for (CrateNum, DefId) {
fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) }
}
provide! { <'tcx> tcx, def_id, other, cdata,
type_of => { cdata.get_type(def_id.index, tcx) }
generics_of => { tcx.alloc_generics(cdata.get_generics(def_id.index)) }
predicates_of => { cdata.get_predicates(def_id.index, tcx) }
@ -119,8 +142,12 @@ provide! { <'tcx> tcx, def_id, cdata,
is_default_impl => { cdata.is_default_impl(def_id.index) }
describe_def => { cdata.get_def(def_id.index) }
def_span => { cdata.get_span(def_id.index, &tcx.sess) }
stability => { cdata.get_stability(def_id.index) }
deprecation => { cdata.get_deprecation(def_id.index) }
lookup_stability => {
cdata.get_stability(def_id.index).map(|s| tcx.intern_stability(s))
}
lookup_deprecation_entry => {
cdata.get_deprecation(def_id.index).map(DeprecationEntry::external)
}
item_attrs => { cdata.get_item_attrs(def_id.index, &tcx.dep_graph) }
// FIXME(#38501) We've skipped a `read` on the `HirBody` of
// a `fn` when encoding, so the dep-tracking wouldn't work.
@ -143,7 +170,68 @@ provide! { <'tcx> tcx, def_id, cdata,
is_panic_runtime => { cdata.is_panic_runtime(&tcx.dep_graph) }
is_compiler_builtins => { cdata.is_compiler_builtins(&tcx.dep_graph) }
has_global_allocator => { cdata.has_global_allocator(&tcx.dep_graph) }
is_sanitizer_runtime => { cdata.is_sanitizer_runtime(&tcx.dep_graph) }
is_profiler_runtime => { cdata.is_profiler_runtime(&tcx.dep_graph) }
panic_strategy => { cdata.panic_strategy(&tcx.dep_graph) }
extern_crate => { Rc::new(cdata.extern_crate.get()) }
is_no_builtins => { cdata.is_no_builtins(&tcx.dep_graph) }
impl_defaultness => { cdata.get_impl_defaultness(def_id.index) }
exported_symbols => { Rc::new(cdata.get_exported_symbols(&tcx.dep_graph)) }
native_libraries => { Rc::new(cdata.get_native_libraries(&tcx.dep_graph)) }
plugin_registrar_fn => {
cdata.root.plugin_registrar_fn.map(|index| {
DefId { krate: def_id.krate, index }
})
}
derive_registrar_fn => {
cdata.root.macro_derive_registrar.map(|index| {
DefId { krate: def_id.krate, index }
})
}
crate_disambiguator => { cdata.disambiguator() }
crate_hash => { cdata.hash() }
original_crate_name => { cdata.name() }
implementations_of_trait => {
let mut result = vec![];
let filter = Some(other);
cdata.get_implementations_for_trait(filter, &tcx.dep_graph, &mut result);
Rc::new(result)
}
all_trait_implementations => {
let mut result = vec![];
cdata.get_implementations_for_trait(None, &tcx.dep_graph, &mut result);
Rc::new(result)
}
is_dllimport_foreign_item => {
cdata.is_dllimport_foreign_item(def_id.index, &tcx.dep_graph)
}
visibility => { cdata.get_visibility(def_id.index) }
dep_kind => { cdata.dep_kind.get() }
crate_name => { cdata.name }
item_children => {
let mut result = vec![];
cdata.each_child_of_item(def_id.index, |child| result.push(child), tcx.sess);
Rc::new(result)
}
defined_lang_items => { Rc::new(cdata.get_lang_items(&tcx.dep_graph)) }
missing_lang_items => { Rc::new(cdata.get_missing_lang_items(&tcx.dep_graph)) }
extern_const_body => {
debug!("item_body({:?}): inlining item", def_id);
cdata.extern_const_body(tcx, def_id.index)
}
missing_extern_crate_item => {
match cdata.extern_crate.get() {
Some(extern_crate) if !extern_crate.direct => true,
_ => false,
}
}
used_crate_source => { Rc::new(cdata.source.clone()) }
}
pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
@ -158,8 +246,108 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
}
}
// FIXME(#44234) - almost all of these queries have no sub-queries and
// therefore no actual inputs, they're just reading tables calculated in
// resolve! Does this work? Unsure! That's what the issue is about
*providers = Providers {
is_const_fn,
is_dllimport_foreign_item: |tcx, id| {
tcx.native_library_kind(id) == Some(NativeLibraryKind::NativeUnknown)
},
is_statically_included_foreign_item: |tcx, id| {
match tcx.native_library_kind(id) {
Some(NativeLibraryKind::NativeStatic) |
Some(NativeLibraryKind::NativeStaticNobundle) => true,
_ => false,
}
},
native_library_kind: |tcx, id| {
tcx.native_libraries(id.krate)
.iter()
.filter(|lib| native_libs::relevant_lib(&tcx.sess, lib))
.find(|l| l.foreign_items.contains(&id.index))
.map(|l| l.kind)
},
native_libraries: |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
Rc::new(native_libs::collect(tcx))
},
link_args: |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
Rc::new(link_args::collect(tcx))
},
extern_mod_stmt_cnum: |tcx, id| {
let id = tcx.hir.definitions().find_node_for_hir_id(id);
tcx.sess.cstore.extern_mod_stmt_cnum_untracked(id)
},
all_crate_nums: |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
Rc::new(tcx.sess.cstore.crates_untracked())
},
// Returns a map from a sufficiently visible external item (i.e. an
// external item that is visible from at least one local module) to a
// sufficiently visible parent (considering modules that re-export the
// external item to be parents).
visible_parent_map: |tcx, cnum| {
use std::collections::vec_deque::VecDeque;
use std::collections::hash_map::Entry;
assert_eq!(cnum, LOCAL_CRATE);
let mut visible_parent_map: DefIdMap<DefId> = DefIdMap();
for &cnum in tcx.crates().iter() {
// Ignore crates without a corresponding local `extern crate` item.
if tcx.missing_extern_crate_item(cnum) {
continue
}
let bfs_queue = &mut VecDeque::new();
let visible_parent_map = &mut visible_parent_map;
let mut add_child = |bfs_queue: &mut VecDeque<_>,
child: &def::Export,
parent: DefId| {
let child = child.def.def_id();
if tcx.visibility(child) != ty::Visibility::Public {
return;
}
match visible_parent_map.entry(child) {
Entry::Occupied(mut entry) => {
// If `child` is defined in crate `cnum`, ensure
// that it is mapped to a parent in `cnum`.
if child.krate == cnum && entry.get().krate != cnum {
entry.insert(parent);
}
}
Entry::Vacant(entry) => {
entry.insert(parent);
bfs_queue.push_back(child);
}
}
};
bfs_queue.push_back(DefId {
krate: cnum,
index: CRATE_DEF_INDEX
});
while let Some(def) = bfs_queue.pop_front() {
for child in tcx.item_children(def).iter() {
add_child(bfs_queue, child, def);
}
}
}
Rc::new(visible_parent_map)
},
postorder_cnums: |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
Rc::new(tcx.sess.cstore.postorder_cnums_untracked())
},
..*providers
};
}
@ -173,53 +361,23 @@ impl CrateStore for cstore::CStore {
&*self.metadata_loader
}
fn visibility(&self, def: DefId) -> ty::Visibility {
fn visibility_untracked(&self, def: DefId) -> ty::Visibility {
self.read_dep_node(def);
self.get_crate_data(def.krate).get_visibility(def.index)
}
fn item_generics_cloned(&self, def: DefId) -> ty::Generics {
fn item_generics_cloned_untracked(&self, def: DefId) -> ty::Generics {
self.read_dep_node(def);
self.get_crate_data(def.krate).get_generics(def.index)
}
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>
{
let mut result = vec![];
self.iter_crate_data(|_, cdata| {
cdata.get_implementations_for_trait(filter, &self.dep_graph, &mut result)
});
result
}
fn impl_defaultness(&self, def: DefId) -> hir::Defaultness
{
self.read_dep_node(def);
self.get_crate_data(def.krate).get_impl_defaultness(def.index)
}
fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem
fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssociatedItem
{
self.read_dep_node(def);
self.get_crate_data(def.krate).get_associated_item(def.index)
}
fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool
{
self.do_is_statically_included_foreign_item(def_id)
}
fn is_dllimport_foreign_item(&self, def_id: DefId) -> bool {
if def_id.krate == LOCAL_CRATE {
self.dllimport_foreign_items.borrow().contains(&def_id.index)
} else {
self.get_crate_data(def_id.krate)
.is_dllimport_foreign_item(def_id.index, &self.dep_graph)
}
}
fn dep_kind(&self, cnum: CrateNum) -> DepKind
fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind
{
let data = self.get_crate_data(cnum);
let dep_node = data.metadata_dep_node(GlobalMetaDataKind::CrateDeps);
@ -227,7 +385,7 @@ impl CrateStore for cstore::CStore {
data.dep_kind.get()
}
fn export_macros(&self, cnum: CrateNum) {
fn export_macros_untracked(&self, cnum: CrateNum) {
let data = self.get_crate_data(cnum);
let dep_node = data.metadata_dep_node(GlobalMetaDataKind::CrateDeps);
@ -237,83 +395,11 @@ impl CrateStore for cstore::CStore {
}
}
fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>
{
self.get_crate_data(cnum).get_lang_items(&self.dep_graph)
}
fn missing_lang_items(&self, cnum: CrateNum)
-> Vec<lang_items::LangItem>
{
self.get_crate_data(cnum).get_missing_lang_items(&self.dep_graph)
}
fn is_compiler_builtins(&self, cnum: CrateNum) -> bool {
self.get_crate_data(cnum).is_compiler_builtins(&self.dep_graph)
}
fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool {
self.get_crate_data(cnum).is_sanitizer_runtime(&self.dep_graph)
}
fn is_profiler_runtime(&self, cnum: CrateNum) -> bool {
self.get_crate_data(cnum).is_profiler_runtime(&self.dep_graph)
}
fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy {
self.get_crate_data(cnum).panic_strategy(&self.dep_graph)
}
fn crate_name(&self, cnum: CrateNum) -> Symbol
fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol
{
self.get_crate_data(cnum).name
}
fn original_crate_name(&self, cnum: CrateNum) -> Symbol
{
self.get_crate_data(cnum).name()
}
fn crate_hash(&self, cnum: CrateNum) -> Svh
{
self.get_crate_hash(cnum)
}
fn crate_disambiguator(&self, cnum: CrateNum) -> Symbol
{
self.get_crate_data(cnum).disambiguator()
}
fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
{
self.get_crate_data(cnum).root.plugin_registrar_fn.map(|index| DefId {
krate: cnum,
index,
})
}
fn derive_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
{
self.get_crate_data(cnum).root.macro_derive_registrar.map(|index| DefId {
krate: cnum,
index,
})
}
fn native_libraries(&self, cnum: CrateNum) -> Vec<NativeLibrary>
{
self.get_crate_data(cnum).get_native_libraries(&self.dep_graph)
}
fn exported_symbols(&self, cnum: CrateNum) -> Vec<DefId>
{
self.get_crate_data(cnum).get_exported_symbols(&self.dep_graph)
}
fn is_no_builtins(&self, cnum: CrateNum) -> bool {
self.get_crate_data(cnum).is_no_builtins(&self.dep_graph)
}
/// Returns the `DefKey` for a given `DefId`. This indicates the
/// parent `DefId` as well as some idea of what kind of data the
/// `DefId` refers to.
@ -343,13 +429,13 @@ impl CrateStore for cstore::CStore {
self.get_crate_data(cnum).def_path_table.clone()
}
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>
fn struct_field_names_untracked(&self, def: DefId) -> Vec<ast::Name>
{
self.read_dep_node(def);
self.get_crate_data(def.krate).get_struct_field_names(def.index)
}
fn item_children(&self, def_id: DefId, sess: &Session) -> Vec<def::Export>
fn item_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec<def::Export>
{
self.read_dep_node(def_id);
let mut result = vec![];
@ -358,7 +444,7 @@ impl CrateStore for cstore::CStore {
result
}
fn load_macro(&self, id: DefId, sess: &Session) -> LoadedMacro {
fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
let data = self.get_crate_data(id.krate);
if let Some(ref proc_macros) = data.proc_macros {
return LoadedMacro::ProcMacro(proc_macros[id.index.as_usize() - 1].1.clone());
@ -387,7 +473,7 @@ impl CrateStore for cstore::CStore {
.insert(local_span, (name.to_string(), data.get_span(id.index, sess)));
LoadedMacro::MacroDef(ast::Item {
ident: ast::Ident::with_empty_ctxt(name),
ident: ast::Ident::from_str(&name),
id: ast::DUMMY_NODE_ID,
span: local_span,
attrs: attrs.iter().cloned().collect(),
@ -400,52 +486,22 @@ impl CrateStore for cstore::CStore {
})
}
fn item_body<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> &'tcx hir::Body {
self.read_dep_node(def_id);
if let Some(cached) = tcx.hir.get_inlined_body_untracked(def_id) {
return cached;
}
debug!("item_body({:?}): inlining item", def_id);
self.get_crate_data(def_id.krate).item_body(tcx, def_id.index)
}
fn crates(&self) -> Vec<CrateNum>
fn crates_untracked(&self) -> Vec<CrateNum>
{
let mut result = vec![];
self.iter_crate_data(|cnum, _| result.push(cnum));
result
}
fn used_libraries(&self) -> Vec<NativeLibrary>
{
self.get_used_libraries().borrow().clone()
}
fn used_link_args(&self) -> Vec<String>
{
self.get_used_link_args().borrow().clone()
}
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
{
self.do_get_used_crates(prefer)
}
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource
{
self.get_crate_data(cnum).source.clone()
}
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>
fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option<CrateNum>
{
self.do_extern_mod_stmt_cnum(emod_id)
}
fn postorder_cnums_untracked(&self) -> Vec<CrateNum> {
self.do_postorder_cnums_untracked()
}
fn encode_metadata<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta,
@ -459,67 +515,4 @@ impl CrateStore for cstore::CStore {
{
schema::METADATA_HEADER
}
/// Returns a map from a sufficiently visible external item (i.e. an external item that is
/// visible from at least one local module) to a sufficiently visible parent (considering
/// modules that re-export the external item to be parents).
fn visible_parent_map<'a>(&'a self, sess: &Session) -> ::std::cell::Ref<'a, DefIdMap<DefId>> {
{
let visible_parent_map = self.visible_parent_map.borrow();
if !visible_parent_map.is_empty() {
return visible_parent_map;
}
}
use std::collections::vec_deque::VecDeque;
use std::collections::hash_map::Entry;
let mut visible_parent_map = self.visible_parent_map.borrow_mut();
for cnum in (1 .. self.next_crate_num().as_usize()).map(CrateNum::new) {
let cdata = self.get_crate_data(cnum);
match cdata.extern_crate.get() {
// Ignore crates without a corresponding local `extern crate` item.
Some(extern_crate) if !extern_crate.direct => continue,
_ => {},
}
let bfs_queue = &mut VecDeque::new();
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| {
let child = child.def.def_id();
if self.visibility(child) != ty::Visibility::Public {
return;
}
match visible_parent_map.entry(child) {
Entry::Occupied(mut entry) => {
// If `child` is defined in crate `cnum`, ensure
// that it is mapped to a parent in `cnum`.
if child.krate == cnum && entry.get().krate != cnum {
entry.insert(parent);
}
}
Entry::Vacant(entry) => {
entry.insert(parent);
bfs_queue.push_back(child);
}
}
};
bfs_queue.push_back(DefId {
krate: cnum,
index: CRATE_DEF_INDEX
});
while let Some(def) = bfs_queue.pop_front() {
for child in self.item_children(def, sess) {
add_child(bfs_queue, child, def);
}
}
}
drop(visible_parent_map);
self.visible_parent_map.borrow()
}
}

View File

@ -41,6 +41,7 @@ use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque};
use syntax::attr;
use syntax::ast::{self, Ident};
use syntax::codemap;
use syntax::symbol::{InternedString, Symbol};
use syntax::ext::base::MacroKind;
use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION};
@ -473,7 +474,7 @@ impl<'a, 'tcx> CrateMetadata {
}
}
pub fn item_name(&self, item_index: DefIndex) -> ast::Name {
pub fn item_name(&self, item_index: DefIndex) -> InternedString {
self.def_key(item_index)
.disambiguated_data
.data
@ -520,12 +521,12 @@ impl<'a, 'tcx> CrateMetadata {
ty::VariantDef {
did: self.local_def_id(data.struct_ctor.unwrap_or(index)),
name: self.item_name(index),
name: Symbol::intern(&self.item_name(index)),
fields: item.children.decode(self).map(|index| {
let f = self.entry(index);
ty::FieldDef {
did: self.local_def_id(index),
name: self.item_name(index),
name: Symbol::intern(&self.item_name(index)),
vis: f.visibility.decode(self)
}
}).collect(),
@ -705,7 +706,7 @@ impl<'a, 'tcx> CrateMetadata {
if let Some(def) = self.get_def(child_index) {
callback(def::Export {
def,
ident: Ident::with_empty_ctxt(self.item_name(child_index)),
ident: Ident::from_str(&self.item_name(child_index)),
span: self.entry(child_index).span.decode((self, sess)),
});
}
@ -722,7 +723,7 @@ impl<'a, 'tcx> CrateMetadata {
let span = child.span.decode((self, sess));
if let (Some(def), Some(name)) =
(self.get_def(child_index), def_key.disambiguated_data.data.get_opt_name()) {
let ident = Ident::with_empty_ctxt(name);
let ident = Ident::from_str(&name);
callback(def::Export { def: def, ident: ident, span: span });
// For non-reexport structs and variants add their constructors to children.
// Reexport lists automatically contain constructors when necessary.
@ -759,10 +760,10 @@ impl<'a, 'tcx> CrateMetadata {
}
}
pub fn item_body(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
id: DefIndex)
-> &'tcx hir::Body {
pub fn extern_const_body(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
id: DefIndex)
-> &'tcx hir::Body {
assert!(!self.is_proc_macro(id));
let ast = self.entry(id).ast.unwrap();
let def_id = self.local_def_id(id);
@ -836,7 +837,7 @@ impl<'a, 'tcx> CrateMetadata {
};
ty::AssociatedItem {
name,
name: Symbol::intern(&name),
kind,
vis: item.visibility.decode(self),
defaultness: container.defaultness(),
@ -906,7 +907,7 @@ impl<'a, 'tcx> CrateMetadata {
self.entry(id)
.children
.decode(self)
.map(|index| self.item_name(index))
.map(|index| Symbol::intern(&self.item_name(index)))
.collect()
}
@ -1038,7 +1039,7 @@ impl<'a, 'tcx> CrateMetadata {
.collect()
}
pub fn get_macro(&self, id: DefIndex) -> (ast::Name, MacroDef) {
pub fn get_macro(&self, id: DefIndex) -> (InternedString, MacroDef) {
let entry = self.entry(id);
match entry.kind {
EntryKind::MacroDef(macro_def) => (self.item_name(id), macro_def.decode(self)),

View File

@ -14,7 +14,7 @@ register_long_diagnostics! {
E0454: r##"
A link name was given with an empty name. Erroneous code example:
```compile_fail,E0454
```ignore (cannot-test-this-because-rustdoc-stops-compile-fail-before-trans)
#[link(name = "")] extern {} // error: #[link(name = "")] given with empty name
```
@ -51,7 +51,7 @@ https://doc.rust-lang.org/book/first-edition/conditional-compilation.html
E0458: r##"
An unknown "kind" was specified for a link attribute. Erroneous code example:
```compile_fail,E0458
```ignore (cannot-test-this-because-rustdoc-stops-compile-fail-before-trans)
#[link(kind = "wonderful_unicorn")] extern {}
// error: unknown kind: `wonderful_unicorn`
```
@ -67,7 +67,7 @@ Please specify a valid "kind" value, from one of the following:
E0459: r##"
A link was used without a name parameter. Erroneous code example:
```compile_fail,E0459
```ignore (cannot-test-this-because-rustdoc-stops-compile-fail-before-trans)
#[link(kind = "dylib")] extern {}
// error: #[link(...)] specified without `name = "foo"`
```

View File

@ -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
@ -1283,21 +1283,20 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
}
fn encode_native_libraries(&mut self, _: ()) -> LazySeq<NativeLibrary> {
let used_libraries = self.tcx.sess.cstore.used_libraries();
self.lazy_seq(used_libraries)
let used_libraries = self.tcx.native_libraries(LOCAL_CRATE);
self.lazy_seq(used_libraries.iter().cloned())
}
fn encode_crate_deps(&mut self, _: ()) -> LazySeq<CrateDep> {
let cstore = &*self.tcx.sess.cstore;
let crates = cstore.crates();
let crates = self.tcx.crates();
let mut deps = crates
.iter()
.map(|&cnum| {
let dep = CrateDep {
name: cstore.original_crate_name(cnum),
hash: cstore.crate_hash(cnum),
kind: cstore.dep_kind(cnum),
name: self.tcx.original_crate_name(cnum),
hash: self.tcx.crate_hash(cnum),
kind: self.tcx.dep_kind(cnum),
};
(cnum, dep)
})
@ -1323,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() {
@ -1336,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.

View File

@ -50,6 +50,8 @@ mod decoder;
mod cstore_impl;
mod isolated_encoder;
mod schema;
mod native_libs;
mod link_args;
pub mod creader;
pub mod cstore;

View File

@ -0,0 +1,65 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir;
use rustc::ty::TyCtxt;
use syntax::abi::Abi;
pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec<String> {
let mut collector = Collector {
args: Vec::new(),
};
tcx.hir.krate().visit_all_item_likes(&mut collector);
for attr in tcx.hir.krate().attrs.iter() {
if attr.path == "link_args" {
if let Some(linkarg) = attr.value_str() {
collector.add_link_args(&linkarg.as_str());
}
}
}
return collector.args
}
struct Collector {
args: Vec<String>,
}
impl<'tcx> ItemLikeVisitor<'tcx> for Collector {
fn visit_item(&mut self, it: &'tcx hir::Item) {
let fm = match it.node {
hir::ItemForeignMod(ref fm) => fm,
_ => return,
};
if fm.abi == Abi::Rust ||
fm.abi == Abi::RustIntrinsic ||
fm.abi == Abi::PlatformIntrinsic {
return
}
// First, add all of the custom #[link_args] attributes
for m in it.attrs.iter().filter(|a| a.check_name("link_args")) {
if let Some(linkarg) = m.value_str() {
self.add_link_args(&linkarg.as_str());
}
}
}
fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem) {}
fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem) {}
}
impl Collector {
fn add_link_args(&mut self, args: &str) {
self.args.extend(args.split(' ').filter(|s| !s.is_empty()).map(|s| s.to_string()))
}
}

View File

@ -0,0 +1,217 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir;
use rustc::middle::cstore::{self, NativeLibrary};
use rustc::session::Session;
use rustc::ty::TyCtxt;
use rustc::util::nodemap::FxHashSet;
use syntax::abi::Abi;
use syntax::attr;
use syntax::codemap::Span;
use syntax::feature_gate::{self, GateIssue};
use syntax::symbol::Symbol;
pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec<NativeLibrary> {
let mut collector = Collector {
tcx,
libs: Vec::new(),
};
tcx.hir.krate().visit_all_item_likes(&mut collector);
collector.process_command_line();
return collector.libs
}
pub fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool {
match lib.cfg {
Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, None),
None => true,
}
}
struct Collector<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
libs: Vec<NativeLibrary>,
}
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> {
fn visit_item(&mut self, it: &'tcx hir::Item) {
let fm = match it.node {
hir::ItemForeignMod(ref fm) => fm,
_ => return,
};
if fm.abi == Abi::Rust ||
fm.abi == Abi::RustIntrinsic ||
fm.abi == Abi::PlatformIntrinsic {
return
}
// Process all of the #[link(..)]-style arguments
for m in it.attrs.iter().filter(|a| a.check_name("link")) {
let items = match m.meta_item_list() {
Some(item) => item,
None => continue,
};
let kind = items.iter().find(|k| {
k.check_name("kind")
}).and_then(|a| a.value_str()).map(Symbol::as_str);
let kind = match kind.as_ref().map(|s| &s[..]) {
Some("static") => cstore::NativeStatic,
Some("static-nobundle") => cstore::NativeStaticNobundle,
Some("dylib") => cstore::NativeUnknown,
Some("framework") => cstore::NativeFramework,
Some(k) => {
struct_span_err!(self.tcx.sess, m.span, E0458,
"unknown kind: `{}`", k)
.span_label(m.span, "unknown kind").emit();
cstore::NativeUnknown
}
None => cstore::NativeUnknown
};
let n = items.iter().find(|n| {
n.check_name("name")
}).and_then(|a| a.value_str());
let n = match n {
Some(n) => n,
None => {
struct_span_err!(self.tcx.sess, m.span, E0459,
"#[link(...)] specified without `name = \"foo\"`")
.span_label(m.span, "missing `name` argument").emit();
Symbol::intern("foo")
}
};
let cfg = items.iter().find(|k| {
k.check_name("cfg")
}).and_then(|a| a.meta_item_list());
let cfg = cfg.map(|list| {
list[0].meta_item().unwrap().clone()
});
let foreign_items = fm.items.iter()
.map(|it| self.tcx.hir.local_def_id(it.id).index)
.collect();
let lib = NativeLibrary {
name: n,
kind,
cfg,
foreign_items,
};
self.register_native_lib(Some(m.span), lib);
}
}
fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem) {}
fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem) {}
}
impl<'a, 'tcx> Collector<'a, 'tcx> {
fn register_native_lib(&mut self, span: Option<Span>, lib: NativeLibrary) {
if lib.name.as_str().is_empty() {
match span {
Some(span) => {
struct_span_err!(self.tcx.sess, span, E0454,
"#[link(name = \"\")] given with empty name")
.span_label(span, "empty name given")
.emit();
}
None => {
self.tcx.sess.err("empty library name given via `-l`");
}
}
return
}
let is_osx = self.tcx.sess.target.target.options.is_like_osx;
if lib.kind == cstore::NativeFramework && !is_osx {
let msg = "native frameworks are only available on macOS targets";
match span {
Some(span) => span_err!(self.tcx.sess, span, E0455, "{}", msg),
None => self.tcx.sess.err(msg),
}
}
if lib.cfg.is_some() && !self.tcx.sess.features.borrow().link_cfg {
feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
"link_cfg",
span.unwrap(),
GateIssue::Language,
"is feature gated");
}
if lib.kind == cstore::NativeStaticNobundle &&
!self.tcx.sess.features.borrow().static_nobundle {
feature_gate::emit_feature_err(&self.tcx.sess.parse_sess,
"static_nobundle",
span.unwrap(),
GateIssue::Language,
"kind=\"static-nobundle\" is feature gated");
}
self.libs.push(lib);
}
// Process libs passed on the command line
fn process_command_line(&mut self) {
// First, check for errors
let mut renames = FxHashSet();
for &(ref name, ref new_name, _) in &self.tcx.sess.opts.libs {
if let &Some(ref new_name) = new_name {
if new_name.is_empty() {
self.tcx.sess.err(
&format!("an empty renaming target was specified for library `{}`",name));
} else if !self.libs.iter().any(|lib| lib.name == name as &str) {
self.tcx.sess.err(&format!("renaming of the library `{}` was specified, \
however this crate contains no #[link(...)] \
attributes referencing this library.", name));
} else if renames.contains(name) {
self.tcx.sess.err(&format!("multiple renamings were \
specified for library `{}` .",
name));
} else {
renames.insert(name);
}
}
}
// Update kind and, optionally, the name of all native libaries
// (there may be more than one) with the specified name.
for &(ref name, ref new_name, kind) in &self.tcx.sess.opts.libs {
let mut found = false;
for lib in self.libs.iter_mut() {
if lib.name == name as &str {
let mut changed = false;
if let Some(k) = kind {
lib.kind = k;
changed = true;
}
if let &Some(ref new_name) = new_name {
lib.name = Symbol::intern(new_name);
changed = true;
}
if !changed {
let msg = format!("redundant linker flag specified for \
library `{}`", name);
self.tcx.sess.warn(&msg);
}
found = true;
}
}
if !found {
// Add if not found
let new_name = new_name.as_ref().map(|s| &**s); // &Option<String> -> Option<&str>
let lib = NativeLibrary {
name: Symbol::intern(new_name.unwrap_or(name)),
kind: if let Some(k) = kind { k } else { cstore::NativeUnknown },
cfg: None,
foreign_items: Vec::new(),
};
self.register_native_lib(None, lib);
}
}
}
}

View File

@ -209,7 +209,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let f = ty.fn_sig(this.hir.tcx());
if f.abi() == Abi::RustIntrinsic ||
f.abi() == Abi::PlatformIntrinsic {
Some(this.hir.tcx().item_name(def_id).as_str())
Some(this.hir.tcx().item_name(def_id))
} else {
None
}

View File

@ -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]);

View File

@ -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)
@ -100,7 +100,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
build_drop_shim(tcx, def_id, ty)
}
ty::InstanceDef::CloneShim(def_id, ty) => {
let name = tcx.item_name(def_id).as_str();
let name = tcx.item_name(def_id);
if name == "clone" {
build_clone_shim(tcx, def_id, ty)
} else if name == "clone_from" {

View File

@ -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());

View File

@ -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());

View File

@ -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));
@ -824,7 +824,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
Abi::RustIntrinsic |
Abi::PlatformIntrinsic => {
assert!(!self.tcx.is_const_fn(def_id));
match &self.tcx.item_name(def_id).as_str()[..] {
match &self.tcx.item_name(def_id)[..] {
"size_of" | "min_align_of" => is_const_fn = true,
name if name.starts_with("simd_shuffle") => {

View File

@ -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,
}

View File

@ -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)));

View File

@ -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;
}
}

View File

@ -630,7 +630,7 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
};
ty::Visibility::from_hir(vis, node_id, self.tcx)
}
None => self.tcx.sess.cstore.visibility(did),
None => self.tcx.visibility(did),
}
}

View File

@ -42,6 +42,7 @@ use syntax::ext::hygiene::Mark;
use syntax::ext::tt::macro_rules;
use syntax::parse::token;
use syntax::symbol::keywords;
use syntax::symbol::Symbol;
use syntax::visit::{self, Visitor};
use syntax_pos::{Span, DUMMY_SP};
@ -253,7 +254,7 @@ impl<'a> Resolver<'a> {
self.crate_loader.process_item(item, &self.definitions);
// n.b. we don't need to look at the path option here, because cstore already did
let crate_id = self.session.cstore.extern_mod_stmt_cnum(item.id).unwrap();
let crate_id = self.session.cstore.extern_mod_stmt_cnum_untracked(item.id).unwrap();
let module =
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
self.populate_module_if_necessary(module);
@ -449,7 +450,7 @@ impl<'a> Resolver<'a> {
let ident = child.ident;
let def = child.def;
let def_id = def.def_id();
let vis = self.session.cstore.visibility(def_id);
let vis = self.session.cstore.visibility_untracked(def_id);
let span = child.span;
let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene
match def {
@ -485,12 +486,12 @@ impl<'a> Resolver<'a> {
span);
self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
for child in self.session.cstore.item_children(def_id, self.session) {
for child in self.session.cstore.item_children_untracked(def_id, self.session) {
let ns = if let Def::AssociatedTy(..) = child.def { TypeNS } else { ValueNS };
self.define(module, child.ident, ns,
(child.def, ty::Visibility::Public, DUMMY_SP, expansion));
if self.session.cstore.associated_item_cloned(child.def.def_id())
if self.session.cstore.associated_item_cloned_untracked(child.def.def_id())
.method_has_self_argument {
self.has_self.insert(child.def.def_id());
}
@ -501,7 +502,7 @@ impl<'a> Resolver<'a> {
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
// Record field names for error reporting.
let field_names = self.session.cstore.struct_field_names(def_id);
let field_names = self.session.cstore.struct_field_names_untracked(def_id);
self.insert_field_names(def_id, field_names);
}
Def::Macro(..) => {
@ -516,20 +517,20 @@ impl<'a> Resolver<'a> {
return self.module_map[&def_id]
}
let macros_only = self.session.cstore.dep_kind(def_id.krate).macros_only();
let macros_only = self.session.cstore.dep_kind_untracked(def_id.krate).macros_only();
if let Some(&module) = self.extern_module_map.get(&(def_id, macros_only)) {
return module;
}
let (name, parent) = if def_id.index == CRATE_DEF_INDEX {
(self.session.cstore.crate_name(def_id.krate), None)
(self.session.cstore.crate_name_untracked(def_id.krate).as_str(), None)
} else {
let def_key = self.session.cstore.def_key(def_id);
(def_key.disambiguated_data.data.get_opt_name().unwrap(),
Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id })))
};
let kind = ModuleKind::Def(Def::Mod(def_id), name);
let kind = ModuleKind::Def(Def::Mod(def_id), Symbol::intern(&name));
let module =
self.arenas.alloc_module(ModuleData::new(parent, kind, def_id, Mark::root(), DUMMY_SP));
self.extern_module_map.insert((def_id, macros_only), module);
@ -558,7 +559,7 @@ impl<'a> Resolver<'a> {
return ext.clone();
}
let macro_def = match self.session.cstore.load_macro(def_id, &self.session) {
let macro_def = match self.session.cstore.load_macro_untracked(def_id, &self.session) {
LoadedMacro::MacroDef(macro_def) => macro_def,
LoadedMacro::ProcMacro(ext) => return ext,
};
@ -574,7 +575,8 @@ impl<'a> Resolver<'a> {
/// is built, building it if it is not.
pub fn populate_module_if_necessary(&mut self, module: Module<'a>) {
if module.populated.get() { return }
for child in self.session.cstore.item_children(module.def_id().unwrap(), self.session) {
let def_id = module.def_id().unwrap();
for child in self.session.cstore.item_children_untracked(def_id, self.session) {
self.build_reduced_graph_for_external_crate_def(module, child);
}
module.populated.set(true)
@ -605,7 +607,8 @@ impl<'a> Resolver<'a> {
span_err!(self.session, item.span, E0468,
"an `extern crate` loading macros must be at the crate root");
} else if !self.use_extern_macros && !used &&
self.session.cstore.dep_kind(module.def_id().unwrap().krate).macros_only() {
self.session.cstore.dep_kind_untracked(module.def_id().unwrap().krate)
.macros_only() {
let msg = "proc macro crates and `#[no_link]` crates have no effect without \
`#[macro_use]`";
self.session.span_warn(item.span, msg);
@ -648,7 +651,7 @@ impl<'a> Resolver<'a> {
}
}
for (name, span) in legacy_imports.reexports {
self.session.cstore.export_macros(module.def_id().unwrap().krate);
self.session.cstore.export_macros_untracked(module.def_id().unwrap().krate);
let ident = Ident::with_empty_ctxt(name);
let result = self.resolve_ident_in_module(module, ident, MacroNS, false, false, span);
if let Ok(binding) = result {

View File

@ -778,7 +778,7 @@ impl<'a> Resolver<'a> {
_ => return,
};
let crate_name = self.session.cstore.crate_name(krate);
let crate_name = self.session.cstore.crate_name_untracked(krate);
self.session.struct_span_err(use_span, warn_msg)
.help(&format!("instead, import the procedural macro like any other item: \

View File

@ -844,7 +844,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
let def = binding.def();
if def != Def::Err {
if !def.def_id().is_local() {
self.session.cstore.export_macros(def.def_id().krate);
self.session.cstore.export_macros_untracked(def.def_id().krate);
}
if let Def::Macro(..) = def {
if let Some(&span) = exported_macro_names.get(&ident.modern()) {

View File

@ -109,7 +109,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
pub fn get_external_crates(&self) -> Vec<ExternalCrateData> {
let mut result = Vec::new();
for n in self.tcx.sess.cstore.crates() {
for &n in self.tcx.crates().iter() {
let span = match *self.tcx.extern_crate(n.as_def_id()) {
Some(ref c) => c.span,
None => {
@ -119,7 +119,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
};
let lo_loc = self.span_utils.sess.codemap().lookup_char_pos(span.lo());
result.push(ExternalCrateData {
name: self.tcx.sess.cstore.crate_name(n).to_string(),
name: self.tcx.crate_name(n).to_string(),
num: n.as_u32(),
file_name: SpanUtils::make_path_string(&lo_loc.file.name),
});

View File

@ -20,10 +20,9 @@ use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType, Pri
use rustc::session::filesearch;
use rustc::session::search_paths::PathKind;
use rustc::session::Session;
use rustc::middle::cstore::{LinkMeta, NativeLibrary, LibSource, LinkagePreference,
NativeLibraryKind};
use rustc::middle::cstore::{LinkMeta, NativeLibrary, LibSource, NativeLibraryKind};
use rustc::middle::dependency_format::Linkage;
use CrateTranslation;
use {CrateTranslation, CrateInfo};
use rustc::util::common::time;
use rustc::util::fs::fix_windows_verbatim_for_gcc;
use rustc::dep_graph::{DepKind, DepNode};
@ -223,8 +222,9 @@ fn filename_for_metadata(sess: &Session, crate_name: &str, outputs: &OutputFilen
}
pub fn each_linked_rlib(sess: &Session,
info: &CrateInfo,
f: &mut FnMut(CrateNum, &Path)) -> Result<(), String> {
let crates = sess.cstore.used_crates(LinkagePreference::RequireStatic).into_iter();
let crates = info.used_crates_static.iter();
let fmts = sess.dependency_formats.borrow();
let fmts = fmts.get(&config::CrateTypeExecutable)
.or_else(|| fmts.get(&config::CrateTypeStaticlib))
@ -234,16 +234,16 @@ pub fn each_linked_rlib(sess: &Session,
Some(f) => f,
None => return Err(format!("could not find formats for rlibs"))
};
for (cnum, path) in crates {
for &(cnum, ref path) in crates {
match fmts.get(cnum.as_usize() - 1) {
Some(&Linkage::NotLinked) |
Some(&Linkage::IncludedFromDylib) => continue,
Some(_) => {}
None => return Err(format!("could not find formats for rlibs"))
}
let name = sess.cstore.crate_name(cnum).clone();
let path = match path {
LibSource::Some(p) => p,
let name = &info.crate_name[&cnum];
let path = match *path {
LibSource::Some(ref p) => p,
LibSource::MetadataOnly => {
return Err(format!("could not find rlib for: `{}`, found rmeta (metadata) file",
name))
@ -267,12 +267,12 @@ pub fn each_linked_rlib(sess: &Session,
/// It's unusual for a crate to not participate in LTO. Typically only
/// compiler-specific and unstable crates have a reason to not participate in
/// LTO.
pub fn ignored_for_lto(sess: &Session, cnum: CrateNum) -> bool {
pub fn ignored_for_lto(info: &CrateInfo, cnum: CrateNum) -> bool {
// `#![no_builtins]` crates don't participate in LTO because the state
// of builtins gets messed up (our crate isn't tagged with no builtins).
// Similarly `#![compiler_builtins]` doesn't participate because we want
// those builtins!
sess.cstore.is_no_builtins(cnum) || sess.cstore.is_compiler_builtins(cnum)
info.is_no_builtins.contains(&cnum) || info.compiler_builtins == Some(cnum)
}
fn out_filename(sess: &Session,
@ -438,7 +438,7 @@ fn link_rlib<'a>(sess: &'a Session,
// feature then we'll need to figure out how to record what objects were
// loaded from the libraries found here and then encode that into the
// metadata of the rlib we're generating somehow.
for lib in sess.cstore.used_libraries() {
for lib in trans.crate_info.used_libraries.iter() {
match lib.kind {
NativeLibraryKind::NativeStatic => {}
NativeLibraryKind::NativeStaticNobundle |
@ -618,9 +618,9 @@ fn link_staticlib(sess: &Session,
tempdir);
let mut all_native_libs = vec![];
let res = each_linked_rlib(sess, &mut |cnum, path| {
let name = sess.cstore.crate_name(cnum);
let native_libs = sess.cstore.native_libraries(cnum);
let res = each_linked_rlib(sess, &trans.crate_info, &mut |cnum, path| {
let name = &trans.crate_info.crate_name[&cnum];
let native_libs = &trans.crate_info.native_libraries[&cnum];
// Here when we include the rlib into our staticlib we need to make a
// decision whether to include the extra object files along the way.
@ -641,10 +641,10 @@ fn link_staticlib(sess: &Session,
});
ab.add_rlib(path,
&name.as_str(),
sess.lto() && !ignored_for_lto(sess, cnum),
sess.lto() && !ignored_for_lto(&trans.crate_info, cnum),
skip_object_files).unwrap();
all_native_libs.extend(sess.cstore.native_libraries(cnum));
all_native_libs.extend(trans.crate_info.native_libraries[&cnum].iter().cloned());
});
if let Err(e) = res {
sess.fatal(&e);
@ -1031,7 +1031,7 @@ fn link_args(cmd: &mut Linker,
cmd.gc_sections(keep_metadata);
}
let used_link_args = sess.cstore.used_link_args();
let used_link_args = &trans.crate_info.link_args;
if crate_type == config::CrateTypeExecutable &&
t.options.position_independent_executables {
@ -1101,9 +1101,9 @@ fn link_args(cmd: &mut Linker,
// link line. And finally upstream native libraries can't depend on anything
// in this DAG so far because they're only dylibs and dylibs can only depend
// on other dylibs (e.g. other native deps).
add_local_native_libraries(cmd, sess);
add_upstream_rust_crates(cmd, sess, crate_type, tmpdir);
add_upstream_native_libraries(cmd, sess, crate_type);
add_local_native_libraries(cmd, sess, trans);
add_upstream_rust_crates(cmd, sess, trans, crate_type, tmpdir);
add_upstream_native_libraries(cmd, sess, trans, crate_type);
// Tell the linker what we're doing.
if crate_type != config::CrateTypeExecutable {
@ -1128,7 +1128,7 @@ fn link_args(cmd: &mut Linker,
path
};
let mut rpath_config = RPathConfig {
used_crates: sess.cstore.used_crates(LinkagePreference::RequireDynamic),
used_crates: &trans.crate_info.used_crates_dynamic,
out_filename: out_filename.to_path_buf(),
has_rpath: sess.target.target.options.has_rpath,
is_like_osx: sess.target.target.options.is_like_osx,
@ -1158,7 +1158,9 @@ fn link_args(cmd: &mut Linker,
// Also note that the native libraries linked here are only the ones located
// in the current crate. Upstream crates with native library dependencies
// may have their native library pulled in above.
fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
fn add_local_native_libraries(cmd: &mut Linker,
sess: &Session,
trans: &CrateTranslation) {
sess.target_filesearch(PathKind::All).for_each_lib_search_path(|path, k| {
match k {
PathKind::Framework => { cmd.framework_path(path); }
@ -1166,7 +1168,7 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
}
});
let relevant_libs = sess.cstore.used_libraries().into_iter().filter(|l| {
let relevant_libs = trans.crate_info.used_libraries.iter().filter(|l| {
relevant_lib(sess, l)
});
@ -1189,6 +1191,7 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
// the intermediate rlib version)
fn add_upstream_rust_crates(cmd: &mut Linker,
sess: &Session,
trans: &CrateTranslation,
crate_type: config::CrateType,
tmpdir: &Path) {
// All of the heavy lifting has previously been accomplished by the
@ -1204,35 +1207,35 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
// Invoke get_used_crates to ensure that we get a topological sorting of
// crates.
let deps = sess.cstore.used_crates(LinkagePreference::RequireDynamic);
let deps = &trans.crate_info.used_crates_dynamic;
let mut compiler_builtins = None;
for &(cnum, _) in &deps {
for &(cnum, _) in deps.iter() {
// We may not pass all crates through to the linker. Some crates may
// appear statically in an existing dylib, meaning we'll pick up all the
// symbols from the dylib.
let src = sess.cstore.used_crate_source(cnum);
let src = &trans.crate_info.used_crate_source[&cnum];
match data[cnum.as_usize() - 1] {
_ if sess.cstore.is_profiler_runtime(cnum) => {
add_static_crate(cmd, sess, tmpdir, crate_type, cnum);
_ if trans.crate_info.profiler_runtime == Some(cnum) => {
add_static_crate(cmd, sess, trans, tmpdir, crate_type, cnum);
}
_ if sess.cstore.is_sanitizer_runtime(cnum) => {
link_sanitizer_runtime(cmd, sess, tmpdir, cnum);
_ if trans.crate_info.sanitizer_runtime == Some(cnum) => {
link_sanitizer_runtime(cmd, sess, trans, tmpdir, cnum);
}
// compiler-builtins are always placed last to ensure that they're
// linked correctly.
_ if sess.cstore.is_compiler_builtins(cnum) => {
_ if trans.crate_info.compiler_builtins == Some(cnum) => {
assert!(compiler_builtins.is_none());
compiler_builtins = Some(cnum);
}
Linkage::NotLinked |
Linkage::IncludedFromDylib => {}
Linkage::Static => {
add_static_crate(cmd, sess, tmpdir, crate_type, cnum);
add_static_crate(cmd, sess, trans, tmpdir, crate_type, cnum);
}
Linkage::Dynamic => {
add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0)
add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0)
}
}
}
@ -1243,7 +1246,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
// was already "included" in a dylib (e.g. `libstd` when `-C prefer-dynamic`
// is used)
if let Some(cnum) = compiler_builtins {
add_static_crate(cmd, sess, tmpdir, crate_type, cnum);
add_static_crate(cmd, sess, trans, tmpdir, crate_type, cnum);
}
// Converts a library file-stem into a cc -l argument
@ -1261,10 +1264,11 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
// linking it.
fn link_sanitizer_runtime(cmd: &mut Linker,
sess: &Session,
trans: &CrateTranslation,
tmpdir: &Path,
cnum: CrateNum) {
let src = sess.cstore.used_crate_source(cnum);
let cratepath = &src.rlib.unwrap().0;
let src = &trans.crate_info.used_crate_source[&cnum];
let cratepath = &src.rlib.as_ref().unwrap().0;
if sess.target.target.options.is_like_osx {
// On Apple platforms, the sanitizer is always built as a dylib, and
@ -1329,21 +1333,22 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
// we're at the end of the dependency chain.
fn add_static_crate(cmd: &mut Linker,
sess: &Session,
trans: &CrateTranslation,
tmpdir: &Path,
crate_type: config::CrateType,
cnum: CrateNum) {
let src = sess.cstore.used_crate_source(cnum);
let cratepath = &src.rlib.unwrap().0;
let src = &trans.crate_info.used_crate_source[&cnum];
let cratepath = &src.rlib.as_ref().unwrap().0;
// See the comment above in `link_staticlib` and `link_rlib` for why if
// there's a static library that's not relevant we skip all object
// files.
let native_libs = sess.cstore.native_libraries(cnum);
let native_libs = &trans.crate_info.native_libraries[&cnum];
let skip_native = native_libs.iter().any(|lib| {
lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib)
});
if (!sess.lto() || ignored_for_lto(sess, cnum)) &&
if (!sess.lto() || ignored_for_lto(&trans.crate_info, cnum)) &&
crate_type != config::CrateTypeDylib &&
!skip_native {
cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
@ -1385,7 +1390,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
// LTO module. Note that `#![no_builtins]` is excluded from LTO,
// though, so we let that object file slide.
let skip_because_lto = sess.lto() && is_rust_object &&
!sess.cstore.is_no_builtins(cnum);
!trans.crate_info.is_no_builtins.contains(&cnum);
if skip_because_cfg_say_so || skip_because_lto {
archive.remove_file(&f);
@ -1407,7 +1412,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
// compiler-builtins crate (e.g. compiler-rt) because it'll get
// repeatedly linked anyway.
if crate_type == config::CrateTypeDylib &&
!sess.cstore.is_compiler_builtins(cnum) {
trans.crate_info.compiler_builtins != Some(cnum) {
cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst));
} else {
cmd.link_rlib(&fix_windows_verbatim_for_gcc(&dst));
@ -1451,7 +1456,10 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
// generic function calls a native function, then the generic function must
// be instantiated in the target crate, meaning that the native symbol must
// also be resolved in the target crate.
fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session, crate_type: config::CrateType) {
fn add_upstream_native_libraries(cmd: &mut Linker,
sess: &Session,
trans: &CrateTranslation,
crate_type: config::CrateType) {
// Be sure to use a topological sorting of crates because there may be
// interdependencies between native libraries. When passing -nodefaultlibs,
// for example, almost all native libraries depend on libc, so we have to
@ -1464,9 +1472,9 @@ fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session, crate_type: c
let formats = sess.dependency_formats.borrow();
let data = formats.get(&crate_type).unwrap();
let crates = sess.cstore.used_crates(LinkagePreference::RequireStatic);
for (cnum, _) in crates {
for lib in sess.cstore.native_libraries(cnum) {
let crates = &trans.crate_info.used_crates_static;
for &(cnum, _) in crates {
for lib in trans.crate_info.native_libraries[&cnum].iter() {
if !relevant_lib(sess, &lib) {
continue
}

View File

@ -17,7 +17,7 @@ use rustc::hir::def_id::CrateNum;
use rustc::middle::cstore::LibSource;
pub struct RPathConfig<'a> {
pub used_crates: Vec<(CrateNum, LibSource)>,
pub used_crates: &'a [(CrateNum, LibSource)],
pub out_filename: PathBuf,
pub is_like_osx: bool,
pub has_rpath: bool,
@ -36,7 +36,7 @@ pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
debug!("preparing the RPATH!");
let libs = config.used_crates.clone();
let libs = libs.into_iter().filter_map(|(_, l)| l.option()).collect::<Vec<_>>();
let libs = libs.iter().filter_map(|&(_, ref l)| l.option()).collect::<Vec<_>>();
let rpaths = get_rpaths(config, &libs);
flags.extend_from_slice(&rpaths_to_flags(&rpaths));

View File

@ -110,13 +110,13 @@ impl ExportedSymbols {
let mut exports = FxHashMap();
exports.insert(LOCAL_CRATE, local_crate);
for cnum in tcx.sess.cstore.crates() {
for &cnum in tcx.crates().iter() {
debug_assert!(cnum != LOCAL_CRATE);
// If this crate is a plugin and/or a custom derive crate, then
// we're not even going to link those in so we skip those crates.
if tcx.sess.cstore.plugin_registrar_fn(cnum).is_some() ||
tcx.sess.cstore.derive_registrar_fn(cnum).is_some() {
if tcx.plugin_registrar_fn(cnum).is_some() ||
tcx.derive_registrar_fn(cnum).is_some() {
continue;
}
@ -128,12 +128,9 @@ impl ExportedSymbols {
// Down below we'll hardwire all of the symbols to the `Rust` export
// level instead.
let special_runtime_crate =
tcx.is_panic_runtime(cnum.as_def_id()) ||
tcx.sess.cstore.is_compiler_builtins(cnum);
tcx.is_panic_runtime(cnum) || tcx.is_compiler_builtins(cnum);
let crate_exports = tcx
.sess
.cstore
.exported_symbols(cnum)
.iter()
.map(|&def_id| {

View File

@ -242,7 +242,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
return name.to_string();
}
// Don't mangle foreign items.
return tcx.item_name(def_id).as_str().to_string();
return tcx.item_name(def_id).to_string();
}
if let Some(name) = attr::find_export_name_attr(tcx.sess.diagnostic(), &attrs) {
@ -252,7 +252,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
if attr::contains_name(&attrs, "no_mangle") {
// Don't mangle
return tcx.item_name(def_id).as_str().to_string();
return tcx.item_name(def_id).to_string();
}
// We want to compute the "type" of this item. Unfortunately, some

View File

@ -22,6 +22,7 @@ use llvm;
use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef};
use llvm::SMDiagnosticRef;
use {CrateTranslation, ModuleSource, ModuleTranslation, CompiledModule, ModuleKind};
use CrateInfo;
use rustc::hir::def_id::CrateNum;
use rustc::util::common::{time, time_depth, set_time_depth, path2cstr, print_time_passes_entry};
use rustc::util::fs::{link_or_copy, rename_or_copy_remove};
@ -675,6 +676,7 @@ pub fn start_async_translation(sess: &Session,
no_builtins: bool,
windows_subsystem: Option<String>,
linker_info: LinkerInfo,
crate_info: CrateInfo,
no_integrated_as: bool)
-> OngoingCrateTranslation {
let output_types_override = if no_integrated_as {
@ -774,6 +776,7 @@ pub fn start_async_translation(sess: &Session,
let (coordinator_send, coordinator_receive) = channel();
let coordinator_thread = start_executing_work(sess,
&crate_info,
shared_emitter,
trans_worker_send,
coordinator_send.clone(),
@ -788,6 +791,7 @@ pub fn start_async_translation(sess: &Session,
windows_subsystem,
linker_info,
no_integrated_as,
crate_info,
regular_module_config: modules_config,
metadata_module_config: metadata_config,
@ -1101,6 +1105,7 @@ enum MainThreadWorkerState {
}
fn start_executing_work(sess: &Session,
crate_info: &CrateInfo,
shared_emitter: SharedEmitter,
trans_worker_send: Sender<Message>,
coordinator_send: Sender<Message>,
@ -1125,8 +1130,8 @@ fn start_executing_work(sess: &Session,
}).expect("failed to spawn helper thread");
let mut each_linked_rlib_for_lto = Vec::new();
drop(link::each_linked_rlib(sess, &mut |cnum, path| {
if link::ignored_for_lto(sess, cnum) {
drop(link::each_linked_rlib(sess, crate_info, &mut |cnum, path| {
if link::ignored_for_lto(crate_info, cnum) {
return
}
each_linked_rlib_for_lto.push((cnum, path.to_path_buf()));
@ -1802,6 +1807,7 @@ pub struct OngoingCrateTranslation {
windows_subsystem: Option<String>,
linker_info: LinkerInfo,
no_integrated_as: bool,
crate_info: CrateInfo,
output_filenames: OutputFilenames,
regular_module_config: ModuleConfig,
@ -1850,6 +1856,7 @@ impl OngoingCrateTranslation {
metadata: self.metadata,
windows_subsystem: self.windows_subsystem,
linker_info: self.linker_info,
crate_info: self.crate_info,
modules: compiled_modules.modules,
allocator_module: compiled_modules.allocator_module,

View File

@ -41,7 +41,7 @@ use rustc::middle::lang_items::StartFnLangItem;
use rustc::middle::cstore::{EncodedMetadata, EncodedMetadataHashes};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::dep_graph::AssertDepGraphSafe;
use rustc::middle::cstore::LinkMeta;
use rustc::middle::cstore::{self, LinkMeta, LinkagePreference};
use rustc::hir::map as hir_map;
use rustc::util::common::{time, print_time_passes_entry};
use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType};
@ -75,6 +75,7 @@ use type_::Type;
use type_of;
use value::Value;
use rustc::util::nodemap::{NodeSet, FxHashMap, FxHashSet};
use CrateInfo;
use libc::c_uint;
use std::ffi::{CStr, CString};
@ -904,7 +905,7 @@ pub fn find_exported_symbols(tcx: TyCtxt, reachable: &NodeSet) -> NodeSet {
match tcx.hir.get(id) {
hir_map::NodeForeignItem(..) => {
let def_id = tcx.hir.local_def_id(id);
tcx.sess.cstore.is_statically_included_foreign_item(def_id)
tcx.is_statically_included_foreign_item(def_id)
}
// Only consider nodes that actually have exported symbols.
@ -970,6 +971,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
} else {
None
};
let crate_info = CrateInfo::new(tcx);
// Skip crate items and just output metadata in -Z no-trans mode.
if tcx.sess.opts.debugging_opts.no_trans ||
@ -987,6 +989,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
no_builtins,
None,
linker_info,
crate_info,
false);
ongoing_translation.submit_pre_translated_module_to_llvm(tcx.sess, metadata_module, true);
@ -1039,6 +1042,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
no_builtins,
windows_subsystem,
linker_info,
crate_info,
no_integrated_as);
// Translate an allocator shim, if any
@ -1502,3 +1506,46 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
(translation_items, codegen_units)
}
impl CrateInfo {
pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CrateInfo {
let mut info = CrateInfo {
panic_runtime: None,
compiler_builtins: None,
profiler_runtime: None,
sanitizer_runtime: None,
is_no_builtins: FxHashSet(),
native_libraries: FxHashMap(),
used_libraries: tcx.native_libraries(LOCAL_CRATE),
link_args: tcx.link_args(LOCAL_CRATE),
crate_name: FxHashMap(),
used_crates_dynamic: cstore::used_crates(tcx, LinkagePreference::RequireDynamic),
used_crates_static: cstore::used_crates(tcx, LinkagePreference::RequireStatic),
used_crate_source: FxHashMap(),
};
for &cnum in tcx.crates().iter() {
info.native_libraries.insert(cnum, tcx.native_libraries(cnum));
info.crate_name.insert(cnum, tcx.crate_name(cnum).to_string());
info.used_crate_source.insert(cnum, tcx.used_crate_source(cnum));
if tcx.is_panic_runtime(cnum) {
info.panic_runtime = Some(cnum);
}
if tcx.is_compiler_builtins(cnum) {
info.compiler_builtins = Some(cnum);
}
if tcx.is_profiler_runtime(cnum) {
info.profiler_runtime = Some(cnum);
}
if tcx.is_sanitizer_runtime(cnum) {
info.sanitizer_runtime = Some(cnum);
}
if tcx.is_no_builtins(cnum) {
info.is_no_builtins.insert(cnum);
}
}
return info
}
}

View File

@ -124,13 +124,17 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
}
if ccx.use_dll_storage_attrs() &&
ccx.sess().cstore.is_dllimport_foreign_item(instance_def_id)
{
unsafe {
llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
// FIXME(#42293) we should actually track this, but fails too many tests
// today.
tcx.dep_graph.with_ignore(|| {
if ccx.use_dll_storage_attrs() &&
tcx.is_dllimport_foreign_item(instance_def_id)
{
unsafe {
llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
}
}
}
});
llfn
};

View File

@ -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);

View File

@ -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());

View File

@ -211,12 +211,17 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
g
};
if ccx.use_dll_storage_attrs() && ccx.sess().cstore.is_dllimport_foreign_item(def_id) {
// For foreign (native) libs we know the exact storage type to use.
unsafe {
llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
// FIXME(#42293) we should actually track this, but fails too many tests
// today.
ccx.tcx().dep_graph.with_ignore(|| {
if ccx.use_dll_storage_attrs() && ccx.tcx().is_dllimport_foreign_item(def_id) {
// For foreign (native) libs we know the exact storage type to use.
unsafe {
llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
}
}
}
});
ccx.instances().borrow_mut().insert(instance, g);
ccx.statics().borrow_mut().insert(g, def_id);
g

View File

@ -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;

View File

@ -1612,7 +1612,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
fn get_enum_discriminant_name(cx: &CrateContext,
def_id: DefId)
-> InternedString {
cx.tcx().item_name(def_id).as_str()
cx.tcx().item_name(def_id)
}
}

View File

@ -189,7 +189,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
output.push_str(&path_element.data.as_interned_str());
}
} else {
output.push_str(&cx.tcx().item_name(def_id).as_str());
output.push_str(&cx.tcx().item_name(def_id));
}
}

View File

@ -104,7 +104,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
let arg_tys = sig.inputs();
let ret_ty = sig.output();
let name = &*tcx.item_name(def_id).as_str();
let name = &*tcx.item_name(def_id);
let llret_ty = type_of::type_of(ccx, ret_ty);
@ -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"),
};

View File

@ -66,6 +66,12 @@ pub use back::symbol_names::provide;
pub use metadata::LlvmMetadataLoader;
pub use llvm_util::{init, target_features, print_version, print_passes, print, enable_llvm_debug};
use std::rc::Rc;
use rustc::hir::def_id::CrateNum;
use rustc::util::nodemap::{FxHashSet, FxHashMap};
use rustc::middle::cstore::{NativeLibrary, CrateSource, LibSource};
pub mod back {
mod archive;
mod command;
@ -217,7 +223,24 @@ pub struct CrateTranslation {
pub link: rustc::middle::cstore::LinkMeta,
pub metadata: rustc::middle::cstore::EncodedMetadata,
windows_subsystem: Option<String>,
linker_info: back::linker::LinkerInfo
linker_info: back::linker::LinkerInfo,
crate_info: CrateInfo,
}
// Misc info we load from metadata to persist beyond the tcx
pub struct CrateInfo {
panic_runtime: Option<CrateNum>,
compiler_builtins: Option<CrateNum>,
profiler_runtime: Option<CrateNum>,
sanitizer_runtime: Option<CrateNum>,
is_no_builtins: FxHashSet<CrateNum>,
native_libraries: FxHashMap<CrateNum, Rc<Vec<NativeLibrary>>>,
crate_name: FxHashMap<CrateNum, String>,
used_libraries: Rc<Vec<NativeLibrary>>,
link_args: Rc<Vec<String>>,
used_crate_source: FxHashMap<CrateNum, Rc<CrateSource>>,
used_crates_static: Vec<(CrateNum, LibSource)>,
used_crates_dynamic: Vec<(CrateNum, LibSource)>,
}
__build_diagnostic_array! { librustc_trans, DIAGNOSTICS }

View File

@ -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.

View File

@ -445,7 +445,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
// Handle intrinsics old trans wants Expr's for, ourselves.
let intrinsic = match def {
Some(ty::InstanceDef::Intrinsic(def_id))
=> Some(bcx.tcx().item_name(def_id).as_str()),
=> Some(bcx.tcx().item_name(def_id)),
_ => None
};
let intrinsic = intrinsic.as_ref().map(|s| &s[..]);

View File

@ -365,7 +365,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
}
if let Some((ref dest, target)) = *destination {
let result = if fn_ty.fn_sig(tcx).abi() == Abi::RustIntrinsic {
match &tcx.item_name(def_id).as_str()[..] {
match &tcx.item_name(def_id)[..] {
"size_of" => {
let llval = C_uint(self.ccx,
self.ccx.size_of(substs.type_at(0)));
@ -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)

View File

@ -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));

View File

@ -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])
});

View File

@ -96,22 +96,23 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
-> ty::Region<'tcx>
{
let tcx = self.tcx();
let r = match tcx.named_region_map.defs.get(&lifetime.id) {
Some(&rl::Region::Static) => {
let hir_id = tcx.hir.node_to_hir_id(lifetime.id);
let r = match tcx.named_region(hir_id) {
Some(rl::Region::Static) => {
tcx.types.re_static
}
Some(&rl::Region::LateBound(debruijn, id)) => {
Some(rl::Region::LateBound(debruijn, id)) => {
let name = tcx.hir.name(id);
tcx.mk_region(ty::ReLateBound(debruijn,
ty::BrNamed(tcx.hir.local_def_id(id), name)))
}
Some(&rl::Region::LateBoundAnon(debruijn, index)) => {
Some(rl::Region::LateBoundAnon(debruijn, index)) => {
tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(index)))
}
Some(&rl::Region::EarlyBound(index, id)) => {
Some(rl::Region::EarlyBound(index, id)) => {
let name = tcx.hir.name(id);
tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
def_id: tcx.hir.local_def_id(id),
@ -120,7 +121,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
}))
}
Some(&rl::Region::Free(scope, id)) => {
Some(rl::Region::Free(scope, id)) => {
let name = tcx.hir.name(id);
tcx.mk_region(ty::ReFree(ty::FreeRegion {
scope,
@ -627,7 +628,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
self.ast_region_to_region(lifetime, None)
} else {
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
if tcx.named_region_map.defs.contains_key(&lifetime.id) {
let hir_id = tcx.hir.node_to_hir_id(lifetime.id);
if tcx.named_region(hir_id).is_some() {
self.ast_region_to_region(lifetime, None)
} else {
self.re_infer(span, None).unwrap_or_else(|| {
@ -1286,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() {
@ -1400,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, &[])

View File

@ -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,
},

View File

@ -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,

View File

@ -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;
}

View File

@ -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 {

View File

@ -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,
};

View File

@ -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);
}
_ => {}

View File

@ -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,
};
@ -552,14 +552,14 @@ pub fn all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> AllTraits<'a>
if !external_mods.insert(def_id) {
return;
}
for child in tcx.sess.cstore.item_children(def_id, tcx.sess) {
for child in tcx.item_children(def_id).iter() {
handle_external_def(tcx, traits, external_mods, child.def)
}
}
_ => {}
}
}
for cnum in tcx.sess.cstore.crates() {
for &cnum in tcx.crates().iter() {
let def_id = DefId {
krate: cnum,
index: CRATE_DEF_INDEX,

View File

@ -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))
}

View File

@ -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,

View File

@ -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(

View File

@ -14,8 +14,9 @@ use rustc::ty::TyCtxt;
use syntax::ast;
use syntax_pos::{Span, DUMMY_SP};
use rustc::hir;
use rustc::hir::def_id::LOCAL_CRATE;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir;
use rustc::util::nodemap::DefIdSet;
struct CheckVisitor<'a, 'tcx: 'a> {
@ -25,7 +26,8 @@ struct CheckVisitor<'a, 'tcx: 'a> {
impl<'a, 'tcx> CheckVisitor<'a, 'tcx> {
fn check_import(&self, id: ast::NodeId, span: Span) {
if !self.tcx.maybe_unused_trait_imports.contains(&id) {
let hir_id = self.tcx.hir.node_to_hir_id(id);
if !self.tcx.maybe_unused_trait_import(hir_id) {
return;
}
@ -73,14 +75,20 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut visitor = CheckVisitor { tcx, used_trait_imports };
tcx.hir.krate().visit_all_item_likes(&mut visitor);
for &(id, span) in &tcx.maybe_unused_extern_crates {
let cnum = tcx.sess.cstore.extern_mod_stmt_cnum(id).unwrap().as_def_id();
if !tcx.is_compiler_builtins(cnum)
&& !tcx.is_panic_runtime(cnum)
&& !tcx.has_global_allocator(cnum) {
let lint = lint::builtin::UNUSED_EXTERN_CRATES;
let msg = "unused extern crate";
tcx.lint_node(lint, id, span, msg);
}
for &(hir_id, span) in tcx.maybe_unused_extern_crates(LOCAL_CRATE).iter() {
let cnum = tcx.extern_mod_stmt_cnum(hir_id).unwrap();
if tcx.is_compiler_builtins(cnum) {
continue
}
if tcx.is_panic_runtime(cnum) {
continue
}
if tcx.has_global_allocator(cnum) {
continue
}
let id = tcx.hir.definitions().find_node_for_hir_id(hir_id);
let lint = lint::builtin::UNUSED_EXTERN_CRATES;
let msg = "unused extern crate";
tcx.lint_node(lint, id, span, msg);
}
}

View File

@ -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));

View File

@ -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);

View File

@ -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() {

View File

@ -812,7 +812,8 @@ fn has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) {
if self.has_late_bound_regions.is_some() { return }
match self.tcx.named_region_map.defs.get(&lt.id).cloned() {
let hir_id = self.tcx.hir.node_to_hir_id(lt.id);
match self.tcx.named_region(hir_id) {
Some(rl::Region::Static) | Some(rl::Region::EarlyBound(..)) => {}
Some(rl::Region::LateBound(debruijn, _)) |
Some(rl::Region::LateBoundAnon(debruijn, _))
@ -830,7 +831,8 @@ fn has_late_bound_regions<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
tcx, binder_depth: 1, has_late_bound_regions: None
};
for lifetime in &generics.lifetimes {
if tcx.named_region_map.late_bound.contains(&lifetime.lifetime.id) {
let hir_id = tcx.hir.node_to_hir_id(lifetime.lifetime.id);
if tcx.is_late_bound(hir_id) {
return Some(lifetime.lifetime.span);
}
}
@ -987,8 +989,8 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}).collect::<Vec<_>>();
let object_lifetime_defaults =
tcx.named_region_map.object_lifetime_defaults.get(&node_id);
let hir_id = tcx.hir.node_to_hir_id(node_id);
let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id);
// Now create the real type parameters.
let type_start = own_start + regions.len() as u32;
@ -1014,7 +1016,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: tcx.hir.local_def_id(p.id),
has_default: p.default.is_some(),
object_lifetime_default:
object_lifetime_defaults.map_or(rl::Set1::Empty, |o| o[i]),
object_lifetime_defaults.as_ref().map_or(rl::Set1::Empty, |o| o[i]),
pure_wrt_drop: p.pure_wrt_drop,
}
});
@ -1307,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.
@ -1343,7 +1345,10 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>(
ast_generics
.lifetimes
.iter()
.filter(move |l| !tcx.named_region_map.late_bound.contains(&l.lifetime.id))
.filter(move |l| {
let hir_id = tcx.hir.node_to_hir_id(l.lifetime.id);
!tcx.is_late_bound(hir_id)
})
}
fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

View File

@ -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]),
];

View File

@ -120,7 +120,7 @@ pub fn load_attrs(cx: &DocContext, did: DefId) -> clean::Attributes {
/// These names are used later on by HTML rendering to generate things like
/// source links back to the original item.
pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) {
let crate_name = cx.tcx.sess.cstore.crate_name(did.krate).to_string();
let crate_name = cx.tcx.crate_name(did.krate).to_string();
let relative = cx.tcx.def_path(did).data.into_iter().filter_map(|elem| {
// extern blocks have an empty name
let s = elem.data.to_string();
@ -236,31 +236,34 @@ pub fn build_impls(cx: &DocContext, did: DefId) -> Vec<clean::Item> {
cx.populated_all_crate_impls.set(true);
for did in tcx.sess.cstore.implementations_of_trait(None) {
build_impl(cx, did, &mut impls);
for &cnum in tcx.crates().iter() {
for did in tcx.all_trait_implementations(cnum).iter() {
build_impl(cx, *did, &mut impls);
}
}
// Also try to inline primitive impls from other crates.
let lang_items = tcx.lang_items();
let primitive_impls = [
tcx.lang_items.isize_impl(),
tcx.lang_items.i8_impl(),
tcx.lang_items.i16_impl(),
tcx.lang_items.i32_impl(),
tcx.lang_items.i64_impl(),
tcx.lang_items.i128_impl(),
tcx.lang_items.usize_impl(),
tcx.lang_items.u8_impl(),
tcx.lang_items.u16_impl(),
tcx.lang_items.u32_impl(),
tcx.lang_items.u64_impl(),
tcx.lang_items.u128_impl(),
tcx.lang_items.f32_impl(),
tcx.lang_items.f64_impl(),
tcx.lang_items.char_impl(),
tcx.lang_items.str_impl(),
tcx.lang_items.slice_impl(),
tcx.lang_items.const_ptr_impl(),
tcx.lang_items.mut_ptr_impl(),
lang_items.isize_impl(),
lang_items.i8_impl(),
lang_items.i16_impl(),
lang_items.i32_impl(),
lang_items.i64_impl(),
lang_items.i128_impl(),
lang_items.usize_impl(),
lang_items.u8_impl(),
lang_items.u16_impl(),
lang_items.u32_impl(),
lang_items.u64_impl(),
lang_items.u128_impl(),
lang_items.f32_impl(),
lang_items.f64_impl(),
lang_items.char_impl(),
lang_items.str_impl(),
lang_items.slice_impl(),
lang_items.const_ptr_impl(),
lang_items.mut_ptr_impl(),
];
for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) {
@ -399,7 +402,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
clean::RegionBound(..) => unreachable!(),
}
});
if trait_.def_id() == tcx.lang_items.deref_trait() {
if trait_.def_id() == tcx.lang_items().deref_trait() {
super::build_deref_target_impls(cx, &trait_items, ret);
}
@ -443,9 +446,9 @@ fn build_module(cx: &DocContext, did: DefId) -> clean::Module {
// two namespaces, so the target may be listed twice. Make sure we only
// visit each node at most once.
let mut visited = FxHashSet();
for item in cx.tcx.sess.cstore.item_children(did, cx.tcx.sess) {
for &item in cx.tcx.item_children(did).iter() {
let def_id = item.def.def_id();
if cx.tcx.sess.cstore.visibility(def_id) == ty::Visibility::Public {
if cx.tcx.visibility(def_id) == ty::Visibility::Public {
if !visited.insert(def_id) { continue }
if let Some(i) = try_inline(cx, item.def, item.ident.name) {
items.extend(i)
@ -471,7 +474,7 @@ impl hir::print::PpAnn for InlinedConst {
}
fn print_inlined_const(cx: &DocContext, did: DefId) -> String {
let body = cx.tcx.sess.cstore.item_body(cx.tcx, did);
let body = cx.tcx.extern_const_body(did);
let inlined = InlinedConst {
nested_bodies: cx.tcx.item_body_nested_bodies(did)
};

Some files were not shown because too many files have changed in this diff Show More