@@ -291,7 +291,31 @@ fn compute_symbol_name<'tcx>(
291291 export:: compute_hash_of_export_fn( tcx, instance)
292292 ) ,
293293 false => match mangling_version {
294- SymbolManglingVersion :: Legacy => legacy:: mangle ( tcx, instance, instantiating_crate) ,
294+ SymbolManglingVersion :: Legacy => {
295+ let mangled_name = legacy:: mangle ( tcx, instance, instantiating_crate) ;
296+
297+ let mangled_name_too_long = {
298+ // The PDB debug info format cannot store mangled symbol names for which its
299+ // internal record exceeds u16::MAX bytes, a limit multiple Rust projects have been
300+ // hitting due to the verbosity of legacy name manglng. Depending on the linker version
301+ // in use, such symbol names can lead to linker crashes or incomprehensible linker error
302+ // about a limit being hit.
303+ // Mangle those symbols with v0 mangling instead, which gives us more room to breathe
304+ // as v0 mangling is more compact.
305+ // Empirical testing has shown the limit for the symbol name to be 65521 bytes; use
306+ // 65000 bytes to leave some room for prefixes / suffixes as well as unknown scenarios
307+ // with a different limit.
308+ const MAX_SYMBOL_LENGTH : usize = 65000 ;
309+
310+ tcx. sess . target . uses_pdb_debuginfo ( ) && mangled_name. len ( ) > MAX_SYMBOL_LENGTH
311+ } ;
312+
313+ if mangled_name_too_long {
314+ v0:: mangle ( tcx, instance, instantiating_crate, false )
315+ } else {
316+ mangled_name
317+ }
318+ }
295319 SymbolManglingVersion :: V0 => v0:: mangle ( tcx, instance, instantiating_crate, false ) ,
296320 SymbolManglingVersion :: Hashed => {
297321 hashed:: mangle ( tcx, instance, instantiating_crate, || {
0 commit comments