Use LocalDefId instead of HirId for reachable_set elements.
This commit is contained in:
parent
7a4fb355c6
commit
8b86b28f50
4 changed files with 55 additions and 57 deletions
|
@ -61,7 +61,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
|
||||||
let mut reachable_non_generics: DefIdMap<_> = tcx
|
let mut reachable_non_generics: DefIdMap<_> = tcx
|
||||||
.reachable_set(LOCAL_CRATE)
|
.reachable_set(LOCAL_CRATE)
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|&hir_id| {
|
.filter_map(|&def_id| {
|
||||||
// We want to ignore some FFI functions that are not exposed from
|
// We want to ignore some FFI functions that are not exposed from
|
||||||
// this crate. Reachable FFI functions can be lumped into two
|
// this crate. Reachable FFI functions can be lumped into two
|
||||||
// categories:
|
// categories:
|
||||||
|
@ -75,9 +75,8 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
|
||||||
//
|
//
|
||||||
// As a result, if this id is an FFI item (foreign item) then we only
|
// As a result, if this id is an FFI item (foreign item) then we only
|
||||||
// let it through if it's included statically.
|
// let it through if it's included statically.
|
||||||
match tcx.hir().get(hir_id) {
|
match tcx.hir().get(tcx.hir().local_def_id_to_hir_id(def_id)) {
|
||||||
Node::ForeignItem(..) => {
|
Node::ForeignItem(..) => {
|
||||||
let def_id = tcx.hir().local_def_id(hir_id);
|
|
||||||
tcx.is_statically_included_foreign_item(def_id).then_some(def_id)
|
tcx.is_statically_included_foreign_item(def_id).then_some(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +86,6 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
|
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
|
||||||
let def_id = tcx.hir().local_def_id(hir_id);
|
|
||||||
let generics = tcx.generics_of(def_id);
|
let generics = tcx.generics_of(def_id);
|
||||||
if !generics.requires_monomorphization(tcx)
|
if !generics.requires_monomorphization(tcx)
|
||||||
// Functions marked with #[inline] are codegened with "internal"
|
// Functions marked with #[inline] are codegened with "internal"
|
||||||
|
@ -361,7 +359,7 @@ fn upstream_drop_glue_for_provider<'tcx>(
|
||||||
|
|
||||||
fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
if let Some(def_id) = def_id.as_local() {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
!tcx.reachable_set(LOCAL_CRATE).contains(&tcx.hir().local_def_id_to_hir_id(def_id))
|
!tcx.reachable_set(LOCAL_CRATE).contains(&def_id)
|
||||||
} else {
|
} else {
|
||||||
bug!("is_unreachable_local_definition called with non-local DefId: {:?}", def_id)
|
bug!("is_unreachable_local_definition called with non-local DefId: {:?}", def_id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -740,7 +740,8 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
|
|
||||||
Other {
|
Other {
|
||||||
query reachable_set(_: CrateNum) -> &'tcx HirIdSet {
|
query reachable_set(_: CrateNum) -> FxHashSet<LocalDefId> {
|
||||||
|
storage(ArenaCacheSelector<'tcx>)
|
||||||
desc { "reachability" }
|
desc { "reachability" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
|
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
|
||||||
use rustc_hir::lang_items::{LangItem, LanguageItems};
|
use rustc_hir::lang_items::{LangItem, LanguageItems};
|
||||||
use rustc_hir::{Crate, HirIdSet, ItemLocalId, TraitCandidate};
|
use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
|
||||||
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
|
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
|
||||||
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
|
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
|
||||||
use rustc_session::utils::NativeLibKind;
|
use rustc_session::utils::NativeLibKind;
|
||||||
|
|
|
@ -12,11 +12,11 @@ use rustc_hir::def_id::LOCAL_CRATE;
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
|
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
|
||||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
||||||
use rustc_hir::{HirIdSet, Node};
|
use rustc_hir::Node;
|
||||||
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
||||||
use rustc_middle::middle::privacy;
|
use rustc_middle::middle::privacy;
|
||||||
use rustc_middle::ty::query::Providers;
|
use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
|
||||||
use rustc_session::config::CrateType;
|
use rustc_session::config::CrateType;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
|
@ -65,10 +65,11 @@ struct ReachableContext<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
|
maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
|
||||||
// The set of items which must be exported in the linkage sense.
|
// The set of items which must be exported in the linkage sense.
|
||||||
reachable_symbols: HirIdSet,
|
reachable_symbols: FxHashSet<LocalDefId>,
|
||||||
// A worklist of item IDs. Each item ID in this worklist will be inlined
|
// A worklist of item IDs. Each item ID in this worklist will be inlined
|
||||||
// and will be scanned for further references.
|
// and will be scanned for further references.
|
||||||
worklist: Vec<hir::HirId>,
|
// FIXME(eddyb) benchmark if this would be faster as a `VecDeque`.
|
||||||
|
worklist: Vec<LocalDefId>,
|
||||||
// Whether any output of this compilation is a library
|
// Whether any output of this compilation is a library
|
||||||
any_library: bool,
|
any_library: bool,
|
||||||
}
|
}
|
||||||
|
@ -100,37 +101,27 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> {
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
match res {
|
if let Some(res) = res {
|
||||||
Some(Res::Local(hir_id)) => {
|
if let Some(def_id) = res.opt_def_id().and_then(|def_id| def_id.as_local()) {
|
||||||
self.reachable_symbols.insert(hir_id);
|
if self.def_id_represents_local_inlined_item(def_id.to_def_id()) {
|
||||||
}
|
self.worklist.push(def_id);
|
||||||
Some(res) => {
|
} else {
|
||||||
if let Some((hir_id, def_id)) = res.opt_def_id().and_then(|def_id| {
|
match res {
|
||||||
def_id
|
// If this path leads to a constant, then we need to
|
||||||
.as_local()
|
// recurse into the constant to continue finding
|
||||||
.map(|def_id| (self.tcx.hir().local_def_id_to_hir_id(def_id), def_id))
|
// items that are reachable.
|
||||||
}) {
|
Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
|
||||||
if self.def_id_represents_local_inlined_item(def_id.to_def_id()) {
|
self.worklist.push(def_id);
|
||||||
self.worklist.push(hir_id);
|
}
|
||||||
} else {
|
|
||||||
match res {
|
|
||||||
// If this path leads to a constant, then we need to
|
|
||||||
// recurse into the constant to continue finding
|
|
||||||
// items that are reachable.
|
|
||||||
Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
|
|
||||||
self.worklist.push(hir_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this wasn't a static, then the destination is
|
// If this wasn't a static, then the destination is
|
||||||
// surely reachable.
|
// surely reachable.
|
||||||
_ => {
|
_ => {
|
||||||
self.reachable_symbols.insert(hir_id);
|
self.reachable_symbols.insert(def_id);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
intravisit::walk_expr(self, expr)
|
intravisit::walk_expr(self, expr)
|
||||||
|
@ -209,13 +200,15 @@ impl<'tcx> ReachableContext<'tcx> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref item) = self.tcx.hir().find(search_item) {
|
if let Some(ref item) =
|
||||||
|
self.tcx.hir().find(self.tcx.hir().local_def_id_to_hir_id(search_item))
|
||||||
|
{
|
||||||
self.propagate_node(item, search_item);
|
self.propagate_node(item, search_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn propagate_node(&mut self, node: &Node<'tcx>, search_item: hir::HirId) {
|
fn propagate_node(&mut self, node: &Node<'tcx>, search_item: LocalDefId) {
|
||||||
if !self.any_library {
|
if !self.any_library {
|
||||||
// If we are building an executable, only explicitly extern
|
// If we are building an executable, only explicitly extern
|
||||||
// types need to be exported.
|
// types need to be exported.
|
||||||
|
@ -297,8 +290,9 @@ impl<'tcx> ReachableContext<'tcx> {
|
||||||
self.visit_nested_body(body);
|
self.visit_nested_body(body);
|
||||||
}
|
}
|
||||||
hir::ImplItemKind::Fn(_, body) => {
|
hir::ImplItemKind::Fn(_, body) => {
|
||||||
let did = self.tcx.hir().get_parent_did(search_item);
|
let impl_def_id =
|
||||||
if method_might_be_inlined(self.tcx, impl_item, did) {
|
self.tcx.parent(search_item.to_def_id()).unwrap().expect_local();
|
||||||
|
if method_might_be_inlined(self.tcx, impl_item, impl_def_id) {
|
||||||
self.visit_nested_body(body)
|
self.visit_nested_body(body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -317,7 +311,9 @@ impl<'tcx> ReachableContext<'tcx> {
|
||||||
_ => {
|
_ => {
|
||||||
bug!(
|
bug!(
|
||||||
"found unexpected node kind in worklist: {} ({:?})",
|
"found unexpected node kind in worklist: {} ({:?})",
|
||||||
self.tcx.hir().node_to_string(search_item),
|
self.tcx
|
||||||
|
.hir()
|
||||||
|
.node_to_string(self.tcx.hir().local_def_id_to_hir_id(search_item)),
|
||||||
node,
|
node,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -336,7 +332,7 @@ impl<'tcx> ReachableContext<'tcx> {
|
||||||
struct CollectPrivateImplItemsVisitor<'a, 'tcx> {
|
struct CollectPrivateImplItemsVisitor<'a, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
access_levels: &'a privacy::AccessLevels,
|
access_levels: &'a privacy::AccessLevels,
|
||||||
worklist: &'a mut Vec<hir::HirId>,
|
worklist: &'a mut Vec<LocalDefId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
|
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
|
||||||
|
@ -349,13 +345,16 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
|
||||||
if codegen_attrs.contains_extern_indicator()
|
if codegen_attrs.contains_extern_indicator()
|
||||||
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
|
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
|
||||||
{
|
{
|
||||||
self.worklist.push(item.hir_id);
|
self.worklist.push(def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need only trait impls here, not inherent impls, and only non-exported ones
|
// We need only trait impls here, not inherent impls, and only non-exported ones
|
||||||
if let hir::ItemKind::Impl { of_trait: Some(ref trait_ref), ref items, .. } = item.kind {
|
if let hir::ItemKind::Impl { of_trait: Some(ref trait_ref), ref items, .. } = item.kind {
|
||||||
if !self.access_levels.is_reachable(item.hir_id) {
|
if !self.access_levels.is_reachable(item.hir_id) {
|
||||||
self.worklist.extend(items.iter().map(|ii_ref| ii_ref.id.hir_id));
|
// FIXME(#53488) remove `let`
|
||||||
|
let tcx = self.tcx;
|
||||||
|
self.worklist
|
||||||
|
.extend(items.iter().map(|ii_ref| tcx.hir().local_def_id(ii_ref.id.hir_id)));
|
||||||
|
|
||||||
let trait_def_id = match trait_ref.path.res {
|
let trait_def_id = match trait_ref.path.res {
|
||||||
Res::Def(DefKind::Trait, def_id) => def_id,
|
Res::Def(DefKind::Trait, def_id) => def_id,
|
||||||
|
@ -366,12 +365,10 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(#53488) remove `let`
|
self.worklist.extend(
|
||||||
let tcx = self.tcx;
|
tcx.provided_trait_methods(trait_def_id)
|
||||||
self.worklist
|
.map(|assoc| assoc.def_id.expect_local()),
|
||||||
.extend(tcx.provided_trait_methods(trait_def_id).map(|assoc| {
|
);
|
||||||
tcx.hir().local_def_id_to_hir_id(assoc.def_id.expect_local())
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,7 +380,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet {
|
fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> FxHashSet<LocalDefId> {
|
||||||
debug_assert!(crate_num == LOCAL_CRATE);
|
debug_assert!(crate_num == LOCAL_CRATE);
|
||||||
|
|
||||||
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
|
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
|
||||||
|
@ -405,11 +402,13 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet
|
||||||
// If other crates link to us, they're going to expect to be able to
|
// If other crates link to us, they're going to expect to be able to
|
||||||
// use the lang items, so we need to be sure to mark them as
|
// use the lang items, so we need to be sure to mark them as
|
||||||
// exported.
|
// exported.
|
||||||
reachable_context.worklist.extend(access_levels.map.iter().map(|(id, _)| *id));
|
reachable_context
|
||||||
|
.worklist
|
||||||
|
.extend(access_levels.map.iter().map(|(id, _)| tcx.hir().local_def_id(*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(def_id) = *item {
|
||||||
if let Some(hir_id) = did.as_local().map(|did| tcx.hir().local_def_id_to_hir_id(did)) {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
reachable_context.worklist.push(hir_id);
|
reachable_context.worklist.push(def_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -428,7 +427,7 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet
|
||||||
debug!("Inline reachability shows: {:?}", reachable_context.reachable_symbols);
|
debug!("Inline reachability shows: {:?}", reachable_context.reachable_symbols);
|
||||||
|
|
||||||
// Return the set of reachable symbols.
|
// Return the set of reachable symbols.
|
||||||
tcx.arena.alloc(reachable_context.reachable_symbols)
|
reachable_context.reachable_symbols
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue