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:
commit
dead08cb33
|
@ -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 {
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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! */ }
|
||||
};
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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)) =
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
//
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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"`
|
||||
```
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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" {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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") => {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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: \
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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),
|
||||
});
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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"),
|
||||
};
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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[..]);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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])
|
||||
});
|
||||
|
||||
|
|
|
@ -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, &[])
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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(<.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>,
|
||||
|
|
|
@ -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]),
|
||||
|
||||
];
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue