1313
1414use rustc_data_structures:: fx:: FxHashSet ;
1515use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
16- use rustc_hir as hir;
1716use rustc_hir:: def_id:: DefId ;
1817use rustc_hir:: definitions:: { DefPathData , DefPathDataName , DisambiguatedDefPathData } ;
18+ use rustc_hir:: { AsyncGeneratorKind , GeneratorKind , Mutability } ;
1919use rustc_middle:: ty:: layout:: IntegerExt ;
2020use rustc_middle:: ty:: subst:: { GenericArgKind , SubstsRef } ;
2121use rustc_middle:: ty:: { self , AdtDef , ExistentialProjection , Ty , TyCtxt } ;
@@ -102,14 +102,14 @@ fn push_debuginfo_type_name<'tcx>(
102102 ty:: RawPtr ( ty:: TypeAndMut { ty : inner_type, mutbl } ) => {
103103 if cpp_like_debuginfo {
104104 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$<" ) ,
107107 }
108108 } else {
109109 output. push ( '*' ) ;
110110 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 " ) ,
113113 }
114114 }
115115
@@ -131,8 +131,8 @@ fn push_debuginfo_type_name<'tcx>(
131131 output. push_str ( mutbl. prefix_str ( ) ) ;
132132 } else if !is_slice_or_str {
133133 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$<" ) ,
136136 }
137137 }
138138
@@ -345,14 +345,39 @@ fn push_debuginfo_type_name<'tcx>(
345345 // processing
346346 visited. remove ( t) ;
347347 }
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+
350353 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 } ;
352355 push_item_name ( tcx, parent_def_id, true , output) ;
353356 output. push_str ( "::" ) ;
354357 }
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) ;
356381 }
357382 // Type parameters from polymorphized functions.
358383 ty:: Param ( _) => {
@@ -509,6 +534,29 @@ pub fn push_item_name(tcx: TyCtxt<'_>, def_id: DefId, qualified: bool, output: &
509534 push_unqualified_item_name ( tcx, def_id, def_key. disambiguated_data , output) ;
510535}
511536
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+
512560fn push_unqualified_item_name (
513561 tcx : TyCtxt < ' _ > ,
514562 def_id : DefId ,
@@ -519,42 +567,32 @@ fn push_unqualified_item_name(
519567 DefPathData :: CrateRoot => {
520568 output. push_str ( tcx. crate_name ( def_id. krate ) . as_str ( ) ) ;
521569 }
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+ ) ;
536579 }
537580 _ => match disambiguated_data. data . name ( ) {
538581 DefPathDataName :: Named ( name) => {
539582 output. push_str ( name. as_str ( ) ) ;
540583 }
541584 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+ ) ;
548591 }
549592 } ,
550593 } ;
551594}
552595
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.
558596fn push_generic_params_internal < ' tcx > (
559597 tcx : TyCtxt < ' tcx > ,
560598 substs : SubstsRef < ' tcx > ,
0 commit comments