Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c531545

Browse files
authoredAug 16, 2020
Rollup merge of rust-lang#74346 - eddyb:reachable-defs, r=nikomatsakis
Use LocalDefId instead of HirId for reachable_set elements. The only `HirId`s being tracked there that don't have matching `DefId`s are local variables, and that's an accident from rust-lang#44316 (where I preserved the old behavior, even if nothing relied on reachability tracking local variables).
2 parents 772038d + 8b86b28 commit c531545

File tree

4 files changed

+55
-57
lines changed

4 files changed

+55
-57
lines changed
 

‎src/librustc_codegen_ssa/back/symbol_export.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
6161
let mut reachable_non_generics: DefIdMap<_> = tcx
6262
.reachable_set(LOCAL_CRATE)
6363
.iter()
64-
.filter_map(|&hir_id| {
64+
.filter_map(|&def_id| {
6565
// We want to ignore some FFI functions that are not exposed from
6666
// this crate. Reachable FFI functions can be lumped into two
6767
// categories:
@@ -75,9 +75,8 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
7575
//
7676
// As a result, if this id is an FFI item (foreign item) then we only
7777
// let it through if it's included statically.
78-
match tcx.hir().get(hir_id) {
78+
match tcx.hir().get(tcx.hir().local_def_id_to_hir_id(def_id)) {
7979
Node::ForeignItem(..) => {
80-
let def_id = tcx.hir().local_def_id(hir_id);
8180
tcx.is_statically_included_foreign_item(def_id).then_some(def_id)
8281
}
8382

@@ -87,7 +86,6 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
8786
..
8887
})
8988
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) => {
90-
let def_id = tcx.hir().local_def_id(hir_id);
9189
let generics = tcx.generics_of(def_id);
9290
if !generics.requires_monomorphization(tcx)
9391
// Functions marked with #[inline] are codegened with "internal"
@@ -361,7 +359,7 @@ fn upstream_drop_glue_for_provider<'tcx>(
361359

362360
fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
363361
if let Some(def_id) = def_id.as_local() {
364-
!tcx.reachable_set(LOCAL_CRATE).contains(&tcx.hir().local_def_id_to_hir_id(def_id))
362+
!tcx.reachable_set(LOCAL_CRATE).contains(&def_id)
365363
} else {
366364
bug!("is_unreachable_local_definition called with non-local DefId: {:?}", def_id)
367365
}

‎src/librustc_middle/query/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,8 @@ rustc_queries! {
740740
}
741741

742742
Other {
743-
query reachable_set(_: CrateNum) -> &'tcx HirIdSet {
743+
query reachable_set(_: CrateNum) -> FxHashSet<LocalDefId> {
744+
storage(ArenaCacheSelector<'tcx>)
744745
desc { "reachability" }
745746
}
746747

‎src/librustc_middle/ty/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use rustc_hir as hir;
4343
use rustc_hir::def::DefKind;
4444
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
4545
use rustc_hir::lang_items::{LangItem, LanguageItems};
46-
use rustc_hir::{Crate, HirIdSet, ItemLocalId, TraitCandidate};
46+
use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
4747
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
4848
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
4949
use rustc_session::utils::NativeLibKind;

‎src/librustc_passes/reachable.rs

+49-50
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ use rustc_hir::def_id::LOCAL_CRATE;
1212
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
1313
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
1414
use rustc_hir::itemlikevisit::ItemLikeVisitor;
15-
use rustc_hir::{HirIdSet, Node};
15+
use rustc_hir::Node;
1616
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
1717
use rustc_middle::middle::privacy;
1818
use rustc_middle::ty::query::Providers;
19-
use rustc_middle::ty::{self, TyCtxt};
19+
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
2020
use rustc_session::config::CrateType;
2121
use rustc_target::spec::abi::Abi;
2222

@@ -65,10 +65,11 @@ struct ReachableContext<'tcx> {
6565
tcx: TyCtxt<'tcx>,
6666
maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
6767
// The set of items which must be exported in the linkage sense.
68-
reachable_symbols: HirIdSet,
68+
reachable_symbols: FxHashSet<LocalDefId>,
6969
// A worklist of item IDs. Each item ID in this worklist will be inlined
7070
// and will be scanned for further references.
71-
worklist: Vec<hir::HirId>,
71+
// FIXME(eddyb) benchmark if this would be faster as a `VecDeque`.
72+
worklist: Vec<LocalDefId>,
7273
// Whether any output of this compilation is a library
7374
any_library: bool,
7475
}
@@ -100,37 +101,27 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> {
100101
_ => None,
101102
};
102103

103-
match res {
104-
Some(Res::Local(hir_id)) => {
105-
self.reachable_symbols.insert(hir_id);
106-
}
107-
Some(res) => {
108-
if let Some((hir_id, def_id)) = res.opt_def_id().and_then(|def_id| {
109-
def_id
110-
.as_local()
111-
.map(|def_id| (self.tcx.hir().local_def_id_to_hir_id(def_id), def_id))
112-
}) {
113-
if self.def_id_represents_local_inlined_item(def_id.to_def_id()) {
114-
self.worklist.push(hir_id);
115-
} else {
116-
match res {
117-
// If this path leads to a constant, then we need to
118-
// recurse into the constant to continue finding
119-
// items that are reachable.
120-
Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
121-
self.worklist.push(hir_id);
122-
}
104+
if let Some(res) = res {
105+
if let Some(def_id) = res.opt_def_id().and_then(|def_id| def_id.as_local()) {
106+
if self.def_id_represents_local_inlined_item(def_id.to_def_id()) {
107+
self.worklist.push(def_id);
108+
} else {
109+
match res {
110+
// If this path leads to a constant, then we need to
111+
// recurse into the constant to continue finding
112+
// items that are reachable.
113+
Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
114+
self.worklist.push(def_id);
115+
}
123116

124-
// If this wasn't a static, then the destination is
125-
// surely reachable.
126-
_ => {
127-
self.reachable_symbols.insert(hir_id);
128-
}
117+
// If this wasn't a static, then the destination is
118+
// surely reachable.
119+
_ => {
120+
self.reachable_symbols.insert(def_id);
129121
}
130122
}
131123
}
132124
}
133-
_ => {}
134125
}
135126

136127
intravisit::walk_expr(self, expr)
@@ -209,13 +200,15 @@ impl<'tcx> ReachableContext<'tcx> {
209200
continue;
210201
}
211202

212-
if let Some(ref item) = self.tcx.hir().find(search_item) {
203+
if let Some(ref item) =
204+
self.tcx.hir().find(self.tcx.hir().local_def_id_to_hir_id(search_item))
205+
{
213206
self.propagate_node(item, search_item);
214207
}
215208
}
216209
}
217210

218-
fn propagate_node(&mut self, node: &Node<'tcx>, search_item: hir::HirId) {
211+
fn propagate_node(&mut self, node: &Node<'tcx>, search_item: LocalDefId) {
219212
if !self.any_library {
220213
// If we are building an executable, only explicitly extern
221214
// types need to be exported.
@@ -297,8 +290,9 @@ impl<'tcx> ReachableContext<'tcx> {
297290
self.visit_nested_body(body);
298291
}
299292
hir::ImplItemKind::Fn(_, body) => {
300-
let did = self.tcx.hir().get_parent_did(search_item);
301-
if method_might_be_inlined(self.tcx, impl_item, did) {
293+
let impl_def_id =
294+
self.tcx.parent(search_item.to_def_id()).unwrap().expect_local();
295+
if method_might_be_inlined(self.tcx, impl_item, impl_def_id) {
302296
self.visit_nested_body(body)
303297
}
304298
}
@@ -317,7 +311,9 @@ impl<'tcx> ReachableContext<'tcx> {
317311
_ => {
318312
bug!(
319313
"found unexpected node kind in worklist: {} ({:?})",
320-
self.tcx.hir().node_to_string(search_item),
314+
self.tcx
315+
.hir()
316+
.node_to_string(self.tcx.hir().local_def_id_to_hir_id(search_item)),
321317
node,
322318
);
323319
}
@@ -336,7 +332,7 @@ impl<'tcx> ReachableContext<'tcx> {
336332
struct CollectPrivateImplItemsVisitor<'a, 'tcx> {
337333
tcx: TyCtxt<'tcx>,
338334
access_levels: &'a privacy::AccessLevels,
339-
worklist: &'a mut Vec<hir::HirId>,
335+
worklist: &'a mut Vec<LocalDefId>,
340336
}
341337

342338
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
@@ -349,13 +345,16 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
349345
if codegen_attrs.contains_extern_indicator()
350346
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
351347
{
352-
self.worklist.push(item.hir_id);
348+
self.worklist.push(def_id);
353349
}
354350

355351
// We need only trait impls here, not inherent impls, and only non-exported ones
356352
if let hir::ItemKind::Impl { of_trait: Some(ref trait_ref), ref items, .. } = item.kind {
357353
if !self.access_levels.is_reachable(item.hir_id) {
358-
self.worklist.extend(items.iter().map(|ii_ref| ii_ref.id.hir_id));
354+
// FIXME(#53488) remove `let`
355+
let tcx = self.tcx;
356+
self.worklist
357+
.extend(items.iter().map(|ii_ref| tcx.hir().local_def_id(ii_ref.id.hir_id)));
359358

360359
let trait_def_id = match trait_ref.path.res {
361360
Res::Def(DefKind::Trait, def_id) => def_id,
@@ -366,12 +365,10 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
366365
return;
367366
}
368367

369-
// FIXME(#53488) remove `let`
370-
let tcx = self.tcx;
371-
self.worklist
372-
.extend(tcx.provided_trait_methods(trait_def_id).map(|assoc| {
373-
tcx.hir().local_def_id_to_hir_id(assoc.def_id.expect_local())
374-
}));
368+
self.worklist.extend(
369+
tcx.provided_trait_methods(trait_def_id)
370+
.map(|assoc| assoc.def_id.expect_local()),
371+
);
375372
}
376373
}
377374
}
@@ -383,7 +380,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
383380
}
384381
}
385382

386-
fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet {
383+
fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> FxHashSet<LocalDefId> {
387384
debug_assert!(crate_num == LOCAL_CRATE);
388385

389386
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
405402
// If other crates link to us, they're going to expect to be able to
406403
// use the lang items, so we need to be sure to mark them as
407404
// exported.
408-
reachable_context.worklist.extend(access_levels.map.iter().map(|(id, _)| *id));
405+
reachable_context
406+
.worklist
407+
.extend(access_levels.map.iter().map(|(id, _)| tcx.hir().local_def_id(*id)));
409408
for item in tcx.lang_items().items().iter() {
410-
if let Some(did) = *item {
411-
if let Some(hir_id) = did.as_local().map(|did| tcx.hir().local_def_id_to_hir_id(did)) {
412-
reachable_context.worklist.push(hir_id);
409+
if let Some(def_id) = *item {
410+
if let Some(def_id) = def_id.as_local() {
411+
reachable_context.worklist.push(def_id);
413412
}
414413
}
415414
}
@@ -428,7 +427,7 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet
428427
debug!("Inline reachability shows: {:?}", reachable_context.reachable_symbols);
429428

430429
// Return the set of reachable symbols.
431-
tcx.arena.alloc(reachable_context.reachable_symbols)
430+
reachable_context.reachable_symbols
432431
}
433432

434433
pub fn provide(providers: &mut Providers) {

0 commit comments

Comments
 (0)
Please sign in to comment.