diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 0c409cef298a..6aea249d6356 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -344,6 +344,7 @@ fn process_builtin_attrs( if i.is_default { Linkage::LinkOnceAny } else { Linkage::External }, Visibility::Default, )); + codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; } } _ => {} diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index acb64bc6990b..b9323e91ca83 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -184,7 +184,13 @@ impl<'tcx> ReachableContext<'tcx> { CodegenFnAttrs::EMPTY }; let is_extern = codegen_attrs.contains_extern_indicator(); - if is_extern { + // Right now, the only way to get "foreign item symbol aliases" is by being an EII-implementation. + // EII implementations will generate under their own name but also under the name of some foreign item + // (hence alias) that may be in another crate. These functions are marked as always-reachable since + // it's very hard to track whether the original foreign item was reachable. It may live in another crate + // and may be reachable from sibling crates. + let has_foreign_aliases_eii = !codegen_attrs.foreign_item_symbol_aliases.is_empty(); + if is_extern || has_foreign_aliases_eii { self.reachable_symbols.insert(search_item); } } else { @@ -429,6 +435,12 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { // `SymbolExportLevel::Rust` export level but may end up being exported in dylibs. || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER) || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) + // Right now, the only way to get "foreign item symbol aliases" is by being an EII-implementation. + // EII implementations will generate under their own name but also under the name of some foreign item + // (hence alias) that may be in another crate. These functions are marked as always-reachable since + // it's very hard to track whether the original foreign item was reachable. It may live in another crate + // and may be reachable from sibling crates. + || !codegen_attrs.foreign_item_symbol_aliases.is_empty() } /// See module-level doc comment above. diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 0aaea96348b5..5349cf6d7dbe 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -422,6 +422,7 @@ impl Resolver<'_, '_> { && !tcx.is_panic_runtime(cnum) && !tcx.has_global_allocator(cnum) && !tcx.has_panic_handler(cnum) + && tcx.externally_implementable_items(cnum).is_empty() }) { maybe_unused_extern_crates.insert(id, import.span); }