Skip to content

Commit 6e69b94

Browse files
authored
Merge pull request #4 from CryZe/match-rustc
Update to match rust-lang/rust#36059
2 parents 25af8f6 + e92a0f1 commit 6e69b94

File tree

1 file changed

+63
-29
lines changed

1 file changed

+63
-29
lines changed

src/lib.rs

+63-29
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ pub fn demangle(s: &str) -> Demangle {
7676
// symbols because we could have any function in the backtrace.
7777
let mut valid = true;
7878
let mut inner = s;
79-
if s.len() > 4 && s.starts_with("_ZN") && s.ends_with("E") {
80-
inner = &s[3 .. s.len() - 1];
81-
// On Windows, dbghelp strips leading underscores, so we accept "ZN...E"
82-
// form too.
83-
} else if s.len() > 3 && s.starts_with("ZN") && s.ends_with("E") {
84-
inner = &s[2 .. s.len() - 1];
79+
if s.len() > 4 && s.starts_with("_ZN") && s.ends_with('E') {
80+
inner = &s[3..s.len() - 1];
81+
} else if s.len() > 3 && s.starts_with("ZN") && s.ends_with('E') {
82+
// On Windows, dbghelp strips leading underscores, so we accept "ZN...E"
83+
// form too.
84+
inner = &s[2..s.len() - 1];
8585
} else {
8686
valid = false;
8787
}
@@ -94,19 +94,23 @@ pub fn demangle(s: &str) -> Demangle {
9494
if c.is_digit(10) {
9595
i = i * 10 + c as usize - '0' as usize;
9696
} else {
97-
break
97+
break;
9898
}
9999
}
100100
if i == 0 {
101101
valid = chars.next().is_none();
102-
break
102+
break;
103103
} else if chars.by_ref().take(i - 1).count() != i - 1 {
104104
valid = false;
105105
}
106106
}
107107
}
108108

109-
Demangle { inner: inner, valid: valid, original: s }
109+
Demangle {
110+
inner: inner,
111+
valid: valid,
112+
original: s,
113+
}
110114
}
111115

112116
impl<'a> Demangle<'a> {
@@ -138,10 +142,21 @@ impl<'a> fmt::Display for Demangle<'a> {
138142
let i: usize = inner[..(inner.len() - rest.len())].parse().unwrap();
139143
inner = &rest[i..];
140144
rest = &rest[..i];
145+
if rest.starts_with("_$") {
146+
rest = &rest[1..];
147+
}
141148
while !rest.is_empty() {
142-
if rest.starts_with("$") {
149+
if rest.starts_with('.') {
150+
if let Some('.') = rest[1..].chars().next() {
151+
try!(f.write_str("::"));
152+
rest = &rest[2..];
153+
} else {
154+
try!(f.write_str("."));
155+
rest = &rest[1..];
156+
}
157+
} else if rest.starts_with('$') {
143158
macro_rules! demangle {
144-
($($pat:expr, => $demangled:expr),*) => ({
159+
($($pat:expr => $demangled:expr),*) => ({
145160
$(if rest.starts_with($pat) {
146161
try!(f.write_str($demangled));
147162
rest = &rest[$pat.len()..];
@@ -154,30 +169,35 @@ impl<'a> fmt::Display for Demangle<'a> {
154169
})
155170
}
156171

157-
// see src/librustc_trans/back/symbol_names.rs for these
158-
// mappings, historical ones also included.
172+
// see src/librustc/back/link.rs for these mappings
159173
demangle! {
160-
"$SP$", => "@",
161-
"$BP$", => "*",
162-
"$RF$", => "&",
163-
"$LT$", => "<",
164-
"$GT$", => ">",
165-
"$LP$", => "(",
166-
"$RP$", => ")",
167-
"$C$", => ",",
174+
"$SP$" => "@",
175+
"$BP$" => "*",
176+
"$RF$" => "&",
177+
"$LT$" => "<",
178+
"$GT$" => ">",
179+
"$LP$" => "(",
180+
"$RP$" => ")",
181+
"$C$" => ",",
168182

169183
// in theory we can demangle any Unicode code point, but
170184
// for simplicity we just catch the common ones.
171-
"$u7e$", => "~",
172-
"$u20$", => " ",
173-
"$u27$", => "'",
174-
"$u5b$", => "[",
175-
"$u5d$", => "]",
176-
"$u7b$", => "{",
177-
"$u7d$", => "}"
185+
"$u7e$" => "~",
186+
"$u20$" => " ",
187+
"$u27$" => "'",
188+
"$u5b$" => "[",
189+
"$u5d$" => "]",
190+
"$u7b$" => "{",
191+
"$u7d$" => "}",
192+
"$u3b$" => ";",
193+
"$u2b$" => "+",
194+
"$u22$" => "\""
178195
}
179196
} else {
180-
let idx = rest.find('$').unwrap_or(rest.len());
197+
let idx = match rest.char_indices().find(|&(_, c)| c == '$' || c == '.') {
198+
None => rest.len(),
199+
Some((i, _)) => i,
200+
};
181201
try!(f.write_str(&rest[..idx]));
182202
rest = &rest[idx..];
183203
}
@@ -218,6 +238,7 @@ mod tests {
218238
t!("_ZN8$RF$testE", "&test");
219239
t!("_ZN8$BP$test4foobE", "*test::foob");
220240
t!("_ZN9$u20$test4foobE", " test::foob");
241+
t!("_ZN35Bar$LT$$u5b$u32$u3b$$u20$4$u5d$$GT$E", "Bar<[u32; 4]>");
221242
}
222243

223244
#[test]
@@ -232,4 +253,17 @@ mod tests {
232253
t!("ZN13test$u20$test4foobE", "test test::foob");
233254
t!("ZN12test$RF$test4foobE", "test&test::foob");
234255
}
256+
257+
#[test]
258+
fn demangle_elements_beginning_with_underscore() {
259+
t!("_ZN13_$LT$test$GT$E", "<test>");
260+
t!("_ZN28_$u7b$$u7b$closure$u7d$$u7d$E", "{{closure}}");
261+
t!("_ZN15__STATIC_FMTSTRE", "__STATIC_FMTSTR");
262+
}
263+
264+
#[test]
265+
fn demangle_trait_impls() {
266+
t!("_ZN71_$LT$Test$u20$$u2b$$u20$$u27$static$u20$as$u20$foo..Bar$LT$Test$GT$$GT$3barE",
267+
"<Test + 'static as foo::Bar<Test>>::bar");
268+
}
235269
}

0 commit comments

Comments
 (0)