@@ -111,44 +111,36 @@ impl fmt::Debug for Symbol {
111
111
}
112
112
}
113
113
114
- // Maybe a parsed C++ symbol, if parsing the mangled symbol as Rust failed.
115
- #[ cfg( feature = "cpp_demangle" ) ]
116
- struct OptionCppSymbol < ' a > ( Option < :: cpp_demangle:: BorrowedSymbol < ' a > > ) ;
117
114
118
- #[ cfg( feature = "cpp_demangle" ) ]
119
- impl < ' a > OptionCppSymbol < ' a > {
120
- fn parse ( input : & ' a [ u8 ] ) -> OptionCppSymbol < ' a > {
121
- OptionCppSymbol ( :: cpp_demangle:: BorrowedSymbol :: with_tail ( input)
122
- . ok ( )
123
- . map ( |( sym, _tail) | sym) )
124
- }
125
-
126
- fn none ( ) -> OptionCppSymbol < ' a > {
127
- OptionCppSymbol ( None )
128
- }
129
-
130
- fn as_str ( & self ) -> Option < Cow < ' a , str > > {
131
- self . 0 . as_ref ( ) . map ( |cpp| Cow :: from ( format ! ( "{}" , cpp) ) )
132
- }
133
- }
115
+ cfg_if ! {
116
+ if #[ cfg( feature = "cpp_demangle" ) ] {
117
+ // Maybe a parsed C++ symbol, if parsing the mangled symbol as Rust
118
+ // failed.
119
+ struct OptionCppSymbol <' a>( Option <:: cpp_demangle:: BorrowedSymbol <' a>>) ;
134
120
135
- // Make sure to keep this zero-sized, so that the `cpp_demangle` feature has no
136
- // cost when disabled.
137
- # [ cfg ( not ( feature = " cpp_demangle" ) ) ]
138
- struct OptionCppSymbol < ' a > ( PhantomData < & ' a ( ) > ) ;
121
+ impl < ' a> OptionCppSymbol < ' a> {
122
+ fn parse ( input : & ' a [ u8 ] ) -> OptionCppSymbol < ' a> {
123
+ OptionCppSymbol ( :: cpp_demangle:: BorrowedSymbol :: new ( input ) . ok ( ) )
124
+ }
139
125
140
- #[ cfg( not( feature = "cpp_demangle" ) ) ]
141
- impl < ' a > OptionCppSymbol < ' a > {
142
- fn parse ( _: & ' a [ u8 ] ) -> OptionCppSymbol < ' a > {
143
- OptionCppSymbol ( PhantomData )
144
- }
126
+ fn as_str( & self ) -> Option <Cow <' a, str >> {
127
+ self . 0 . as_ref( ) . map( |cpp| Cow :: from( cpp. to_string( ) ) )
128
+ }
129
+ }
130
+ } else {
131
+ // Make sure to keep this zero-sized, so that the `cpp_demangle` feature
132
+ // has no cost when disabled.
133
+ struct OptionCppSymbol <' a>( PhantomData <& ' a ( ) >) ;
145
134
146
- fn none ( ) -> OptionCppSymbol < ' a > {
147
- OptionCppSymbol ( PhantomData )
148
- }
135
+ impl <' a> OptionCppSymbol <' a> {
136
+ fn parse( _: & ' a [ u8 ] ) -> OptionCppSymbol <' a> {
137
+ OptionCppSymbol ( PhantomData )
138
+ }
149
139
150
- fn as_str ( & self ) -> Option < Cow < ' a , str > > {
151
- None
140
+ fn as_str( & self ) -> Option <Cow <' a, str >> {
141
+ None
142
+ }
143
+ }
152
144
}
153
145
}
154
146
@@ -165,12 +157,18 @@ impl<'a> SymbolName<'a> {
165
157
pub fn new ( bytes : & ' a [ u8 ] ) -> SymbolName < ' a > {
166
158
let demangled = str:: from_utf8 ( bytes) . ok ( ) . map ( demangle) ;
167
159
168
- // Only try and parse a C++ symbol if we didn't parse a Rust symbol.
169
- let cpp = if demangled. is_none ( ) {
170
- OptionCppSymbol :: parse ( bytes)
171
- } else {
172
- OptionCppSymbol :: none ( )
173
- } ;
160
+ // Unfortunately, rustc_demangle::Demangle doesn't expose its internal
161
+ // `valid` flag, so we don't know if it successfully "demangled" as a
162
+ // no-op on the str or not. Therefore, we have no choice but to always
163
+ // attempt to parse the bytes as a C++ symbol, and can't do it only as a
164
+ // fall back when demangling as Rust fails.
165
+ let cpp = OptionCppSymbol :: parse ( bytes) ;
166
+
167
+ println ! ( "FITZGEN: bytes = {}" , String :: from_utf8_lossy( bytes) ) ;
168
+ println ! ( "FITZGEN: cpp = {:#?}" , cpp. 0 ) ;
169
+ if let Some ( ref cpp) = cpp. 0 {
170
+ println ! ( "FITZGEN: demangled = {}" , cpp) ;
171
+ }
174
172
175
173
SymbolName {
176
174
bytes : bytes,
@@ -180,12 +178,22 @@ impl<'a> SymbolName<'a> {
180
178
}
181
179
182
180
/// Returns the raw symbol name as a `str` if the symbols is valid utf-8.
183
- pub fn as_str ( & self ) -> Option < Cow < ' a , str > > {
184
- self . demangled
185
- . as_ref ( )
186
- . map ( |s| Cow :: from ( s. as_str ( ) ) )
181
+ ///
182
+ /// Will not demangle C++ symbols.
183
+ pub fn as_str ( & self ) -> Option < & ' a str > {
184
+ self . demangled . as_ref ( ) . map ( |s| s. as_str ( ) )
185
+ }
186
+
187
+ /// Returns the symbol name as `Cow<'a, str>` if the symbol is valid utf-8.
188
+ ///
189
+ /// Will demangle C++ symbols.
190
+ pub fn as_cow ( & self ) -> Option < Cow < ' a , str > > {
191
+ // TODO: Next major version bump, remove the old `as_str` above, and
192
+ // rename this to `as_str`.
193
+ self . cpp_demangled
194
+ . as_str ( )
187
195
. or_else ( || {
188
- self . cpp_demangled . as_str ( )
196
+ self . demangled . as_ref ( ) . map ( |s| Cow :: from ( s . as_str ( ) ) )
189
197
} )
190
198
}
191
199
@@ -195,46 +203,54 @@ impl<'a> SymbolName<'a> {
195
203
}
196
204
}
197
205
198
- impl < ' a > fmt:: Display for SymbolName < ' a > {
199
- #[ cfg( feature = "cpp_demangle" ) ]
200
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
201
- if let Some ( ref s) = self . demangled {
202
- s. fmt ( f)
203
- } else if let Some ( ref cpp) = self . cpp_demangled . 0 {
204
- cpp. fmt ( f)
205
- } else {
206
- String :: from_utf8_lossy ( self . bytes ) . fmt ( f)
206
+ cfg_if ! {
207
+ if #[ cfg( feature = "cpp_demangle" ) ] {
208
+ impl <' a> fmt:: Display for SymbolName <' a> {
209
+ fn fmt( & self , f: & mut fmt:: Formatter ) -> fmt:: Result {
210
+ if let Some ( ref cpp) = self . cpp_demangled. 0 {
211
+ cpp. fmt( f)
212
+ } else if let Some ( ref s) = self . demangled {
213
+ s. fmt( f)
214
+ } else {
215
+ String :: from_utf8_lossy( self . bytes) . fmt( f)
216
+ }
217
+ }
207
218
}
208
- }
209
-
210
- #[ cfg( not( feature = "cpp_demangle" ) ) ]
211
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
212
- if let Some ( ref s) = self . demangled {
213
- s. fmt ( f)
214
- } else {
215
- String :: from_utf8_lossy ( self . bytes ) . fmt ( f)
219
+ } else {
220
+ impl <' a> fmt:: Display for SymbolName <' a> {
221
+ fn fmt( & self , f: & mut fmt:: Formatter ) -> fmt:: Result {
222
+ if let Some ( ref s) = self . demangled {
223
+ s. fmt( f)
224
+ } else {
225
+ String :: from_utf8_lossy( self . bytes) . fmt( f)
226
+ }
227
+ }
216
228
}
217
229
}
218
230
}
219
231
220
- impl < ' a > fmt:: Debug for SymbolName < ' a > {
221
- #[ cfg( feature = "cpp_demangle" ) ]
222
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
223
- if let Some ( ref s) = self . demangled {
224
- s. fmt ( f)
225
- } else if let Some ( ref cpp) = self . cpp_demangled . 0 {
226
- cpp. fmt ( f)
227
- } else {
228
- String :: from_utf8_lossy ( self . bytes ) . fmt ( f)
232
+ cfg_if ! {
233
+ if #[ cfg( feature = "cpp_demangle" ) ] {
234
+ impl <' a> fmt:: Debug for SymbolName <' a> {
235
+ fn fmt( & self , f: & mut fmt:: Formatter ) -> fmt:: Result {
236
+ if let Some ( ref cpp) = self . cpp_demangled. 0 {
237
+ fmt:: Display :: fmt( cpp, f)
238
+ } else if let Some ( ref s) = self . demangled {
239
+ s. fmt( f)
240
+ } else {
241
+ String :: from_utf8_lossy( self . bytes) . fmt( f)
242
+ }
243
+ }
229
244
}
230
- }
231
-
232
- #[ cfg( not( feature = "cpp_demangle" ) ) ]
233
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
234
- if let Some ( ref s) = self . demangled {
235
- s. fmt ( f)
236
- } else {
237
- String :: from_utf8_lossy ( self . bytes ) . fmt ( f)
245
+ } else {
246
+ impl <' a> fmt:: Debug for SymbolName <' a> {
247
+ fn fmt( & self , f: & mut fmt:: Formatter ) -> fmt:: Result {
248
+ if let Some ( ref s) = self . demangled {
249
+ s. fmt( f)
250
+ } else {
251
+ String :: from_utf8_lossy( self . bytes) . fmt( f)
252
+ }
253
+ }
238
254
}
239
255
}
240
256
}
0 commit comments