@@ -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