diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index ebcc3b03999..2a314727744 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -197,34 +197,8 @@ fn partition<'tcx, I>( let instrument_dead_code = tcx.sess.instrument_coverage() && !tcx.sess.instrument_coverage_except_unused_functions(); - if instrument_dead_code { - assert!( - codegen_units.len() > 0, - "There must be at least one CGU that code coverage data can be generated in." - ); - - // Find the smallest CGU that has exported symbols and put the dead - // function stubs in that CGU. We look for exported symbols to increase - // the likelihood the linker won't throw away the dead functions. - // FIXME(#92165): In order to truly resolve this, we need to make sure - // the object file (CGU) containing the dead function stubs is included - // in the final binary. This will probably require forcing these - // function symbols to be included via `-u` or `/include` linker args. - let mut cgus: Vec<_> = codegen_units.iter_mut().collect(); - cgus.sort_by_key(|cgu| cgu.size_estimate()); - - let dead_code_cgu = - if let Some(cgu) = cgus.into_iter().rev().find(|cgu| { - cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External) - }) { - cgu - } else { - // If there are no CGUs that have externally linked items, - // then we just pick the first CGU as a fallback. - &mut codegen_units[0] - }; - dead_code_cgu.make_code_coverage_dead_code_cgu(); + mark_code_coverage_dead_code_cgu(&mut codegen_units); } // Ensure CGUs are sorted by name, so that we get deterministic results. @@ -545,6 +519,33 @@ enum MonoItemPlacement { } } +fn mark_code_coverage_dead_code_cgu<'tcx>(codegen_units: &mut [CodegenUnit<'tcx>]) { + assert!(!codegen_units.is_empty()); + + // Find the smallest CGU that has exported symbols and put the dead + // function stubs in that CGU. We look for exported symbols to increase + // the likelihood the linker won't throw away the dead functions. + // FIXME(#92165): In order to truly resolve this, we need to make sure + // the object file (CGU) containing the dead function stubs is included + // in the final binary. This will probably require forcing these + // function symbols to be included via `-u` or `/include` linker args. + let mut cgus: Vec<&mut CodegenUnit<'tcx>> = codegen_units.iter_mut().collect(); + cgus.sort_by_key(|cgu| cgu.size_estimate()); + + let dead_code_cgu = if let Some(cgu) = cgus + .into_iter() + .rev() + .find(|cgu| cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External)) + { + cgu + } else { + // If there are no CGUs that have externally linked items, + // then we just pick the first CGU as a fallback. + &mut codegen_units[0] + }; + dead_code_cgu.make_code_coverage_dead_code_cgu(); +} + fn characteristic_def_id_of_mono_item<'tcx>( tcx: TyCtxt<'tcx>, mono_item: MonoItem<'tcx>,