@@ -105,14 +105,24 @@ use rustc::hir::map as hir_map;
105
105
use rustc:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
106
106
use rustc:: ty:: fold:: TypeVisitor ;
107
107
use rustc:: ty:: item_path:: { self , ItemPathBuffer , RootMode } ;
108
+ use rustc:: ty:: maps:: Providers ;
108
109
use rustc:: ty:: subst:: Substs ;
109
110
use rustc:: hir:: map:: definitions:: DefPathData ;
110
111
use rustc:: util:: common:: record_time;
111
112
112
113
use syntax:: attr;
114
+ use syntax_pos:: symbol:: Symbol ;
113
115
114
116
use std:: fmt:: Write ;
115
117
118
+ pub fn provide ( providers : & mut Providers ) {
119
+ * providers = Providers {
120
+ def_symbol_name,
121
+ symbol_name,
122
+ ..* providers
123
+ } ;
124
+ }
125
+
116
126
fn get_symbol_hash < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
117
127
118
128
// the DefId of the item this name is for
@@ -127,7 +137,7 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
127
137
// values for generic type parameters,
128
138
// if any.
129
139
substs : Option < & ' tcx Substs < ' tcx > > )
130
- -> String {
140
+ -> u64 {
131
141
debug ! ( "get_symbol_hash(def_id={:?}, parameters={:?})" , def_id, substs) ;
132
142
133
143
let mut hasher = ty:: util:: TypeIdHasher :: < u64 > :: new ( tcx) ;
@@ -162,11 +172,28 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
162
172
} ) ;
163
173
164
174
// 64 bits should be enough to avoid collisions.
165
- format ! ( "h{:016x}" , hasher. finish( ) )
175
+ hasher. finish ( )
176
+ }
177
+
178
+ fn def_symbol_name < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId )
179
+ -> ty:: SymbolName
180
+ {
181
+ let mut buffer = SymbolPathBuffer :: new ( ) ;
182
+ item_path:: with_forced_absolute_paths ( || {
183
+ tcx. push_item_path ( & mut buffer, def_id) ;
184
+ } ) ;
185
+ buffer. into_interned ( )
166
186
}
167
187
168
- pub fn symbol_name < ' a , ' tcx > ( instance : Instance < ' tcx > ,
169
- tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> String {
188
+ fn symbol_name < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , instance : Instance < ' tcx > )
189
+ -> ty:: SymbolName
190
+ {
191
+ ty:: SymbolName { name : Symbol :: intern ( & compute_symbol_name ( tcx, instance) ) . as_str ( ) }
192
+ }
193
+
194
+ fn compute_symbol_name < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , instance : Instance < ' tcx > )
195
+ -> String
196
+ {
170
197
let def_id = instance. def_id ( ) ;
171
198
let substs = instance. substs ;
172
199
@@ -253,11 +280,7 @@ pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>,
253
280
254
281
let hash = get_symbol_hash ( tcx, Some ( def_id) , instance_ty, Some ( substs) ) ;
255
282
256
- let mut buffer = SymbolPathBuffer :: new ( ) ;
257
- item_path:: with_forced_absolute_paths ( || {
258
- tcx. push_item_path ( & mut buffer, def_id) ;
259
- } ) ;
260
- buffer. finish ( & hash)
283
+ SymbolPathBuffer :: from_interned ( tcx. def_symbol_name ( def_id) ) . finish ( hash)
261
284
}
262
285
263
286
// Follow C++ namespace-mangling style, see
@@ -288,10 +311,22 @@ impl SymbolPathBuffer {
288
311
result
289
312
}
290
313
291
- fn finish ( mut self , hash : & str ) -> String {
292
- // end name-sequence
293
- self . push ( hash) ;
294
- self . result . push ( 'E' ) ;
314
+ fn from_interned ( symbol : ty:: SymbolName ) -> Self {
315
+ let mut result = SymbolPathBuffer {
316
+ result : String :: with_capacity ( 64 ) ,
317
+ temp_buf : String :: with_capacity ( 16 )
318
+ } ;
319
+ result. result . push_str ( & symbol. name ) ;
320
+ result
321
+ }
322
+
323
+ fn into_interned ( self ) -> ty:: SymbolName {
324
+ ty:: SymbolName { name : Symbol :: intern ( & self . result ) . as_str ( ) }
325
+ }
326
+
327
+ fn finish ( mut self , hash : u64 ) -> String {
328
+ // E = end name-sequence
329
+ let _ = write ! ( self . result, "17h{:016x}E" , hash) ;
295
330
self . result
296
331
}
297
332
}
@@ -320,7 +355,7 @@ pub fn exported_name_from_type_and_prefix<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
320
355
let hash = get_symbol_hash ( tcx, None , t, None ) ;
321
356
let mut buffer = SymbolPathBuffer :: new ( ) ;
322
357
buffer. push ( prefix) ;
323
- buffer. finish ( & hash)
358
+ buffer. finish ( hash)
324
359
}
325
360
326
361
// Name sanitation. LLVM will happily accept identifiers with weird names, but
0 commit comments