@@ -104,7 +104,7 @@ use rustc::middle::cstore;
104
104
use rustc:: middle:: def_id:: DefId ;
105
105
use rustc:: middle:: ty:: { self , TypeFoldable } ;
106
106
use rustc:: middle:: ty:: item_path:: { ItemPathBuffer , RootMode } ;
107
- use rustc:: front:: map:: definitions:: DefPath ;
107
+ use rustc:: front:: map:: definitions:: { DefPath , DefPathData } ;
108
108
109
109
use std:: fmt:: Write ;
110
110
use syntax:: parse:: token:: { self , InternedString } ;
@@ -134,7 +134,18 @@ pub fn def_path_to_string<'tcx>(tcx: &ty::TyCtxt<'tcx>, def_path: &DefPath) -> S
134
134
}
135
135
136
136
fn get_symbol_hash < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
137
+
138
+ // path to the item this name is for
137
139
def_path : & DefPath ,
140
+
141
+ // type of the item, without any generic
142
+ // parameters substituted; this is
143
+ // included in the hash as a kind of
144
+ // safeguard.
145
+ item_type : ty:: Ty < ' tcx > ,
146
+
147
+ // values for generic type parameters,
148
+ // if any.
138
149
parameters : & [ ty:: Ty < ' tcx > ] )
139
150
-> String {
140
151
debug ! ( "get_symbol_hash(def_path={:?}, parameters={:?})" ,
@@ -151,6 +162,13 @@ fn get_symbol_hash<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
151
162
// truly unique path
152
163
hash_state. input_str ( & def_path_to_string ( tcx, def_path) ) ;
153
164
165
+ // Include the main item-type. Note that, in this case, the
166
+ // assertions about `needs_subst` may not hold, but this item-type
167
+ // ought to be the same for every reference anyway.
168
+ assert ! ( !item_type. has_erasable_regions( ) ) ;
169
+ let encoded_item_type = tcx. sess . cstore . encode_type ( tcx, item_type, def_id_to_string) ;
170
+ hash_state. input ( & encoded_item_type[ ..] ) ;
171
+
154
172
// also include any type parameters (for generic items)
155
173
for t in parameters {
156
174
assert ! ( !t. has_erasable_regions( ) ) ;
@@ -185,7 +203,38 @@ fn exported_name_with_opt_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
185
203
186
204
let def_path = ccx. tcx ( ) . def_path ( def_id) ;
187
205
assert_eq ! ( def_path. krate, def_id. krate) ;
188
- let hash = get_symbol_hash ( ccx, & def_path, parameters. as_slice ( ) ) ;
206
+
207
+ // We want to compute the "type" of this item. Unfortunately, some
208
+ // kinds of items (e.g., closures) don't have an entry in the
209
+ // item-type array. So walk back up the find the closest parent
210
+ // that DOES have an entry.
211
+ let mut ty_def_id = def_id;
212
+ let instance_ty;
213
+ loop {
214
+ let key = ccx. tcx ( ) . def_key ( ty_def_id) ;
215
+ match key. disambiguated_data . data {
216
+ DefPathData :: TypeNs ( _) |
217
+ DefPathData :: ValueNs ( _) => {
218
+ instance_ty = ccx. tcx ( ) . lookup_item_type ( ty_def_id) ;
219
+ break ;
220
+ }
221
+ _ => {
222
+ // if we're making a symbol for something, there ought
223
+ // to be a value or type-def or something in there
224
+ // *somewhere*
225
+ ty_def_id. index = key. parent . unwrap_or_else ( || {
226
+ panic ! ( "finding type for {:?}, encountered def-id {:?} with no \
227
+ parent", def_id, ty_def_id) ;
228
+ } ) ;
229
+ }
230
+ }
231
+ }
232
+
233
+ // Erase regions because they may not be deterministic when hashed
234
+ // and should not matter anyhow.
235
+ let instance_ty = ccx. tcx ( ) . erase_regions ( & instance_ty. ty ) ;
236
+
237
+ let hash = get_symbol_hash ( ccx, & def_path, instance_ty, parameters. as_slice ( ) ) ;
189
238
190
239
let mut buffer = SymbolPathBuffer {
191
240
names : Vec :: with_capacity ( def_path. data . len ( ) )
@@ -239,7 +288,7 @@ pub fn internal_name_from_type_and_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>
239
288
data : vec ! [ ] ,
240
289
krate : cstore:: LOCAL_CRATE ,
241
290
} ;
242
- let hash = get_symbol_hash ( ccx, & def_path, & [ t ] ) ;
291
+ let hash = get_symbol_hash ( ccx, & def_path, t , & [ ] ) ;
243
292
mangle ( path. iter ( ) . cloned ( ) , Some ( & hash[ ..] ) )
244
293
}
245
294
0 commit comments