@@ -105,14 +105,24 @@ use rustc::hir::map as hir_map;
105105use rustc:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
106106use rustc:: ty:: fold:: TypeVisitor ;
107107use rustc:: ty:: item_path:: { self , ItemPathBuffer , RootMode } ;
108+ use rustc:: ty:: maps:: Providers ;
108109use rustc:: ty:: subst:: Substs ;
109110use rustc:: hir:: map:: definitions:: DefPathData ;
110111use rustc:: util:: common:: record_time;
111112
112113use syntax:: attr;
114+ use syntax_pos:: symbol:: Symbol ;
113115
114116use std:: fmt:: Write ;
115117
118+ pub fn provide ( providers : & mut Providers ) {
119+ * providers = Providers {
120+ def_symbol_name,
121+ symbol_name,
122+ ..* providers
123+ } ;
124+ }
125+
116126fn get_symbol_hash < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
117127
118128 // the DefId of the item this name is for
@@ -127,7 +137,7 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
127137 // values for generic type parameters,
128138 // if any.
129139 substs : Option < & ' tcx Substs < ' tcx > > )
130- -> String {
140+ -> u64 {
131141 debug ! ( "get_symbol_hash(def_id={:?}, parameters={:?})" , def_id, substs) ;
132142
133143 let mut hasher = ty:: util:: TypeIdHasher :: < u64 > :: new ( tcx) ;
@@ -162,11 +172,28 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
162172 } ) ;
163173
164174 // 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 ( )
166186}
167187
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+ {
170197 let def_id = instance. def_id ( ) ;
171198 let substs = instance. substs ;
172199
@@ -253,11 +280,7 @@ pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>,
253280
254281 let hash = get_symbol_hash ( tcx, Some ( def_id) , instance_ty, Some ( substs) ) ;
255282
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)
261284}
262285
263286// Follow C++ namespace-mangling style, see
@@ -288,10 +311,22 @@ impl SymbolPathBuffer {
288311 result
289312 }
290313
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) ;
295330 self . result
296331 }
297332}
@@ -320,7 +355,7 @@ pub fn exported_name_from_type_and_prefix<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
320355 let hash = get_symbol_hash ( tcx, None , t, None ) ;
321356 let mut buffer = SymbolPathBuffer :: new ( ) ;
322357 buffer. push ( prefix) ;
323- buffer. finish ( & hash)
358+ buffer. finish ( hash)
324359}
325360
326361// Name sanitation. LLVM will happily accept identifiers with weird names, but
0 commit comments