Make resolutions a query.
This commit is contained in:
parent
b09dad3edd
commit
071a047dc7
13 changed files with 127 additions and 112 deletions
|
@ -23,7 +23,7 @@ use tracing::debug;
|
||||||
/// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
|
/// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
|
||||||
/// stores the `DefIndex` of its parent.
|
/// stores the `DefIndex` of its parent.
|
||||||
/// There is one `DefPathTable` for each crate.
|
/// There is one `DefPathTable` for each crate.
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default, Debug)]
|
||||||
pub struct DefPathTable {
|
pub struct DefPathTable {
|
||||||
index_to_key: IndexVec<DefIndex, DefKey>,
|
index_to_key: IndexVec<DefIndex, DefKey>,
|
||||||
def_path_hashes: IndexVec<DefIndex, DefPathHash>,
|
def_path_hashes: IndexVec<DefIndex, DefPathHash>,
|
||||||
|
@ -96,7 +96,7 @@ impl DefPathTable {
|
||||||
/// The definition table containing node definitions.
|
/// The definition table containing node definitions.
|
||||||
/// It holds the `DefPathTable` for `LocalDefId`s/`DefPath`s.
|
/// It holds the `DefPathTable` for `LocalDefId`s/`DefPath`s.
|
||||||
/// It also stores mappings to convert `LocalDefId`s to/from `HirId`s.
|
/// It also stores mappings to convert `LocalDefId`s to/from `HirId`s.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Definitions {
|
pub struct Definitions {
|
||||||
table: DefPathTable,
|
table: DefPathTable,
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,12 @@ pub struct CStore {
|
||||||
unused_externs: Vec<Symbol>,
|
unused_externs: Vec<Symbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for CStore {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("CStore").finish_non_exhaustive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct CrateLoader<'a> {
|
pub struct CrateLoader<'a> {
|
||||||
// Immutable configuration.
|
// Immutable configuration.
|
||||||
sess: &'a Session,
|
sess: &'a Session,
|
||||||
|
|
|
@ -156,11 +156,13 @@ impl<'hir> Map<'hir> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn definitions(&self) -> &'hir Definitions {
|
pub fn definitions(&self) -> &'hir Definitions {
|
||||||
&self.tcx.definitions
|
// Accessing the definitions is ok, since all its contents are tracked by the query system.
|
||||||
|
&self.tcx.untracked_resolutions.definitions
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn def_key(&self, def_id: LocalDefId) -> DefKey {
|
pub fn def_key(&self, def_id: LocalDefId) -> DefKey {
|
||||||
self.tcx.definitions.def_key(def_id)
|
// Accessing the definitions is ok, since all its contents are tracked by the query system.
|
||||||
|
self.tcx.untracked_resolutions.definitions.def_key(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn def_path_from_hir_id(&self, id: HirId) -> Option<DefPath> {
|
pub fn def_path_from_hir_id(&self, id: HirId) -> Option<DefPath> {
|
||||||
|
@ -168,7 +170,8 @@ impl<'hir> Map<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn def_path(&self, def_id: LocalDefId) -> DefPath {
|
pub fn def_path(&self, def_id: LocalDefId) -> DefPath {
|
||||||
self.tcx.definitions.def_path(def_id)
|
// Accessing the definitions is ok, since all its contents are tracked by the query system.
|
||||||
|
self.tcx.untracked_resolutions.definitions.def_path(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -184,16 +187,19 @@ impl<'hir> Map<'hir> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn opt_local_def_id(&self, hir_id: HirId) -> Option<LocalDefId> {
|
pub fn opt_local_def_id(&self, hir_id: HirId) -> Option<LocalDefId> {
|
||||||
self.tcx.definitions.opt_hir_id_to_local_def_id(hir_id)
|
// Accessing the definitions is ok, since all its contents are tracked by the query system.
|
||||||
|
self.tcx.untracked_resolutions.definitions.opt_hir_id_to_local_def_id(hir_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
|
pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
|
||||||
self.tcx.definitions.local_def_id_to_hir_id(def_id)
|
// Accessing the definitions is ok, since all its contents are tracked by the query system.
|
||||||
|
self.tcx.untracked_resolutions.definitions.local_def_id_to_hir_id(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
|
pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
|
||||||
self.tcx.definitions.iter_local_def_id()
|
// Accessing the definitions is ok, since all its contents are tracked by the query system.
|
||||||
|
self.tcx.untracked_resolutions.definitions.iter_local_def_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opt_def_kind(&self, local_def_id: LocalDefId) -> Option<DefKind> {
|
pub fn opt_def_kind(&self, local_def_id: LocalDefId) -> Option<DefKind> {
|
||||||
|
@ -932,9 +938,15 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
|
||||||
pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexedHir<'tcx> {
|
pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexedHir<'tcx> {
|
||||||
let _prof_timer = tcx.sess.prof.generic_activity("build_hir_map");
|
let _prof_timer = tcx.sess.prof.generic_activity("build_hir_map");
|
||||||
|
|
||||||
|
// We can access untracked state since we are an eval_always query.
|
||||||
let hcx = tcx.create_stable_hashing_context();
|
let hcx = tcx.create_stable_hashing_context();
|
||||||
let mut collector =
|
let mut collector = NodeCollector::root(
|
||||||
NodeCollector::root(tcx.sess, &**tcx.arena, tcx.untracked_crate, &tcx.definitions, hcx);
|
tcx.sess,
|
||||||
|
&**tcx.arena,
|
||||||
|
tcx.untracked_crate,
|
||||||
|
&tcx.untracked_resolutions.definitions,
|
||||||
|
hcx,
|
||||||
|
);
|
||||||
intravisit::walk_crate(&mut collector, tcx.untracked_crate);
|
intravisit::walk_crate(&mut collector, tcx.untracked_crate);
|
||||||
|
|
||||||
let map = collector.finalize_and_compute_crate_hash();
|
let map = collector.finalize_and_compute_crate_hash();
|
||||||
|
@ -944,6 +956,7 @@ pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexedHir<'tc
|
||||||
pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
||||||
assert_eq!(crate_num, LOCAL_CRATE);
|
assert_eq!(crate_num, LOCAL_CRATE);
|
||||||
|
|
||||||
|
// We can access untracked state since we are an eval_always query.
|
||||||
let mut hcx = tcx.create_stable_hashing_context();
|
let mut hcx = tcx.create_stable_hashing_context();
|
||||||
|
|
||||||
let mut hir_body_nodes: Vec<_> = tcx
|
let mut hir_body_nodes: Vec<_> = tcx
|
||||||
|
@ -951,7 +964,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
||||||
.map
|
.map
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.filter_map(|(def_id, hod)| {
|
.filter_map(|(def_id, hod)| {
|
||||||
let def_path_hash = tcx.definitions.def_path_hash(def_id);
|
let def_path_hash = tcx.untracked_resolutions.definitions.def_path_hash(def_id);
|
||||||
let mut hasher = StableHasher::new();
|
let mut hasher = StableHasher::new();
|
||||||
hod.as_ref()?.hash_stable(&mut hcx, &mut hasher);
|
hod.as_ref()?.hash_stable(&mut hcx, &mut hasher);
|
||||||
AttributeMap { map: &tcx.untracked_crate.attrs, prefix: def_id }
|
AttributeMap { map: &tcx.untracked_crate.attrs, prefix: def_id }
|
||||||
|
@ -968,7 +981,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let upstream_crates = upstream_crates(&*tcx.cstore);
|
let upstream_crates = upstream_crates(&*tcx.untracked_resolutions.cstore);
|
||||||
|
|
||||||
// We hash the final, remapped names of all local source files so we
|
// We hash the final, remapped names of all local source files so we
|
||||||
// don't have to include the path prefix remapping commandline args.
|
// don't have to include the path prefix remapping commandline args.
|
||||||
|
|
|
@ -169,6 +169,6 @@ pub fn provide(providers: &mut Providers) {
|
||||||
providers.all_local_trait_impls = |tcx, ()| &tcx.hir_crate(()).trait_impls;
|
providers.all_local_trait_impls = |tcx, ()| &tcx.hir_crate(()).trait_impls;
|
||||||
providers.expn_that_defined = |tcx, id| {
|
providers.expn_that_defined = |tcx, id| {
|
||||||
let id = id.expect_local();
|
let id = id.expect_local();
|
||||||
tcx.definitions.expansion_that_defined(id)
|
tcx.resolutions(()).definitions.expansion_that_defined(id)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,7 @@ pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;
|
||||||
/// that it's *not* tracked for dependency information throughout compilation
|
/// that it's *not* tracked for dependency information throughout compilation
|
||||||
/// (it'd break incremental compilation) and should only be called pre-HIR (e.g.
|
/// (it'd break incremental compilation) and should only be called pre-HIR (e.g.
|
||||||
/// during resolve)
|
/// during resolve)
|
||||||
pub trait CrateStore {
|
pub trait CrateStore: std::fmt::Debug {
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
|
|
||||||
// resolve
|
// resolve
|
||||||
|
|
|
@ -14,6 +14,12 @@ rustc_queries! {
|
||||||
desc { "trigger a delay span bug" }
|
desc { "trigger a delay span bug" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query resolutions(_: ()) -> &'tcx ty::ResolverOutputs {
|
||||||
|
eval_always
|
||||||
|
no_hash
|
||||||
|
desc { "get the resolver outputs" }
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents crate as a whole (as distinct from the top-level crate module).
|
/// Represents crate as a whole (as distinct from the top-level crate module).
|
||||||
/// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`),
|
/// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`),
|
||||||
/// we will have to assume that any change means that you need to be recompiled.
|
/// we will have to assume that any change means that you need to be recompiled.
|
||||||
|
@ -207,7 +213,6 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
|
|
||||||
query expn_that_defined(key: DefId) -> rustc_span::ExpnId {
|
query expn_that_defined(key: DefId) -> rustc_span::ExpnId {
|
||||||
eval_always
|
|
||||||
desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1129,7 +1134,6 @@ rustc_queries! {
|
||||||
|
|
||||||
query module_exports(def_id: LocalDefId) -> Option<&'tcx [Export<LocalDefId>]> {
|
query module_exports(def_id: LocalDefId) -> Option<&'tcx [Export<LocalDefId>]> {
|
||||||
desc { |tcx| "looking up items exported by `{}`", tcx.def_path_str(def_id.to_def_id()) }
|
desc { |tcx| "looking up items exported by `{}`", tcx.def_path_str(def_id.to_def_id()) }
|
||||||
eval_always
|
|
||||||
}
|
}
|
||||||
|
|
||||||
query impl_defaultness(def_id: DefId) -> hir::Defaultness {
|
query impl_defaultness(def_id: DefId) -> hir::Defaultness {
|
||||||
|
@ -1319,7 +1323,6 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
|
|
||||||
query visibility(def_id: DefId) -> ty::Visibility {
|
query visibility(def_id: DefId) -> ty::Visibility {
|
||||||
eval_always
|
|
||||||
desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
|
desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1344,8 +1347,6 @@ rustc_queries! {
|
||||||
desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) }
|
desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) }
|
||||||
}
|
}
|
||||||
query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> {
|
query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> {
|
||||||
// This depends on untracked global state (`tcx.extern_crate_map`)
|
|
||||||
eval_always
|
|
||||||
desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id.to_def_id()) }
|
desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id.to_def_id()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1422,16 +1423,12 @@ rustc_queries! {
|
||||||
eval_always
|
eval_always
|
||||||
}
|
}
|
||||||
query maybe_unused_trait_import(def_id: LocalDefId) -> bool {
|
query maybe_unused_trait_import(def_id: LocalDefId) -> bool {
|
||||||
eval_always
|
|
||||||
desc { |tcx| "maybe_unused_trait_import for `{}`", tcx.def_path_str(def_id.to_def_id()) }
|
desc { |tcx| "maybe_unused_trait_import for `{}`", tcx.def_path_str(def_id.to_def_id()) }
|
||||||
}
|
}
|
||||||
query maybe_unused_extern_crates(_: ()) -> &'tcx [(LocalDefId, Span)] {
|
query maybe_unused_extern_crates(_: ()) -> &'tcx [(LocalDefId, Span)] {
|
||||||
eval_always
|
|
||||||
desc { "looking up all possibly unused extern crates" }
|
desc { "looking up all possibly unused extern crates" }
|
||||||
}
|
}
|
||||||
query names_imported_by_glob_use(def_id: LocalDefId)
|
query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx FxHashSet<Symbol> {
|
||||||
-> &'tcx FxHashSet<Symbol> {
|
|
||||||
eval_always
|
|
||||||
desc { |tcx| "names_imported_by_glob_use for `{}`", tcx.def_path_str(def_id.to_def_id()) }
|
desc { |tcx| "names_imported_by_glob_use for `{}`", tcx.def_path_str(def_id.to_def_id()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1441,7 +1438,6 @@ rustc_queries! {
|
||||||
desc { "calculating the stability index for the local crate" }
|
desc { "calculating the stability index for the local crate" }
|
||||||
}
|
}
|
||||||
query crates(_: ()) -> &'tcx [CrateNum] {
|
query crates(_: ()) -> &'tcx [CrateNum] {
|
||||||
eval_always
|
|
||||||
desc { "fetching all foreign CrateNum instances" }
|
desc { "fetching all foreign CrateNum instances" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,12 @@
|
||||||
|
|
||||||
use crate::arena::Arena;
|
use crate::arena::Arena;
|
||||||
use crate::dep_graph::DepGraph;
|
use crate::dep_graph::DepGraph;
|
||||||
use crate::hir::exports::ExportMap;
|
|
||||||
use crate::hir::place::Place as HirPlace;
|
use crate::hir::place::Place as HirPlace;
|
||||||
use crate::ich::{NodeIdHashingMode, StableHashingContext};
|
use crate::ich::{NodeIdHashingMode, StableHashingContext};
|
||||||
use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
|
use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
|
||||||
use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource};
|
use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource};
|
||||||
use crate::middle;
|
use crate::middle;
|
||||||
use crate::middle::cstore::{CrateStoreDyn, EncodedMetadata};
|
use crate::middle::cstore::EncodedMetadata;
|
||||||
use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath, ObjectLifetimeDefault};
|
use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath, ObjectLifetimeDefault};
|
||||||
use crate::middle::stability;
|
use crate::middle::stability;
|
||||||
use crate::mir::interpret::{self, AllocId, Allocation, ConstValue, Scalar};
|
use crate::mir::interpret::{self, AllocId, Allocation, ConstValue, Scalar};
|
||||||
|
@ -21,10 +20,9 @@ use crate::ty::TyKind::*;
|
||||||
use crate::ty::{
|
use crate::ty::{
|
||||||
self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
|
self, AdtDef, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
|
||||||
ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar,
|
ClosureSizeProfileData, Const, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, FloatVar,
|
||||||
FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
|
FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst,
|
||||||
MainDefinition, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind,
|
ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind, ProjectionTy, Region, RegionKind,
|
||||||
ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar,
|
ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
|
||||||
TyVid, TypeAndMut, UintTy, Visibility,
|
|
||||||
};
|
};
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
|
@ -39,7 +37,6 @@ use rustc_errors::ErrorReported;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
|
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
|
||||||
use rustc_hir::definitions::Definitions;
|
|
||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
|
@ -966,8 +963,6 @@ pub struct GlobalCtxt<'tcx> {
|
||||||
|
|
||||||
interners: CtxtInterners<'tcx>,
|
interners: CtxtInterners<'tcx>,
|
||||||
|
|
||||||
pub(crate) cstore: Box<CrateStoreDyn>,
|
|
||||||
|
|
||||||
pub sess: &'tcx Session,
|
pub sess: &'tcx Session,
|
||||||
|
|
||||||
/// This only ever stores a `LintStore` but we don't want a dependency on that type here.
|
/// This only ever stores a `LintStore` but we don't want a dependency on that type here.
|
||||||
|
@ -989,17 +984,10 @@ pub struct GlobalCtxt<'tcx> {
|
||||||
/// Common consts, pre-interned for your convenience.
|
/// Common consts, pre-interned for your convenience.
|
||||||
pub consts: CommonConsts<'tcx>,
|
pub consts: CommonConsts<'tcx>,
|
||||||
|
|
||||||
/// Visibilities produced by resolver.
|
/// Output of the resolver.
|
||||||
pub visibilities: FxHashMap<LocalDefId, Visibility>,
|
pub(crate) untracked_resolutions: ty::ResolverOutputs,
|
||||||
|
|
||||||
/// Resolutions of `extern crate` items produced by resolver.
|
|
||||||
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
|
|
||||||
|
|
||||||
/// Export map produced by name resolution.
|
|
||||||
export_map: ExportMap<LocalDefId>,
|
|
||||||
|
|
||||||
pub(crate) untracked_crate: &'tcx hir::Crate<'tcx>,
|
pub(crate) untracked_crate: &'tcx hir::Crate<'tcx>,
|
||||||
pub(crate) definitions: Definitions,
|
|
||||||
|
|
||||||
/// This provides access to the incremental compilation on-disk cache for query results.
|
/// This provides access to the incremental compilation on-disk cache for query results.
|
||||||
/// Do not access this directly. It is only meant to be used by
|
/// Do not access this directly. It is only meant to be used by
|
||||||
|
@ -1010,15 +998,6 @@ pub struct GlobalCtxt<'tcx> {
|
||||||
pub queries: &'tcx dyn query::QueryEngine<'tcx>,
|
pub queries: &'tcx dyn query::QueryEngine<'tcx>,
|
||||||
pub query_caches: query::QueryCaches<'tcx>,
|
pub query_caches: query::QueryCaches<'tcx>,
|
||||||
|
|
||||||
maybe_unused_trait_imports: FxHashSet<LocalDefId>,
|
|
||||||
maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
|
|
||||||
/// A map of glob use to a set of names it actually imports. Currently only
|
|
||||||
/// used in save-analysis.
|
|
||||||
pub(crate) glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
|
|
||||||
/// Extern prelude entries. The value is `true` if the entry was introduced
|
|
||||||
/// via `extern crate` item and not `--extern` option or compiler built-in.
|
|
||||||
pub extern_prelude: FxHashMap<Symbol, bool>,
|
|
||||||
|
|
||||||
// Internal caches for metadata decoding. No need to track deps on this.
|
// Internal caches for metadata decoding. No need to track deps on this.
|
||||||
pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
|
pub ty_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
|
||||||
pub pred_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Predicate<'tcx>>>,
|
pub pred_rcache: Lock<FxHashMap<ty::CReaderCacheKey, Predicate<'tcx>>>,
|
||||||
|
@ -1052,8 +1031,6 @@ pub struct GlobalCtxt<'tcx> {
|
||||||
|
|
||||||
output_filenames: Arc<OutputFilenames>,
|
output_filenames: Arc<OutputFilenames>,
|
||||||
|
|
||||||
pub main_def: Option<MainDefinition>,
|
|
||||||
|
|
||||||
pub(super) vtables_cache:
|
pub(super) vtables_cache:
|
||||||
Lock<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), AllocId>>,
|
Lock<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), AllocId>>,
|
||||||
}
|
}
|
||||||
|
@ -1176,28 +1153,19 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
let common_types = CommonTypes::new(&interners);
|
let common_types = CommonTypes::new(&interners);
|
||||||
let common_lifetimes = CommonLifetimes::new(&interners);
|
let common_lifetimes = CommonLifetimes::new(&interners);
|
||||||
let common_consts = CommonConsts::new(&interners, &common_types);
|
let common_consts = CommonConsts::new(&interners, &common_types);
|
||||||
let cstore = resolutions.cstore;
|
|
||||||
|
|
||||||
GlobalCtxt {
|
GlobalCtxt {
|
||||||
sess: s,
|
sess: s,
|
||||||
lint_store,
|
lint_store,
|
||||||
cstore,
|
|
||||||
arena,
|
arena,
|
||||||
interners,
|
interners,
|
||||||
dep_graph,
|
dep_graph,
|
||||||
|
untracked_resolutions: resolutions,
|
||||||
prof: s.prof.clone(),
|
prof: s.prof.clone(),
|
||||||
types: common_types,
|
types: common_types,
|
||||||
lifetimes: common_lifetimes,
|
lifetimes: common_lifetimes,
|
||||||
consts: common_consts,
|
consts: common_consts,
|
||||||
visibilities: resolutions.visibilities,
|
|
||||||
extern_crate_map: resolutions.extern_crate_map,
|
|
||||||
export_map: resolutions.export_map,
|
|
||||||
maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports,
|
|
||||||
maybe_unused_extern_crates: resolutions.maybe_unused_extern_crates,
|
|
||||||
glob_map: resolutions.glob_map,
|
|
||||||
extern_prelude: resolutions.extern_prelude,
|
|
||||||
untracked_crate: krate,
|
untracked_crate: krate,
|
||||||
definitions: resolutions.definitions,
|
|
||||||
on_disk_cache,
|
on_disk_cache,
|
||||||
queries,
|
queries,
|
||||||
query_caches: query::QueryCaches::default(),
|
query_caches: query::QueryCaches::default(),
|
||||||
|
@ -1212,7 +1180,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
const_stability_interner: Default::default(),
|
const_stability_interner: Default::default(),
|
||||||
alloc_map: Lock::new(interpret::AllocMap::new()),
|
alloc_map: Lock::new(interpret::AllocMap::new()),
|
||||||
output_filenames: Arc::new(output_filenames),
|
output_filenames: Arc::new(output_filenames),
|
||||||
main_def: resolutions.main_def,
|
|
||||||
vtables_cache: Default::default(),
|
vtables_cache: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1273,7 +1240,12 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey {
|
pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey {
|
||||||
if let Some(id) = id.as_local() { self.hir().def_key(id) } else { self.cstore.def_key(id) }
|
// Accessing the definitions is ok, since all its contents are tracked by the query system.
|
||||||
|
if let Some(id) = id.as_local() {
|
||||||
|
self.hir().def_key(id)
|
||||||
|
} else {
|
||||||
|
self.untracked_resolutions.cstore.def_key(id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a `DefId` into its fully expanded `DefPath` (every
|
/// Converts a `DefId` into its fully expanded `DefPath` (every
|
||||||
|
@ -1282,19 +1254,21 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
/// Note that if `id` is not local to this crate, the result will
|
/// Note that if `id` is not local to this crate, the result will
|
||||||
/// be a non-local `DefPath`.
|
/// be a non-local `DefPath`.
|
||||||
pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
|
pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath {
|
||||||
|
// Accessing the definitions is ok, since all its contents are tracked by the query system.
|
||||||
if let Some(id) = id.as_local() {
|
if let Some(id) = id.as_local() {
|
||||||
self.hir().def_path(id)
|
self.hir().def_path(id)
|
||||||
} else {
|
} else {
|
||||||
self.cstore.def_path(id)
|
self.untracked_resolutions.cstore.def_path(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
|
pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash {
|
||||||
|
// Accessing the definitions is ok, since all its contents are tracked by the query system.
|
||||||
if let Some(def_id) = def_id.as_local() {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
self.definitions.def_path_hash(def_id)
|
self.untracked_resolutions.definitions.def_path_hash(def_id)
|
||||||
} else {
|
} else {
|
||||||
self.cstore.def_path_hash(def_id)
|
self.untracked_resolutions.cstore.def_path_hash(def_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1303,7 +1277,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
if crate_num == LOCAL_CRATE {
|
if crate_num == LOCAL_CRATE {
|
||||||
self.sess.local_stable_crate_id()
|
self.sess.local_stable_crate_id()
|
||||||
} else {
|
} else {
|
||||||
self.cstore.stable_crate_id_untracked(crate_num)
|
self.untracked_resolutions.cstore.stable_crate_id_untracked(crate_num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1315,9 +1289,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
let (crate_name, stable_crate_id) = if def_id.is_local() {
|
let (crate_name, stable_crate_id) = if def_id.is_local() {
|
||||||
(self.crate_name, self.sess.local_stable_crate_id())
|
(self.crate_name, self.sess.local_stable_crate_id())
|
||||||
} else {
|
} else {
|
||||||
|
let cstore = &self.untracked_resolutions.cstore;
|
||||||
(
|
(
|
||||||
self.cstore.crate_name_untracked(def_id.krate),
|
cstore.crate_name_untracked(def_id.krate),
|
||||||
self.def_path_hash(def_id.krate.as_def_id()).stable_crate_id(),
|
cstore.stable_crate_id_untracked(def_id.krate),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1333,27 +1308,34 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
|
||||||
pub fn encode_metadata(self) -> EncodedMetadata {
|
pub fn encode_metadata(self) -> EncodedMetadata {
|
||||||
let _prof_timer = self.prof.verbose_generic_activity("generate_crate_metadata");
|
let _prof_timer = self.prof.verbose_generic_activity("generate_crate_metadata");
|
||||||
self.cstore.encode_metadata(self)
|
self.untracked_resolutions.cstore.encode_metadata(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that this is *untracked* and should only be used within the query
|
// Note that this is *untracked* and should only be used within the query
|
||||||
// system if the result is otherwise tracked through queries
|
// system if the result is otherwise tracked through queries
|
||||||
pub fn cstore_as_any(self) -> &'tcx dyn Any {
|
pub fn cstore_as_any(self) -> &'tcx dyn Any {
|
||||||
self.cstore.as_any()
|
self.untracked_resolutions.cstore.as_any()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> {
|
pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> {
|
||||||
let krate = self.gcx.untracked_crate;
|
let krate = self.gcx.untracked_crate;
|
||||||
|
let resolutions = &self.gcx.untracked_resolutions;
|
||||||
|
|
||||||
StableHashingContext::new(self.sess, krate, &self.definitions, &*self.cstore)
|
StableHashingContext::new(self.sess, krate, &resolutions.definitions, &*resolutions.cstore)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn create_no_span_stable_hashing_context(self) -> StableHashingContext<'tcx> {
|
pub fn create_no_span_stable_hashing_context(self) -> StableHashingContext<'tcx> {
|
||||||
let krate = self.gcx.untracked_crate;
|
let krate = self.gcx.untracked_crate;
|
||||||
|
let resolutions = &self.gcx.untracked_resolutions;
|
||||||
|
|
||||||
StableHashingContext::ignore_spans(self.sess, krate, &self.definitions, &*self.cstore)
|
StableHashingContext::ignore_spans(
|
||||||
|
self.sess,
|
||||||
|
krate,
|
||||||
|
&resolutions.definitions,
|
||||||
|
&*resolutions.cstore,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize_query_result_cache(self, encoder: &mut FileEncoder) -> FileEncodeResult {
|
pub fn serialize_query_result_cache(self, encoder: &mut FileEncoder) -> FileEncodeResult {
|
||||||
|
@ -2821,15 +2803,19 @@ fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
|
||||||
|
|
||||||
pub fn provide(providers: &mut ty::query::Providers) {
|
pub fn provide(providers: &mut ty::query::Providers) {
|
||||||
providers.in_scope_traits_map = |tcx, id| tcx.hir_crate(()).trait_map.get(&id);
|
providers.in_scope_traits_map = |tcx, id| tcx.hir_crate(()).trait_map.get(&id);
|
||||||
providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).map(|v| &v[..]);
|
providers.resolutions = |tcx, ()| &tcx.untracked_resolutions;
|
||||||
|
providers.module_exports = |tcx, id| tcx.resolutions(()).export_map.get(&id).map(|v| &v[..]);
|
||||||
providers.crate_name = |tcx, id| {
|
providers.crate_name = |tcx, id| {
|
||||||
assert_eq!(id, LOCAL_CRATE);
|
assert_eq!(id, LOCAL_CRATE);
|
||||||
tcx.crate_name
|
tcx.crate_name
|
||||||
};
|
};
|
||||||
providers.maybe_unused_trait_import = |tcx, id| tcx.maybe_unused_trait_imports.contains(&id);
|
providers.maybe_unused_trait_import =
|
||||||
providers.maybe_unused_extern_crates = |tcx, ()| &tcx.maybe_unused_extern_crates[..];
|
|tcx, id| tcx.resolutions(()).maybe_unused_trait_imports.contains(&id);
|
||||||
providers.names_imported_by_glob_use =
|
providers.maybe_unused_extern_crates =
|
||||||
|tcx, id| tcx.arena.alloc(tcx.glob_map.get(&id).cloned().unwrap_or_default());
|
|tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..];
|
||||||
|
providers.names_imported_by_glob_use = |tcx, id| {
|
||||||
|
tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
|
||||||
|
};
|
||||||
|
|
||||||
providers.lookup_stability = |tcx, id| {
|
providers.lookup_stability = |tcx, id| {
|
||||||
let id = tcx.hir().local_def_id_to_hir_id(id.expect_local());
|
let id = tcx.hir().local_def_id_to_hir_id(id.expect_local());
|
||||||
|
@ -2843,8 +2829,10 @@ pub fn provide(providers: &mut ty::query::Providers) {
|
||||||
let id = tcx.hir().local_def_id_to_hir_id(id.expect_local());
|
let id = tcx.hir().local_def_id_to_hir_id(id.expect_local());
|
||||||
tcx.stability().local_deprecation_entry(id)
|
tcx.stability().local_deprecation_entry(id)
|
||||||
};
|
};
|
||||||
providers.extern_mod_stmt_cnum = |tcx, id| tcx.extern_crate_map.get(&id).cloned();
|
providers.extern_mod_stmt_cnum =
|
||||||
providers.crates = |tcx, ()| tcx.arena.alloc_slice(&tcx.cstore.crates_untracked());
|
|tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
|
||||||
|
providers.crates =
|
||||||
|
|tcx, ()| tcx.arena.alloc_slice(&tcx.resolutions(()).cstore.crates_untracked());
|
||||||
providers.output_filenames = |tcx, ()| tcx.output_filenames.clone();
|
providers.output_filenames = |tcx, ()| tcx.output_filenames.clone();
|
||||||
providers.features_query = |tcx, ()| tcx.sess.features_untracked();
|
providers.features_query = |tcx, ()| tcx.sess.features_untracked();
|
||||||
providers.is_panic_runtime = |tcx, cnum| {
|
providers.is_panic_runtime = |tcx, cnum| {
|
||||||
|
|
|
@ -113,6 +113,7 @@ mod sty;
|
||||||
|
|
||||||
// Data types
|
// Data types
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct ResolverOutputs {
|
pub struct ResolverOutputs {
|
||||||
pub definitions: rustc_hir::definitions::Definitions,
|
pub definitions: rustc_hir::definitions::Definitions,
|
||||||
pub cstore: Box<CrateStoreDyn>,
|
pub cstore: Box<CrateStoreDyn>,
|
||||||
|
|
|
@ -2313,7 +2313,7 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
|
||||||
let unique_symbols_rev: &mut FxHashMap<(Namespace, Symbol), Option<DefId>> =
|
let unique_symbols_rev: &mut FxHashMap<(Namespace, Symbol), Option<DefId>> =
|
||||||
&mut FxHashMap::default();
|
&mut FxHashMap::default();
|
||||||
|
|
||||||
for symbol_set in tcx.glob_map.values() {
|
for symbol_set in tcx.resolutions(()).glob_map.values() {
|
||||||
for symbol in symbol_set {
|
for symbol in symbol_set {
|
||||||
unique_symbols_rev.insert((Namespace::TypeNS, *symbol), None);
|
unique_symbols_rev.insert((Namespace::TypeNS, *symbol), None);
|
||||||
unique_symbols_rev.insert((Namespace::ValueNS, *symbol), None);
|
unique_symbols_rev.insert((Namespace::ValueNS, *symbol), None);
|
||||||
|
|
|
@ -584,7 +584,9 @@ impl<'sess> OnDiskCache<'sess> {
|
||||||
debug!("def_path_hash_to_def_id({:?})", hash);
|
debug!("def_path_hash_to_def_id({:?})", hash);
|
||||||
// Check if the `DefPathHash` corresponds to a definition in the current
|
// Check if the `DefPathHash` corresponds to a definition in the current
|
||||||
// crate
|
// crate
|
||||||
if let Some(def_id) = tcx.definitions.local_def_path_hash_to_def_id(hash) {
|
if let Some(def_id) =
|
||||||
|
tcx.untracked_resolutions.definitions.local_def_path_hash_to_def_id(hash)
|
||||||
|
{
|
||||||
let def_id = def_id.to_def_id();
|
let def_id = def_id.to_def_id();
|
||||||
e.insert(Some(def_id));
|
e.insert(Some(def_id));
|
||||||
return Some(def_id);
|
return Some(def_id);
|
||||||
|
@ -612,7 +614,11 @@ impl<'sess> OnDiskCache<'sess> {
|
||||||
debug_assert_ne!(krate, LOCAL_CRATE);
|
debug_assert_ne!(krate, LOCAL_CRATE);
|
||||||
// Try to find a definition in the current session, using the previous `DefIndex`
|
// Try to find a definition in the current session, using the previous `DefIndex`
|
||||||
// as an initial guess.
|
// as an initial guess.
|
||||||
let opt_def_id = tcx.cstore.def_path_hash_to_def_id(krate, raw_def_id.index, hash);
|
let opt_def_id = tcx.untracked_resolutions.cstore.def_path_hash_to_def_id(
|
||||||
|
krate,
|
||||||
|
raw_def_id.index,
|
||||||
|
hash,
|
||||||
|
);
|
||||||
debug!("def_path_to_def_id({:?}): opt_def_id = {:?}", hash, opt_def_id);
|
debug!("def_path_to_def_id({:?}): opt_def_id = {:?}", hash, opt_def_id);
|
||||||
e.insert(opt_def_id);
|
e.insert(opt_def_id);
|
||||||
opt_def_id
|
opt_def_id
|
||||||
|
|
|
@ -147,33 +147,36 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De
|
||||||
Some((tcx.hir().local_def_id(hir_id).to_def_id(), EntryFnType::Start))
|
Some((tcx.hir().local_def_id(hir_id).to_def_id(), EntryFnType::Start))
|
||||||
} else if let Some((hir_id, _)) = visitor.attr_main_fn {
|
} else if let Some((hir_id, _)) = visitor.attr_main_fn {
|
||||||
Some((tcx.hir().local_def_id(hir_id).to_def_id(), EntryFnType::Main))
|
Some((tcx.hir().local_def_id(hir_id).to_def_id(), EntryFnType::Main))
|
||||||
} else if let Some(def_id) = tcx.main_def.and_then(|main_def| main_def.opt_fn_def_id()) {
|
} else {
|
||||||
// non-local main imports are handled below
|
if let Some(main_def) = tcx.resolutions(()).main_def {
|
||||||
if def_id.is_local() {
|
if let Some(def_id) = main_def.opt_fn_def_id() {
|
||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
// non-local main imports are handled below
|
||||||
if matches!(tcx.hir().find(hir_id), Some(Node::ForeignItem(_))) {
|
if def_id.is_local() {
|
||||||
tcx.sess
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||||
.struct_span_err(
|
if matches!(tcx.hir().find(hir_id), Some(Node::ForeignItem(_))) {
|
||||||
tcx.hir().span(hir_id),
|
tcx.sess
|
||||||
"the `main` function cannot be declared in an `extern` block",
|
.struct_span_err(
|
||||||
|
tcx.hir().span(hir_id),
|
||||||
|
"the `main` function cannot be declared in an `extern` block",
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if main_def.is_import && !tcx.features().imported_main {
|
||||||
|
let span = main_def.span;
|
||||||
|
feature_err(
|
||||||
|
&tcx.sess.parse_sess,
|
||||||
|
sym::imported_main,
|
||||||
|
span,
|
||||||
|
"using an imported function as entry point `main` is experimental",
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
return None;
|
}
|
||||||
|
return Some((def_id, EntryFnType::Main));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if tcx.main_def.unwrap().is_import && !tcx.features().imported_main {
|
|
||||||
let span = tcx.main_def.unwrap().span;
|
|
||||||
feature_err(
|
|
||||||
&tcx.sess.parse_sess,
|
|
||||||
sym::imported_main,
|
|
||||||
span,
|
|
||||||
"using an imported function as entry point `main` is experimental",
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
|
||||||
Some((def_id, EntryFnType::Main))
|
|
||||||
} else {
|
|
||||||
no_main_err(tcx, visitor);
|
no_main_err(tcx, visitor);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -223,7 +226,7 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) {
|
||||||
err.note(¬e);
|
err.note(¬e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(main_def) = tcx.main_def {
|
if let Some(main_def) = tcx.resolutions(()).main_def {
|
||||||
if main_def.opt_fn_def_id().is_none() {
|
if main_def.opt_fn_def_id().is_none() {
|
||||||
// There is something at `crate::main`, but it is not a function definition.
|
// There is something at `crate::main`, but it is not a function definition.
|
||||||
err.span_label(main_def.span, &format!("non-function item at `crate::main` is found"));
|
err.span_label(main_def.span, &format!("non-function item at `crate::main` is found"));
|
||||||
|
|
|
@ -2031,7 +2031,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
|
|
||||||
fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
|
fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
|
||||||
let def_id = def_id.expect_local();
|
let def_id = def_id.expect_local();
|
||||||
match tcx.visibilities.get(&def_id) {
|
match tcx.resolutions(()).visibilities.get(&def_id) {
|
||||||
Some(vis) => *vis,
|
Some(vis) => *vis,
|
||||||
None => {
|
None => {
|
||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
|
|
|
@ -116,6 +116,8 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
|
||||||
crates_to_lint: &mut crates_to_lint,
|
crates_to_lint: &mut crates_to_lint,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let extern_prelude = &tcx.resolutions(()).extern_prelude;
|
||||||
|
|
||||||
for extern_crate in &crates_to_lint {
|
for extern_crate in &crates_to_lint {
|
||||||
let def_id = extern_crate.def_id.expect_local();
|
let def_id = extern_crate.def_id.expect_local();
|
||||||
let id = tcx.hir().local_def_id_to_hir_id(def_id);
|
let id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
|
@ -155,7 +157,7 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
|
||||||
// If the extern crate isn't in the extern prelude,
|
// If the extern crate isn't in the extern prelude,
|
||||||
// there is no way it can be written as an `use`.
|
// there is no way it can be written as an `use`.
|
||||||
let orig_name = extern_crate.orig_name.unwrap_or(item.ident.name);
|
let orig_name = extern_crate.orig_name.unwrap_or(item.ident.name);
|
||||||
if !tcx.extern_prelude.get(&orig_name).map_or(false, |from_item| !from_item) {
|
if !extern_prelude.get(&orig_name).map_or(false, |from_item| !from_item) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue