diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index cb3fdd4d3f76e..7135b8f04a2e3 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -51,6 +51,7 @@ #![feature(negative_impls)] #![feature(never_type)] #![feature(ptr_alignment_type)] +#![feature(round_char_boundary)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(trusted_len)] diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 7243f87ee6380..47ba850d50dd4 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::fmt; use std::hash::Hash; @@ -468,6 +469,29 @@ impl<'tcx> CodegenUnit<'tcx> { hash.as_u128().to_base_fixed_len(CASE_INSENSITIVE) } + pub fn shorten_name(human_readable_name: &str) -> Cow<'_, str> { + // Set a limit a somewhat below the common platform limits for file names. + const MAX_CGU_NAME_LENGTH: usize = 200; + const TRUNCATED_NAME_PREFIX: &str = "-trunc-"; + if human_readable_name.len() > MAX_CGU_NAME_LENGTH { + let mangled_name = Self::mangle_name(human_readable_name); + // Determine a safe byte offset to truncate the name to + let truncate_to = human_readable_name.floor_char_boundary( + MAX_CGU_NAME_LENGTH - TRUNCATED_NAME_PREFIX.len() - mangled_name.len(), + ); + format!( + "{}{}{}", + &human_readable_name[..truncate_to], + TRUNCATED_NAME_PREFIX, + mangled_name + ) + .into() + } else { + // If the name is short enough, we can just return it as is. + human_readable_name.into() + } + } + pub fn compute_size_estimate(&mut self) { // The size of a codegen unit as the sum of the sizes of the items // within it. @@ -604,7 +628,7 @@ impl<'tcx> CodegenUnitNameBuilder<'tcx> { let cgu_name = self.build_cgu_name_no_mangle(cnum, components, special_suffix); if self.tcx.sess.opts.unstable_opts.human_readable_cgu_names { - cgu_name + Symbol::intern(&CodegenUnit::shorten_name(cgu_name.as_str())) } else { Symbol::intern(&CodegenUnit::mangle_name(cgu_name.as_str())) } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index b4169a060d4d6..49025673bbd2f 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -461,15 +461,15 @@ fn merge_codegen_units<'tcx>( for cgu in codegen_units.iter_mut() { if let Some(new_cgu_name) = new_cgu_names.get(&cgu.name()) { - if cx.tcx.sess.opts.unstable_opts.human_readable_cgu_names { - cgu.set_name(Symbol::intern(new_cgu_name)); + let new_cgu_name = if cx.tcx.sess.opts.unstable_opts.human_readable_cgu_names { + Symbol::intern(&CodegenUnit::shorten_name(new_cgu_name)) } else { // If we don't require CGU names to be human-readable, // we use a fixed length hash of the composite CGU name // instead. - let new_cgu_name = CodegenUnit::mangle_name(new_cgu_name); - cgu.set_name(Symbol::intern(&new_cgu_name)); - } + Symbol::intern(&CodegenUnit::mangle_name(new_cgu_name)) + }; + cgu.set_name(new_cgu_name); } }