@@ -1572,7 +1572,9 @@ pub struct FmtPrinterData<'a, 'tcx> {
15721572 in_value : bool ,
15731573 pub print_alloc_ids : bool ,
15741574
1575+ // set of all named (non-anonymous) region names
15751576 used_region_names : FxHashSet < Symbol > ,
1577+
15761578 region_index : usize ,
15771579 binder_depth : usize ,
15781580 printed_type_count : usize ,
@@ -2139,23 +2141,31 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21392141 where
21402142 T : Print < ' tcx , Self , Output = Self , Error = fmt:: Error > + TypeFoldable < ' tcx > ,
21412143 {
2142- fn name_by_region_index ( index : usize ) -> Symbol {
2143- match index {
2144- 0 => Symbol :: intern ( "'r" ) ,
2145- 1 => Symbol :: intern ( "'s" ) ,
2146- i => Symbol :: intern ( & format ! ( "'t{}" , i - 2 ) ) ,
2144+ fn name_by_region_index (
2145+ index : usize ,
2146+ available_names : & mut Vec < Symbol > ,
2147+ num_available : usize ,
2148+ ) -> Symbol {
2149+ if let Some ( name) = available_names. pop ( ) {
2150+ name
2151+ } else {
2152+ Symbol :: intern ( & format ! ( "'t{}" , index - num_available) )
21472153 }
21482154 }
21492155
2156+ debug ! ( "name_all_regions" ) ;
2157+
21502158 // Replace any anonymous late-bound regions with named
21512159 // variants, using new unique identifiers, so that we can
21522160 // clearly differentiate between named and unnamed regions in
21532161 // the output. We'll probably want to tweak this over time to
21542162 // decide just how much information to give.
21552163 if self . binder_depth == 0 {
2156- self . prepare_late_bound_region_info ( value) ;
2164+ self . prepare_region_info ( value) ;
21572165 }
21582166
2167+ debug ! ( "self.used_region_names: {:?}" , & self . used_region_names) ;
2168+
21592169 let mut empty = true ;
21602170 let mut start_or_continue = |cx : & mut Self , start : & str , cont : & str | {
21612171 let w = if empty {
@@ -2172,13 +2182,23 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21722182
21732183 define_scoped_cx ! ( self ) ;
21742184
2185+ let possible_names = vec ! [ Symbol :: intern( "'t" ) , Symbol :: intern( "'s" ) , Symbol :: intern( "'r" ) ] ;
2186+
2187+ let mut available_names = possible_names
2188+ . into_iter ( )
2189+ . filter ( |name| !self . used_region_names . contains ( & name) )
2190+ . collect :: < Vec < _ > > ( ) ;
2191+ debug ! ( ?available_names) ;
2192+ let num_available = available_names. len ( ) ;
2193+
21752194 let mut region_index = self . region_index ;
2176- let mut next_name = |this : & Self | loop {
2177- let name = name_by_region_index ( region_index) ;
2195+ let mut next_name = |this : & Self | {
2196+ let name = name_by_region_index ( region_index, & mut available_names, num_available) ;
2197+ debug ! ( ?name) ;
21782198 region_index += 1 ;
2179- if ! this. used_region_names . contains ( & name) {
2180- break name ;
2181- }
2199+ assert ! ( ! this. used_region_names. contains( & name) ) ;
2200+
2201+ name
21822202 } ;
21832203
21842204 // If we want to print verbosely, then print *all* binders, even if they
@@ -2199,6 +2219,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
21992219 ty:: BrAnon ( _) | ty:: BrEnv => {
22002220 start_or_continue ( & mut self , "for<" , ", " ) ;
22012221 let name = next_name ( & self ) ;
2222+ debug ! ( ?name) ;
22022223 do_continue ( & mut self , name) ;
22032224 ty:: BrNamed ( CRATE_DEF_ID . to_def_id ( ) , name)
22042225 }
@@ -2292,29 +2313,37 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
22922313 Ok ( inner)
22932314 }
22942315
2295- fn prepare_late_bound_region_info < T > ( & mut self , value : & ty:: Binder < ' tcx , T > )
2316+ fn prepare_region_info < T > ( & mut self , value : & ty:: Binder < ' tcx , T > )
22962317 where
22972318 T : TypeVisitable < ' tcx > ,
22982319 {
2299- struct LateBoundRegionNameCollector < ' a , ' tcx > {
2300- used_region_names : & ' a mut FxHashSet < Symbol > ,
2320+ struct RegionNameCollector < ' tcx > {
2321+ used_region_names : FxHashSet < Symbol > ,
23012322 type_collector : SsoHashSet < Ty < ' tcx > > ,
23022323 }
23032324
2304- impl < ' tcx > ty:: visit:: TypeVisitor < ' tcx > for LateBoundRegionNameCollector < ' _ , ' tcx > {
2325+ impl < ' tcx > RegionNameCollector < ' tcx > {
2326+ fn new ( ) -> Self {
2327+ RegionNameCollector {
2328+ used_region_names : Default :: default ( ) ,
2329+ type_collector : SsoHashSet :: new ( ) ,
2330+ }
2331+ }
2332+ }
2333+
2334+ impl < ' tcx > ty:: visit:: TypeVisitor < ' tcx > for RegionNameCollector < ' tcx > {
23052335 type BreakTy = ( ) ;
23062336
23072337 fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
23082338 trace ! ( "address: {:p}" , r. 0.0 ) ;
2309- if let ty:: ReLateBound ( _, ty:: BoundRegion { kind : ty:: BrNamed ( _, name) , .. } ) = * r {
2310- self . used_region_names . insert ( name) ;
2311- } else if let ty:: RePlaceholder ( ty:: PlaceholderRegion {
2312- name : ty:: BrNamed ( _, name) ,
2313- ..
2314- } ) = * r
2315- {
2339+
2340+ // Collect all named lifetimes. These allow us to prevent duplication
2341+ // of already existing lifetime names when introducing names for
2342+ // anonymous late-bound regions.
2343+ if let Some ( name) = r. get_name ( ) {
23162344 self . used_region_names . insert ( name) ;
23172345 }
2346+
23182347 r. super_visit_with ( self )
23192348 }
23202349
@@ -2330,12 +2359,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
23302359 }
23312360 }
23322361
2333- self . used_region_names . clear ( ) ;
2334- let mut collector = LateBoundRegionNameCollector {
2335- used_region_names : & mut self . used_region_names ,
2336- type_collector : SsoHashSet :: new ( ) ,
2337- } ;
2362+ let mut collector = RegionNameCollector :: new ( ) ;
23382363 value. visit_with ( & mut collector) ;
2364+ self . used_region_names = collector. used_region_names ;
23392365 self . region_index = 0 ;
23402366 }
23412367}
0 commit comments