@@ -1562,7 +1562,9 @@ pub struct FmtPrinterData<'a, 'tcx> {
15621562 in_value : bool ,
15631563 pub print_alloc_ids : bool ,
15641564
1565+ // set of all named (non-anonymous) region names
15651566 used_region_names : FxHashSet < Symbol > ,
1567+
15661568 region_index : usize ,
15671569 binder_depth : usize ,
15681570 printed_type_count : usize ,
@@ -2118,23 +2120,31 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21182120 where
21192121 T : Print < ' tcx , Self , Output = Self , Error = fmt:: Error > + TypeFoldable < ' tcx > ,
21202122 {
2121- fn name_by_region_index ( index : usize ) -> Symbol {
2122- match index {
2123- 0 => Symbol :: intern ( "'r" ) ,
2124- 1 => Symbol :: intern ( "'s" ) ,
2125- i => Symbol :: intern ( & format ! ( "'t{}" , i - 2 ) ) ,
2123+ fn name_by_region_index (
2124+ index : usize ,
2125+ available_names : & mut Vec < Symbol > ,
2126+ num_available : usize ,
2127+ ) -> Symbol {
2128+ if let Some ( name) = available_names. pop ( ) {
2129+ name
2130+ } else {
2131+ Symbol :: intern ( & format ! ( "'t{}" , index - num_available) )
21262132 }
21272133 }
21282134
2135+ debug ! ( "name_all_regions" ) ;
2136+
21292137 // Replace any anonymous late-bound regions with named
21302138 // variants, using new unique identifiers, so that we can
21312139 // clearly differentiate between named and unnamed regions in
21322140 // the output. We'll probably want to tweak this over time to
21332141 // decide just how much information to give.
21342142 if self . binder_depth == 0 {
2135- self . prepare_late_bound_region_info ( value) ;
2143+ self . prepare_region_info ( value) ;
21362144 }
21372145
2146+ debug ! ( "self.used_region_names: {:?}" , & self . used_region_names) ;
2147+
21382148 let mut empty = true ;
21392149 let mut start_or_continue = |cx : & mut Self , start : & str , cont : & str | {
21402150 let w = if empty {
@@ -2151,13 +2161,23 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21512161
21522162 define_scoped_cx ! ( self ) ;
21532163
2164+ let possible_names = vec ! [ Symbol :: intern( "'t" ) , Symbol :: intern( "'s" ) , Symbol :: intern( "'r" ) ] ;
2165+
2166+ let mut available_names = possible_names
2167+ . into_iter ( )
2168+ . filter ( |name| !self . used_region_names . contains ( & name) )
2169+ . collect :: < Vec < _ > > ( ) ;
2170+ debug ! ( ?available_names) ;
2171+ let num_available = available_names. len ( ) ;
2172+
21542173 let mut region_index = self . region_index ;
2155- let mut next_name = |this : & Self | loop {
2156- let name = name_by_region_index ( region_index) ;
2174+ let mut next_name = |this : & Self | {
2175+ let name = name_by_region_index ( region_index, & mut available_names, num_available) ;
2176+ debug ! ( ?name) ;
21572177 region_index += 1 ;
2158- if ! this. used_region_names . contains ( & name) {
2159- break name ;
2160- }
2178+ assert ! ( ! this. used_region_names. contains( & name) ) ;
2179+
2180+ name
21612181 } ;
21622182
21632183 // If we want to print verbosely, then print *all* binders, even if they
@@ -2178,6 +2198,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21782198 ty:: BrAnon ( _) | ty:: BrEnv => {
21792199 start_or_continue ( & mut self , "for<" , ", " ) ;
21802200 let name = next_name ( & self ) ;
2201+ debug ! ( ?name) ;
21812202 do_continue ( & mut self , name) ;
21822203 ty:: BrNamed ( CRATE_DEF_ID . to_def_id ( ) , name)
21832204 }
@@ -2271,29 +2292,37 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
22712292 Ok ( inner)
22722293 }
22732294
2274- fn prepare_late_bound_region_info < T > ( & mut self , value : & ty:: Binder < ' tcx , T > )
2295+ fn prepare_region_info < T > ( & mut self , value : & ty:: Binder < ' tcx , T > )
22752296 where
22762297 T : TypeVisitable < ' tcx > ,
22772298 {
2278- struct LateBoundRegionNameCollector < ' a , ' tcx > {
2279- used_region_names : & ' a mut FxHashSet < Symbol > ,
2299+ struct RegionNameCollector < ' tcx > {
2300+ used_region_names : FxHashSet < Symbol > ,
22802301 type_collector : SsoHashSet < Ty < ' tcx > > ,
22812302 }
22822303
2283- impl < ' tcx > ty:: visit:: TypeVisitor < ' tcx > for LateBoundRegionNameCollector < ' _ , ' tcx > {
2304+ impl < ' tcx > RegionNameCollector < ' tcx > {
2305+ fn new ( ) -> Self {
2306+ RegionNameCollector {
2307+ used_region_names : Default :: default ( ) ,
2308+ type_collector : SsoHashSet :: new ( ) ,
2309+ }
2310+ }
2311+ }
2312+
2313+ impl < ' tcx > ty:: visit:: TypeVisitor < ' tcx > for RegionNameCollector < ' tcx > {
22842314 type BreakTy = ( ) ;
22852315
22862316 fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
22872317 trace ! ( "address: {:p}" , r. 0.0 ) ;
2288- if let ty:: ReLateBound ( _, ty:: BoundRegion { kind : ty:: BrNamed ( _, name) , .. } ) = * r {
2289- self . used_region_names . insert ( name) ;
2290- } else if let ty:: RePlaceholder ( ty:: PlaceholderRegion {
2291- name : ty:: BrNamed ( _, name) ,
2292- ..
2293- } ) = * r
2294- {
2318+
2319+ // Collect all named lifetimes. These allow us to prevent duplication
2320+ // of already existing lifetime names when introducing names for
2321+ // anonymous late-bound regions.
2322+ if let Some ( name) = r. get_name ( ) {
22952323 self . used_region_names . insert ( name) ;
22962324 }
2325+
22972326 r. super_visit_with ( self )
22982327 }
22992328
@@ -2309,12 +2338,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
23092338 }
23102339 }
23112340
2312- self . used_region_names . clear ( ) ;
2313- let mut collector = LateBoundRegionNameCollector {
2314- used_region_names : & mut self . used_region_names ,
2315- type_collector : SsoHashSet :: new ( ) ,
2316- } ;
2341+ let mut collector = RegionNameCollector :: new ( ) ;
23172342 value. visit_with ( & mut collector) ;
2343+ self . used_region_names = collector. used_region_names ;
23182344 self . region_index = 0 ;
23192345 }
23202346}
0 commit comments