diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index c052037f05b39..ba87b214d9436 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -307,7 +307,18 @@ fn compute_symbol_name<'tcx>( mangled_name } } - SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate, false), + SymbolManglingVersion::V0 => { + let mangled = v0::mangle(tcx, instance, instantiating_crate, false); + // v0 mangling can produce symbols that are too deeply nested for + // `rustc_demangle` to handle (e.g. pathologically nested generic + // type aliases exceed its recursion limit). Fall back to hashed + // mangling in that case so we always emit a demanglable symbol. + if rustc_demangle::try_demangle(&mangled).is_ok() { + mangled + } else { + hashed::mangle(tcx, instance, instantiating_crate, || mangled) + } + } SymbolManglingVersion::Hashed => { hashed::mangle(tcx, instance, instantiating_crate, || { v0::mangle(tcx, instance, instantiating_crate, false) diff --git a/tests/ui/symbol-names/deeply-nested-generic-aliases.rs b/tests/ui/symbol-names/deeply-nested-generic-aliases.rs new file mode 100644 index 0000000000000..a44c696d740d9 --- /dev/null +++ b/tests/ui/symbol-names/deeply-nested-generic-aliases.rs @@ -0,0 +1,24 @@ +//@ build-pass +//@ compile-flags: -C symbol-mangling-version=v0 + +struct D; + +type O0 = Option; +type O1 = O0; +type O2 = O1>; +type O3 = O2>; +type O4 = O3>; +type O5 = O4>; +type O6 = O5>; +type O7 = O6>; +type O8 = O7>; +type Q510 = O8>>>>>>; + +fn f() {} +fn describe() { + f::>() +} + +fn main() { + describe::(); +}