Skip to content

Commit 0a029e2

Browse files
committed
remove CollectPrivateImplItemsVisitor
Signed-off-by: Miguel Guarniz <mi9uel9@gmail.com>
1 parent 45c37da commit 0a029e2

File tree

1 file changed

+57
-70
lines changed

1 file changed

+57
-70
lines changed

compiler/rustc_passes/src/reachable.rs

Lines changed: 57 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use rustc_hir as hir;
1010
use rustc_hir::def::{DefKind, Res};
1111
use rustc_hir::def_id::{DefId, LocalDefId};
1212
use rustc_hir::intravisit::{self, Visitor};
13-
use rustc_hir::itemlikevisit::ItemLikeVisitor;
1413
use rustc_hir::Node;
1514
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
1615
use rustc_middle::middle::privacy;
@@ -314,79 +313,56 @@ impl<'tcx> ReachableContext<'tcx> {
314313
}
315314
}
316315

317-
// Some methods from non-exported (completely private) trait impls still have to be
318-
// reachable if they are called from inlinable code. Generally, it's not known until
319-
// monomorphization if a specific trait impl item can be reachable or not. So, we
320-
// conservatively mark all of them as reachable.
321-
// FIXME: One possible strategy for pruning the reachable set is to avoid marking impl
322-
// items of non-exported traits (or maybe all local traits?) unless their respective
323-
// trait items are used from inlinable code through method call syntax or UFCS, or their
324-
// trait is a lang item.
325-
struct CollectPrivateImplItemsVisitor<'a, 'tcx> {
316+
fn check_item<'tcx>(
326317
tcx: TyCtxt<'tcx>,
327-
access_levels: &'a privacy::AccessLevels,
328-
worklist: &'a mut Vec<LocalDefId>,
329-
}
318+
item: &hir::Item<'_>,
319+
worklist: &mut Vec<LocalDefId>,
320+
access_levels: &privacy::AccessLevels
321+
) {
322+
push_to_worklist_if_has_custom_linkage(tcx, worklist, item.def_id);
323+
324+
// We need only trait impls here, not inherent impls, and only non-exported ones
325+
if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) =
326+
item.kind
327+
{
328+
if !access_levels.is_reachable(item.def_id) {
329+
// FIXME(#53488) remove `let`
330+
let tcx = tcx;
331+
worklist.extend(items.iter().map(|ii_ref| ii_ref.id.def_id));
330332

331-
impl CollectPrivateImplItemsVisitor<'_, '_> {
332-
fn push_to_worklist_if_has_custom_linkage(&mut self, def_id: LocalDefId) {
333-
// Anything which has custom linkage gets thrown on the worklist no
334-
// matter where it is in the crate, along with "special std symbols"
335-
// which are currently akin to allocator symbols.
336-
if self.tcx.def_kind(def_id).has_codegen_attrs() {
337-
let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
338-
if codegen_attrs.contains_extern_indicator()
339-
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
340-
// FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by
341-
// `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their
342-
// `SymbolExportLevel::Rust` export level but may end up being exported in dylibs.
343-
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED)
344-
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
345-
{
346-
self.worklist.push(def_id);
333+
let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res else {
334+
unreachable!();
335+
};
336+
337+
if !trait_def_id.is_local() {
338+
return;
347339
}
340+
341+
worklist.extend(
342+
tcx.provided_trait_methods(trait_def_id)
343+
.map(|assoc| assoc.def_id.expect_local()),
344+
);
348345
}
349346
}
350347
}
351348

352-
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
353-
fn visit_item(&mut self, item: &hir::Item<'_>) {
354-
self.push_to_worklist_if_has_custom_linkage(item.def_id);
355-
356-
// We need only trait impls here, not inherent impls, and only non-exported ones
357-
if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) =
358-
item.kind
349+
fn push_to_worklist_if_has_custom_linkage<'tcx>(tcx: TyCtxt<'tcx>, worklist: &mut Vec<LocalDefId>, def_id: LocalDefId) {
350+
// Anything which has custom linkage gets thrown on the worklist no
351+
// matter where it is in the crate, along with "special std symbols"
352+
// which are currently akin to allocator symbols.
353+
if tcx.def_kind(def_id).has_codegen_attrs() {
354+
let codegen_attrs = tcx.codegen_fn_attrs(def_id);
355+
if codegen_attrs.contains_extern_indicator()
356+
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
357+
// FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by
358+
// `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their
359+
// `SymbolExportLevel::Rust` export level but may end up being exported in dylibs.
360+
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED)
361+
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
359362
{
360-
if !self.access_levels.is_reachable(item.def_id) {
361-
// FIXME(#53488) remove `let`
362-
let tcx = self.tcx;
363-
self.worklist.extend(items.iter().map(|ii_ref| ii_ref.id.def_id));
364-
365-
let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res else {
366-
unreachable!();
367-
};
368-
369-
if !trait_def_id.is_local() {
370-
return;
371-
}
372-
373-
self.worklist.extend(
374-
tcx.provided_trait_methods(trait_def_id)
375-
.map(|assoc| assoc.def_id.expect_local()),
376-
);
377-
}
363+
worklist.push(def_id);
378364
}
379365
}
380-
381-
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
382-
383-
fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) {
384-
self.push_to_worklist_if_has_custom_linkage(impl_item.def_id);
385-
}
386-
387-
fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {
388-
// We never export foreign functions as they have no body to export.
389-
}
390366
}
391367

392368
fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet<LocalDefId> {
@@ -418,12 +394,23 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet<LocalDefId> {
418394
}
419395
}
420396
{
421-
let mut collect_private_impl_items = CollectPrivateImplItemsVisitor {
422-
tcx,
423-
access_levels,
424-
worklist: &mut reachable_context.worklist,
425-
};
426-
tcx.hir().visit_all_item_likes(&mut collect_private_impl_items);
397+
// Some methods from non-exported (completely private) trait impls still have to be
398+
// reachable if they are called from inlinable code. Generally, it's not known until
399+
// monomorphization if a specific trait impl item can be reachable or not. So, we
400+
// conservatively mark all of them as reachable.
401+
// FIXME: One possible strategy for pruning the reachable set is to avoid marking impl
402+
// items of non-exported traits (or maybe all local traits?) unless their respective
403+
// trait items are used from inlinable code through method call syntax or UFCS, or their
404+
// trait is a lang item.
405+
let crate_items = tcx.hir_crate_items(());
406+
407+
for id in crate_items.items() {
408+
check_item(tcx, tcx.hir().item(id), &mut reachable_context.worklist, access_levels);
409+
}
410+
411+
for id in crate_items.impl_items() {
412+
push_to_worklist_if_has_custom_linkage(tcx, &mut reachable_context.worklist, id.def_id)
413+
}
427414
}
428415

429416
// Step 2: Mark all symbols that the symbols on the worklist touch.

0 commit comments

Comments
 (0)