Skip to content

Commit acd3f79

Browse files
authored
Auto merge of #36059 - CryZe:improved-demangling, r=alexcrichton
Improve Demangling of Rust Symbols This turns `..` into `::`, handles some more escapes and gets rid of unwanted underscores at the beginning of path elements. ![Image of Diff](http://puu.sh/qQIN3.png)
2 parents 312734c + 121b2fe commit acd3f79

File tree

1 file changed

+47
-19
lines changed

1 file changed

+47
-19
lines changed

src/libstd/sys/common/backtrace.rs

+47-19
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,21 @@ pub fn demangle(writer: &mut Write, s: &str) -> io::Result<()> {
137137
let i: usize = inner[.. (inner.len() - rest.len())].parse().unwrap();
138138
inner = &rest[i..];
139139
rest = &rest[..i];
140+
if rest.starts_with("_$") {
141+
rest = &rest[1..];
142+
}
140143
while !rest.is_empty() {
141-
if rest.starts_with("$") {
144+
if rest.starts_with(".") {
145+
if let Some('.') = rest[1..].chars().next() {
146+
writer.write_all(b"::")?;
147+
rest = &rest[2..];
148+
} else {
149+
writer.write_all(b".")?;
150+
rest = &rest[1..];
151+
}
152+
} else if rest.starts_with("$") {
142153
macro_rules! demangle {
143-
($($pat:expr, => $demangled:expr),*) => ({
154+
($($pat:expr => $demangled:expr),*) => ({
144155
$(if rest.starts_with($pat) {
145156
try!(writer.write_all($demangled));
146157
rest = &rest[$pat.len()..];
@@ -155,29 +166,32 @@ pub fn demangle(writer: &mut Write, s: &str) -> io::Result<()> {
155166

156167
// see src/librustc/back/link.rs for these mappings
157168
demangle! (
158-
"$SP$", => b"@",
159-
"$BP$", => b"*",
160-
"$RF$", => b"&",
161-
"$LT$", => b"<",
162-
"$GT$", => b">",
163-
"$LP$", => b"(",
164-
"$RP$", => b")",
165-
"$C$", => b",",
169+
"$SP$" => b"@",
170+
"$BP$" => b"*",
171+
"$RF$" => b"&",
172+
"$LT$" => b"<",
173+
"$GT$" => b">",
174+
"$LP$" => b"(",
175+
"$RP$" => b")",
176+
"$C$" => b",",
166177

167178
// in theory we can demangle any Unicode code point, but
168179
// for simplicity we just catch the common ones.
169-
"$u7e$", => b"~",
170-
"$u20$", => b" ",
171-
"$u27$", => b"'",
172-
"$u5b$", => b"[",
173-
"$u5d$", => b"]",
174-
"$u7b$", => b"{",
175-
"$u7d$", => b"}"
180+
"$u7e$" => b"~",
181+
"$u20$" => b" ",
182+
"$u27$" => b"'",
183+
"$u5b$" => b"[",
184+
"$u5d$" => b"]",
185+
"$u7b$" => b"{",
186+
"$u7d$" => b"}",
187+
"$u3b$" => b";",
188+
"$u2b$" => b"+",
189+
"$u22$" => b"\""
176190
)
177191
} else {
178-
let idx = match rest.find('$') {
192+
let idx = match rest.char_indices().find(|&(_, c)| c == '$' || c == '.') {
179193
None => rest.len(),
180-
Some(i) => i,
194+
Some((i, _)) => i,
181195
};
182196
writer.write_all(rest[..idx].as_bytes())?;
183197
rest = &rest[idx..];
@@ -212,6 +226,7 @@ mod tests {
212226
t!("_ZN8$RF$testE", "&test");
213227
t!("_ZN8$BP$test4foobE", "*test::foob");
214228
t!("_ZN9$u20$test4foobE", " test::foob");
229+
t!("_ZN35Bar$LT$$u5b$u32$u3b$$u20$4$u5d$$GT$E", "Bar<[u32; 4]>");
215230
}
216231

217232
#[test]
@@ -226,4 +241,17 @@ mod tests {
226241
t!("ZN13test$u20$test4foobE", "test test::foob");
227242
t!("ZN12test$RF$test4foobE", "test&test::foob");
228243
}
244+
245+
#[test]
246+
fn demangle_elements_beginning_with_underscore() {
247+
t!("_ZN13_$LT$test$GT$E", "<test>");
248+
t!("_ZN28_$u7b$$u7b$closure$u7d$$u7d$E", "{{closure}}");
249+
t!("_ZN15__STATIC_FMTSTRE", "__STATIC_FMTSTR");
250+
}
251+
252+
#[test]
253+
fn demangle_trait_impls() {
254+
t!("_ZN71_$LT$Test$u20$$u2b$$u20$$u27$static$u20$as$u20$foo..Bar$LT$Test$GT$$GT$3barE",
255+
"<Test + 'static as foo::Bar<Test>>::bar");
256+
}
229257
}

0 commit comments

Comments
 (0)