@@ -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
112116impl < ' 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