@@ -152,6 +152,8 @@ pub struct TypeMap<'ll, 'tcx> {
152
152
type_to_metadata : FxHashMap < Ty < ' tcx > , & ' ll DIType > ,
153
153
/// A map from types to `UniqueTypeId`. This is an N:1 mapping.
154
154
type_to_unique_id : FxHashMap < Ty < ' tcx > , UniqueTypeId > ,
155
+ /// A map from `UniqueTypeId` to it's type-name string.
156
+ unique_id_to_type_name : FxHashMap < UniqueTypeId , String > ,
155
157
}
156
158
157
159
impl TypeMap < ' ll , ' tcx > {
@@ -201,6 +203,21 @@ impl TypeMap<'ll, 'tcx> {
201
203
}
202
204
}
203
205
206
+ /// Adds a `UniqueTypeId` to type-name mapping to the `TypeMap`. The
207
+ /// method will fail if the mapping already exists.
208
+ fn register_unique_id_with_type_name (
209
+ & mut self ,
210
+ unique_type_id : UniqueTypeId ,
211
+ type_name : String
212
+ ) {
213
+ if self . unique_id_to_type_name . insert ( unique_type_id, type_name) . is_some ( ) {
214
+ bug ! (
215
+ "type name for unique ID '{}' is already in the `TypeMap`!" ,
216
+ self . get_unique_type_id_as_string( unique_type_id)
217
+ ) ;
218
+ }
219
+ }
220
+
204
221
fn find_metadata_for_type ( & self , type_ : Ty < ' tcx > ) -> Option < & ' ll DIType > {
205
222
self . type_to_metadata . get ( & type_) . cloned ( )
206
223
}
@@ -209,6 +226,10 @@ impl TypeMap<'ll, 'tcx> {
209
226
self . unique_id_to_metadata . get ( & unique_type_id) . cloned ( )
210
227
}
211
228
229
+ fn find_type_name_for_unique_id ( & self , unique_type_id : UniqueTypeId ) -> Option < String > {
230
+ self . unique_id_to_type_name . get ( & unique_type_id) . cloned ( )
231
+ }
232
+
212
233
/// Gets the string representation of a `UniqueTypeId`. This method will fail if
213
234
/// the ID is unknown.
214
235
fn get_unique_type_id_as_string ( & self , unique_type_id : UniqueTypeId ) -> & str {
@@ -374,6 +395,26 @@ macro_rules! return_if_metadata_created_in_meantime {
374
395
} ;
375
396
}
376
397
398
+ fn check_type_name_cache (
399
+ cx : & CodegenCx < ' ll , ' tcx > ,
400
+ ty : Ty < ' tcx > ,
401
+ qualified : bool ,
402
+ ) -> String {
403
+ let mut type_map = debug_context ( cx) . type_map . borrow_mut ( ) ;
404
+ let unique_type_id = type_map. get_unique_type_id_of_type ( cx, ty) ;
405
+ match type_map. find_type_name_for_unique_id ( unique_type_id) {
406
+ Some ( type_name) => { type_name } ,
407
+ None => {
408
+ let type_name = compute_debuginfo_type_name ( cx. tcx , ty, qualified) ;
409
+ type_map. register_unique_id_with_type_name (
410
+ unique_type_id,
411
+ type_name. clone ( ) ,
412
+ ) ;
413
+ type_name
414
+ } ,
415
+ }
416
+ }
417
+
377
418
fn fixed_vec_metadata (
378
419
cx : & CodegenCx < ' ll , ' tcx > ,
379
420
unique_type_id : UniqueTypeId ,
@@ -422,7 +463,7 @@ fn vec_slice_metadata(
422
463
423
464
return_if_metadata_created_in_meantime ! ( cx, unique_type_id) ;
424
465
425
- let slice_type_name = compute_debuginfo_type_name ( cx. tcx , slice_ptr_type, true ) ;
466
+ let slice_type_name = check_type_name_cache ( cx, slice_ptr_type, true ) ;
426
467
427
468
let ( pointer_size, pointer_align) = cx. size_and_align_of ( data_ptr_type) ;
428
469
let ( usize_size, usize_align) = cx. size_and_align_of ( cx. tcx . types . usize ) ;
@@ -520,10 +561,10 @@ fn trait_pointer_metadata(
520
561
Some ( trait_object_type) => match trait_object_type. kind ( ) {
521
562
ty:: Adt ( def, _) => (
522
563
Some ( get_namespace_for_item ( cx, def. did ) ) ,
523
- compute_debuginfo_type_name ( cx. tcx , trait_object_type, false ) ,
564
+ check_type_name_cache ( cx, trait_object_type, false ) ,
524
565
) ,
525
566
ty:: RawPtr ( _) | ty:: Ref ( ..) => {
526
- ( NO_SCOPE_METADATA , compute_debuginfo_type_name ( cx. tcx , trait_object_type, true ) )
567
+ ( NO_SCOPE_METADATA , check_type_name_cache ( cx, trait_object_type, true ) )
527
568
}
528
569
_ => {
529
570
bug ! (
@@ -536,7 +577,7 @@ fn trait_pointer_metadata(
536
577
537
578
// No object type, use the trait type directly (no scope here since the type
538
579
// will be wrapped in the dyn$ synthetic type).
539
- None => ( NO_SCOPE_METADATA , compute_debuginfo_type_name ( cx. tcx , trait_type, true ) ) ,
580
+ None => ( NO_SCOPE_METADATA , check_type_name_cache ( cx, trait_type, true ) ) ,
540
581
} ;
541
582
542
583
let file_metadata = unknown_file_metadata ( cx) ;
@@ -987,7 +1028,7 @@ fn foreign_type_metadata(
987
1028
) -> & ' ll DIType {
988
1029
debug ! ( "foreign_type_metadata: {:?}" , t) ;
989
1030
990
- let name = compute_debuginfo_type_name ( cx. tcx , t, false ) ;
1031
+ let name = check_type_name_cache ( cx, t, false ) ;
991
1032
create_struct_stub ( cx, t, & name, unique_type_id, NO_SCOPE_METADATA , DIFlags :: FlagZero )
992
1033
}
993
1034
@@ -997,7 +1038,7 @@ fn pointer_type_metadata(
997
1038
pointee_type_metadata : & ' ll DIType ,
998
1039
) -> & ' ll DIType {
999
1040
let ( pointer_size, pointer_align) = cx. size_and_align_of ( pointer_type) ;
1000
- let name = compute_debuginfo_type_name ( cx. tcx , pointer_type, false ) ;
1041
+ let name = check_type_name_cache ( cx, pointer_type, false ) ;
1001
1042
unsafe {
1002
1043
llvm:: LLVMRustDIBuilderCreatePointerType (
1003
1044
DIB ( cx) ,
@@ -1300,7 +1341,7 @@ fn prepare_struct_metadata(
1300
1341
unique_type_id : UniqueTypeId ,
1301
1342
span : Span ,
1302
1343
) -> RecursiveTypeDescription < ' ll , ' tcx > {
1303
- let struct_name = compute_debuginfo_type_name ( cx. tcx , struct_type, false ) ;
1344
+ let struct_name = check_type_name_cache ( cx, struct_type, false ) ;
1304
1345
1305
1346
let ( struct_def_id, variant) = match struct_type. kind ( ) {
1306
1347
ty:: Adt ( def, _) => ( def. did , def. non_enum_variant ( ) ) ,
@@ -1406,7 +1447,7 @@ fn prepare_tuple_metadata(
1406
1447
span : Span ,
1407
1448
containing_scope : Option < & ' ll DIScope > ,
1408
1449
) -> RecursiveTypeDescription < ' ll , ' tcx > {
1409
- let tuple_name = compute_debuginfo_type_name ( cx. tcx , tuple_type, false ) ;
1450
+ let tuple_name = check_type_name_cache ( cx, tuple_type, false ) ;
1410
1451
1411
1452
let struct_stub = create_struct_stub (
1412
1453
cx,
@@ -1470,7 +1511,7 @@ fn prepare_union_metadata(
1470
1511
unique_type_id : UniqueTypeId ,
1471
1512
span : Span ,
1472
1513
) -> RecursiveTypeDescription < ' ll , ' tcx > {
1473
- let union_name = compute_debuginfo_type_name ( cx. tcx , union_type, false ) ;
1514
+ let union_name = check_type_name_cache ( cx, union_type, false ) ;
1474
1515
1475
1516
let ( union_def_id, variant) = match union_type. kind ( ) {
1476
1517
ty:: Adt ( def, _) => ( def. did , def. non_enum_variant ( ) ) ,
@@ -2025,7 +2066,7 @@ fn prepare_enum_metadata(
2025
2066
outer_field_tys : Vec < Ty < ' tcx > > ,
2026
2067
) -> RecursiveTypeDescription < ' ll , ' tcx > {
2027
2068
let tcx = cx. tcx ;
2028
- let enum_name = compute_debuginfo_type_name ( tcx , enum_type, false ) ;
2069
+ let enum_name = check_type_name_cache ( cx , enum_type, false ) ;
2029
2070
2030
2071
let containing_scope = get_namespace_for_item ( cx, enum_def_id) ;
2031
2072
// FIXME: This should emit actual file metadata for the enum, but we
0 commit comments