13
13
14
14
use rustc_data_structures:: fx:: FxHashSet ;
15
15
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
16
- use rustc_hir as hir;
17
16
use rustc_hir:: def_id:: DefId ;
18
17
use rustc_hir:: definitions:: { DefPathData , DefPathDataName , DisambiguatedDefPathData } ;
18
+ use rustc_hir:: { AsyncGeneratorKind , GeneratorKind , Mutability } ;
19
19
use rustc_middle:: ty:: layout:: IntegerExt ;
20
20
use rustc_middle:: ty:: subst:: { GenericArgKind , SubstsRef } ;
21
21
use rustc_middle:: ty:: { self , AdtDef , ExistentialProjection , Ty , TyCtxt } ;
@@ -102,14 +102,14 @@ fn push_debuginfo_type_name<'tcx>(
102
102
ty:: RawPtr ( ty:: TypeAndMut { ty : inner_type, mutbl } ) => {
103
103
if cpp_like_debuginfo {
104
104
match mutbl {
105
- hir :: Mutability :: Not => output. push_str ( "ptr_const$<" ) ,
106
- hir :: Mutability :: Mut => output. push_str ( "ptr_mut$<" ) ,
105
+ Mutability :: Not => output. push_str ( "ptr_const$<" ) ,
106
+ Mutability :: Mut => output. push_str ( "ptr_mut$<" ) ,
107
107
}
108
108
} else {
109
109
output. push ( '*' ) ;
110
110
match mutbl {
111
- hir :: Mutability :: Not => output. push_str ( "const " ) ,
112
- hir :: Mutability :: Mut => output. push_str ( "mut " ) ,
111
+ Mutability :: Not => output. push_str ( "const " ) ,
112
+ Mutability :: Mut => output. push_str ( "mut " ) ,
113
113
}
114
114
}
115
115
@@ -131,8 +131,8 @@ fn push_debuginfo_type_name<'tcx>(
131
131
output. push_str ( mutbl. prefix_str ( ) ) ;
132
132
} else if !is_slice_or_str {
133
133
match mutbl {
134
- hir :: Mutability :: Not => output. push_str ( "ref$<" ) ,
135
- hir :: Mutability :: Mut => output. push_str ( "ref_mut$<" ) ,
134
+ Mutability :: Not => output. push_str ( "ref$<" ) ,
135
+ Mutability :: Mut => output. push_str ( "ref_mut$<" ) ,
136
136
}
137
137
}
138
138
@@ -345,14 +345,39 @@ fn push_debuginfo_type_name<'tcx>(
345
345
// processing
346
346
visited. remove ( t) ;
347
347
}
348
- ty:: Closure ( def_id, ..) | ty:: Generator ( def_id, ..) => {
349
- let key = tcx. def_key ( def_id) ;
348
+ ty:: Closure ( def_id, substs) | ty:: Generator ( def_id, substs, ..) => {
349
+ // Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or
350
+ // "{async_fn_env#0}<T1, T2, ...>", etc.
351
+ let def_key = tcx. def_key ( def_id) ;
352
+
350
353
if qualified {
351
- let parent_def_id = DefId { index : key . parent . unwrap ( ) , ..def_id } ;
354
+ let parent_def_id = DefId { index : def_key . parent . unwrap ( ) , ..def_id } ;
352
355
push_item_name ( tcx, parent_def_id, true , output) ;
353
356
output. push_str ( "::" ) ;
354
357
}
355
- push_unqualified_item_name ( tcx, def_id, key. disambiguated_data , output) ;
358
+
359
+ let mut label = String :: with_capacity ( 20 ) ;
360
+ write ! ( & mut label, "{}_env" , generator_kind_label( tcx. generator_kind( def_id) ) ) . unwrap ( ) ;
361
+
362
+ push_disambiguated_special_name (
363
+ & label,
364
+ def_key. disambiguated_data . disambiguator ,
365
+ cpp_like_debuginfo,
366
+ output,
367
+ ) ;
368
+
369
+ // We also need to add the generic arguments of the async fn/generator or
370
+ // the enclosing function (for closures or async blocks), so that we end
371
+ // up with a unique name for every instantiation.
372
+
373
+ // Find the generics of the enclosing function, as defined in the source code.
374
+ let enclosing_fn_def_id = tcx. typeck_root_def_id ( def_id) ;
375
+ let generics = tcx. generics_of ( enclosing_fn_def_id) ;
376
+
377
+ // Truncate the substs to the length of the above generics. This will cut off
378
+ // anything closure- or generator-specific.
379
+ let substs = substs. truncate_to ( tcx, generics) ;
380
+ push_generic_params_internal ( tcx, substs, output, visited) ;
356
381
}
357
382
// Type parameters from polymorphized functions.
358
383
ty:: Param ( _) => {
@@ -509,6 +534,29 @@ pub fn push_item_name(tcx: TyCtxt<'_>, def_id: DefId, qualified: bool, output: &
509
534
push_unqualified_item_name ( tcx, def_id, def_key. disambiguated_data , output) ;
510
535
}
511
536
537
+ fn generator_kind_label ( generator_kind : Option < GeneratorKind > ) -> & ' static str {
538
+ match generator_kind {
539
+ Some ( GeneratorKind :: Async ( AsyncGeneratorKind :: Block ) ) => "async_block" ,
540
+ Some ( GeneratorKind :: Async ( AsyncGeneratorKind :: Closure ) ) => "async_closure" ,
541
+ Some ( GeneratorKind :: Async ( AsyncGeneratorKind :: Fn ) ) => "async_fn" ,
542
+ Some ( GeneratorKind :: Gen ) => "generator" ,
543
+ None => "closure" ,
544
+ }
545
+ }
546
+
547
+ fn push_disambiguated_special_name (
548
+ label : & str ,
549
+ disambiguator : u32 ,
550
+ cpp_like_debuginfo : bool ,
551
+ output : & mut String ,
552
+ ) {
553
+ if cpp_like_debuginfo {
554
+ write ! ( output, "{}${}" , label, disambiguator) . unwrap ( ) ;
555
+ } else {
556
+ write ! ( output, "{{{}#{}}}" , label, disambiguator) . unwrap ( ) ;
557
+ }
558
+ }
559
+
512
560
fn push_unqualified_item_name (
513
561
tcx : TyCtxt < ' _ > ,
514
562
def_id : DefId ,
@@ -519,42 +567,32 @@ fn push_unqualified_item_name(
519
567
DefPathData :: CrateRoot => {
520
568
output. push_str ( tcx. crate_name ( def_id. krate ) . as_str ( ) ) ;
521
569
}
522
- DefPathData :: ClosureExpr if tcx. generator_kind ( def_id) . is_some ( ) => {
523
- let key = match tcx. generator_kind ( def_id) . unwrap ( ) {
524
- hir:: GeneratorKind :: Async ( hir:: AsyncGeneratorKind :: Block ) => "async_block" ,
525
- hir:: GeneratorKind :: Async ( hir:: AsyncGeneratorKind :: Closure ) => "async_closure" ,
526
- hir:: GeneratorKind :: Async ( hir:: AsyncGeneratorKind :: Fn ) => "async_fn" ,
527
- hir:: GeneratorKind :: Gen => "generator" ,
528
- } ;
529
- // Generators look like closures, but we want to treat them differently
530
- // in the debug info.
531
- if cpp_like_debuginfo ( tcx) {
532
- write ! ( output, "{}${}" , key, disambiguated_data. disambiguator) . unwrap ( ) ;
533
- } else {
534
- write ! ( output, "{{{}#{}}}" , key, disambiguated_data. disambiguator) . unwrap ( ) ;
535
- }
570
+ DefPathData :: ClosureExpr => {
571
+ let label = generator_kind_label ( tcx. generator_kind ( def_id) ) ;
572
+
573
+ push_disambiguated_special_name (
574
+ label,
575
+ disambiguated_data. disambiguator ,
576
+ cpp_like_debuginfo ( tcx) ,
577
+ output,
578
+ ) ;
536
579
}
537
580
_ => match disambiguated_data. data . name ( ) {
538
581
DefPathDataName :: Named ( name) => {
539
582
output. push_str ( name. as_str ( ) ) ;
540
583
}
541
584
DefPathDataName :: Anon { namespace } => {
542
- if cpp_like_debuginfo ( tcx ) {
543
- write ! ( output , "{}${}" , namespace, disambiguated_data . disambiguator ) . unwrap ( ) ;
544
- } else {
545
- write ! ( output , "{{{}#{}}}" , namespace , disambiguated_data . disambiguator )
546
- . unwrap ( ) ;
547
- }
585
+ push_disambiguated_special_name (
586
+ namespace. as_str ( ) ,
587
+ disambiguated_data . disambiguator ,
588
+ cpp_like_debuginfo ( tcx ) ,
589
+ output ,
590
+ ) ;
548
591
}
549
592
} ,
550
593
} ;
551
594
}
552
595
553
- // Pushes the generic parameters in the given `InternalSubsts` to the output string.
554
- // This ignores region parameters, since they can't reliably be
555
- // reconstructed for items from non-local crates. For local crates, this
556
- // would be possible but with inlining and LTO we have to use the least
557
- // common denominator - otherwise we would run into conflicts.
558
596
fn push_generic_params_internal < ' tcx > (
559
597
tcx : TyCtxt < ' tcx > ,
560
598
substs : SubstsRef < ' tcx > ,
0 commit comments