1 //! Demangles rustc mangled names.
3 //! Note regarding crate disambiguators:
5 //! Some demangled symbol paths can include "crate disambiguator" suffixes, represented as a large
6 //! hexadecimal value enclosed in square braces, and appended to the name of the crate. a suffix to the
7 //! original crate name. For example, the `core` crate, here, includes a disambiguator:
10 //! <generics::Firework<f64> as core[a7a74cee373f048]::ops::drop::Drop>::drop
13 //! These disambiguators are known to vary depending on environmental circumstances. As a result,
14 //! tests that compare results including demangled names can fail across development environments,
15 //! particularly with cross-platform testing. Also, the resulting crate paths are not syntactically
16 //! valid, and don't match the original source symbol paths, which can impact development tools.
18 //! For these reasons, by default, `rust-demangler` uses a heuristic to remove crate disambiguators
19 //! from their original demangled representation before printing them to standard output. If crate
20 //! disambiguators are required, add the `-d` (or `--disambiguators`) flag, and the disambiguators
21 //! will not be removed.
23 //! Also note that the disambiguators are stripped by a Regex pattern that is tolerant to some
24 //! variation in the number of hexadecimal digits. The disambiguators come from a hash value, which
25 //! typically generates a 16-digit hex representation on a 64-bit architecture; however, leading
26 //! zeros are not included, which can shorten the hex digit length, and a different hash algorithm
27 //! that might also be dependent on the architecture, might shorten the length even further. A
28 //! minimum length of 5 digits is assumed, which should be more than sufficient to support hex
29 //! representations that generate only 8-digits of precision with an extremely rare (but not
30 //! impossible) result with up to 3 leading zeros.
32 //! Using a minimum number of digits less than 5 risks the possibility of stripping demangled name
33 //! components with a similar pattern. For example, some closures instantiated multiple times
34 //! include their own disambiguators, demangled as non-hashed zero-based indexes in square brackets.
35 //! These disambiguators seem to have more analytical value (for instance, in coverage analysis), so
36 //! they are not removed.
38 use rust_demangler::*;
39 use std::io::{self, Read, Write};
41 fn main() -> io::Result<()> {
42 // FIXME(richkadel): In Issue #77615 discussed updating the `rustc-demangle` library, to provide
43 // an option to generate demangled names without including crate disambiguators. If that
44 // happens, update this tool to use that option (if the `-d` flag is not set) instead stripping
45 // them via the Regex heuristic. The update the doc comments and help.
47 // Strip hashed hexadecimal crate disambiguators. Leading zeros are not enforced, and can be
48 // different across different platform/architecture types, so while 16 hex digits are common,
49 // they can also be shorter.
51 // Also note that a demangled symbol path may include the `[<digits>]` pattern, with zero-based
52 // indexes (such as for closures, and possibly for types defined in anonymous scopes). Preferably
53 // these should not be stripped.
55 // The minimum length of 5 digits supports the possibility that some target architecture (maybe
56 // a 32-bit or smaller architecture) could generate a hash value with a maximum of 8 digits,
57 // and more than three leading zeros should be extremely unlikely. Conversely, it should be
58 // sufficient to assume the zero-based indexes for closures and anonymous scopes will never
59 // exceed the value 9999.
60 let mut strip_crate_disambiguators = Some(create_disambiguator_re());
62 let mut args = std::env::args();
63 let progname = args.next().unwrap();
65 if arg == "--disambiguators" || arg == "-d" {
66 strip_crate_disambiguators = None;
69 eprintln!("Usage: {} [-d|--disambiguators]", progname);
72 "This tool converts a list of Rust mangled symbols (one per line) into a\n\
73 corresponding list of demangled symbols."
77 "With -d (--disambiguators), Rust symbols mangled with the v0 symbol mangler may\n\
78 include crate disambiguators (a hexadecimal hash value, typically up to 16 digits\n\
79 long, enclosed in square brackets)."
83 "By default, crate disambiguators are removed, using a heuristics-based regular\n\
84 expression. (See the `rust-demangler` doc comments for more information.)"
91 let mut buffer = String::new();
92 io::stdin().read_to_string(&mut buffer)?;
93 let mut demangled_lines = demangle_lines(buffer.lines(), strip_crate_disambiguators);
94 demangled_lines.push("".to_string()); // ensure a trailing newline
95 io::stdout().write_all(demangled_lines.join("\n").as_bytes())?;