@@ -76,12 +76,12 @@ pub fn demangle(s: &str) -> Demangle {
76
76
// symbols because we could have any function in the backtrace.
77
77
let mut valid = true ;
78
78
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 ] ;
85
85
} else {
86
86
valid = false ;
87
87
}
@@ -94,19 +94,23 @@ pub fn demangle(s: &str) -> Demangle {
94
94
if c. is_digit ( 10 ) {
95
95
i = i * 10 + c as usize - '0' as usize ;
96
96
} else {
97
- break
97
+ break ;
98
98
}
99
99
}
100
100
if i == 0 {
101
101
valid = chars. next ( ) . is_none ( ) ;
102
- break
102
+ break ;
103
103
} else if chars. by_ref ( ) . take ( i - 1 ) . count ( ) != i - 1 {
104
104
valid = false ;
105
105
}
106
106
}
107
107
}
108
108
109
- Demangle { inner : inner, valid : valid, original : s }
109
+ Demangle {
110
+ inner : inner,
111
+ valid : valid,
112
+ original : s,
113
+ }
110
114
}
111
115
112
116
impl < ' a > Demangle < ' a > {
@@ -138,10 +142,21 @@ impl<'a> fmt::Display for Demangle<'a> {
138
142
let i: usize = inner[ ..( inner. len ( ) - rest. len ( ) ) ] . parse ( ) . unwrap ( ) ;
139
143
inner = & rest[ i..] ;
140
144
rest = & rest[ ..i] ;
145
+ if rest. starts_with ( "_$" ) {
146
+ rest = & rest[ 1 ..] ;
147
+ }
141
148
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 ( '$' ) {
143
158
macro_rules! demangle {
144
- ( $( $pat: expr, => $demangled: expr) ,* ) => ( {
159
+ ( $( $pat: expr => $demangled: expr) ,* ) => ( {
145
160
$( if rest. starts_with( $pat) {
146
161
try!( f. write_str( $demangled) ) ;
147
162
rest = & rest[ $pat. len( ) ..] ;
@@ -154,30 +169,35 @@ impl<'a> fmt::Display for Demangle<'a> {
154
169
} )
155
170
}
156
171
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
159
173
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$" => "," ,
168
182
169
183
// in theory we can demangle any Unicode code point, but
170
184
// 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$" => "\" "
178
195
}
179
196
} 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
+ } ;
181
201
try!( f. write_str ( & rest[ ..idx] ) ) ;
182
202
rest = & rest[ idx..] ;
183
203
}
@@ -218,6 +238,7 @@ mod tests {
218
238
t ! ( "_ZN8$RF$testE" , "&test" ) ;
219
239
t ! ( "_ZN8$BP$test4foobE" , "*test::foob" ) ;
220
240
t ! ( "_ZN9$u20$test4foobE" , " test::foob" ) ;
241
+ t ! ( "_ZN35Bar$LT$$u5b$u32$u3b$$u20$4$u5d$$GT$E" , "Bar<[u32; 4]>" ) ;
221
242
}
222
243
223
244
#[ test]
@@ -232,4 +253,17 @@ mod tests {
232
253
t ! ( "ZN13test$u20$test4foobE" , "test test::foob" ) ;
233
254
t ! ( "ZN12test$RF$test4foobE" , "test&test::foob" ) ;
234
255
}
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
+ }
235
269
}
0 commit comments