From 90685c633357054dac6a91ecd0c14cbfc7a726a7 Mon Sep 17 00:00:00 2001 From: Miguel Guarniz Date: Wed, 4 May 2022 16:34:24 -0400 Subject: [PATCH] check def_kind before fetching item Signed-off-by: Miguel Guarniz --- compiler/rustc_passes/src/reachable.rs | 48 +++++++++++++++----------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 88ca48eae3e..0ded6a421f5 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -315,15 +315,22 @@ fn propagate_node(&mut self, node: &Node<'tcx>, search_item: LocalDefId) { fn check_item<'tcx>( tcx: TyCtxt<'tcx>, - item: &hir::Item<'_>, + id: hir::ItemId, worklist: &mut Vec, - access_levels: &privacy::AccessLevels + access_levels: &privacy::AccessLevels, ) { - push_to_worklist_if_has_custom_linkage(tcx, worklist, item.def_id); + if has_custom_linkage(tcx, id.def_id) { + worklist.push(id.def_id); + } + + if !matches!(tcx.def_kind(id.def_id), DefKind::Impl) { + return; + } // We need only trait impls here, not inherent impls, and only non-exported ones + let item = tcx.hir().item(id); if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) = - item.kind + item.kind { if !access_levels.is_reachable(item.def_id) { // FIXME(#53488) remove `let` @@ -339,30 +346,27 @@ fn check_item<'tcx>( } worklist.extend( - tcx.provided_trait_methods(trait_def_id) - .map(|assoc| assoc.def_id.expect_local()), + tcx.provided_trait_methods(trait_def_id).map(|assoc| assoc.def_id.expect_local()), ); } } } -fn push_to_worklist_if_has_custom_linkage<'tcx>(tcx: TyCtxt<'tcx>, worklist: &mut Vec, def_id: LocalDefId) { +fn has_custom_linkage<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool { // Anything which has custom linkage gets thrown on the worklist no // matter where it is in the crate, along with "special std symbols" // which are currently akin to allocator symbols. - if tcx.def_kind(def_id).has_codegen_attrs() { - let codegen_attrs = tcx.codegen_fn_attrs(def_id); - if codegen_attrs.contains_extern_indicator() - || codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) - // FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by - // `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their - // `SymbolExportLevel::Rust` export level but may end up being exported in dylibs. - || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED) - || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) - { - worklist.push(def_id); - } + if !tcx.def_kind(def_id).has_codegen_attrs() { + return false; } + let codegen_attrs = tcx.codegen_fn_attrs(def_id); + codegen_attrs.contains_extern_indicator() + || codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) + // FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by + // `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their + // `SymbolExportLevel::Rust` export level but may end up being exported in dylibs. + || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED) + || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) } fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet { @@ -405,11 +409,13 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet { let crate_items = tcx.hir_crate_items(()); for id in crate_items.items() { - check_item(tcx, tcx.hir().item(id), &mut reachable_context.worklist, access_levels); + check_item(tcx, id, &mut reachable_context.worklist, access_levels); } for id in crate_items.impl_items() { - push_to_worklist_if_has_custom_linkage(tcx, &mut reachable_context.worklist, id.def_id) + if has_custom_linkage(tcx, id.def_id) { + reachable_context.worklist.push(id.def_id); + } } }