@@ -20,6 +20,7 @@ use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple};
2020use ty:: { TyClosure , TyGenerator , TyProjection , TyAnon } ;
2121use ty:: { TyDynamic , TyInt , TyUint , TyInfer } ;
2222use ty:: { self , Ty , TyCtxt , TypeFoldable } ;
23+ use util:: nodemap:: FxHashSet ;
2324
2425use std:: cell:: Cell ;
2526use std:: fmt;
@@ -259,12 +260,34 @@ pub fn parameterized(f: &mut fmt::Formatter,
259260 Ok ( ( ) )
260261}
261262
263+ struct LateBoundRegionNameCollector ( FxHashSet < Symbol > ) ;
264+
265+ impl < ' tcx > ty:: fold:: TypeVisitor < ' tcx > for LateBoundRegionNameCollector {
266+ fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> bool {
267+ match * r {
268+ ty:: ReLateBound ( _, ty:: BrNamed ( _, name) ) => {
269+ self . 0 . insert ( name) ;
270+ } ,
271+ _ => { } ,
272+ }
273+ r. super_visit_with ( self )
274+ }
275+ }
276+
262277fn in_binder < ' a , ' gcx , ' tcx , T , U > ( f : & mut fmt:: Formatter ,
263278 tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
264279 original : & ty:: Binder < T > ,
265280 lifted : Option < ty:: Binder < U > > ) -> fmt:: Result
266281 where T : fmt:: Display , U : fmt:: Display + TypeFoldable < ' tcx >
267282{
283+ fn name_by_region_index ( index : usize ) -> Symbol {
284+ match index {
285+ 0 => Symbol :: intern ( "'r" ) ,
286+ 1 => Symbol :: intern ( "'s" ) ,
287+ i => Symbol :: intern ( & format ! ( "'t{}" , i-2 ) ) ,
288+ }
289+ }
290+
268291 // Replace any anonymous late-bound regions with named
269292 // variants, using gensym'd identifiers, so that we can
270293 // clearly differentiate between named and unnamed regions in
@@ -286,27 +309,54 @@ fn in_binder<'a, 'gcx, 'tcx, T, U>(f: &mut fmt::Formatter,
286309 }
287310 } ;
288311
289- let new_value = tcx. replace_late_bound_regions ( & value, |br| {
290- let _ = start_or_continue ( f, "for<" , ", " ) ;
291- let br = match br {
292- ty:: BrNamed ( _, name) => {
293- let _ = write ! ( f, "{}" , name) ;
294- br
295- }
296- ty:: BrAnon ( _) |
297- ty:: BrFresh ( _) |
298- ty:: BrEnv => {
299- let name = Symbol :: intern ( "'r" ) ;
300- let _ = write ! ( f, "{}" , name) ;
301- ty:: BrNamed ( tcx. hir . local_def_id ( CRATE_NODE_ID ) ,
302- name)
303- }
304- } ;
305- tcx. mk_region ( ty:: ReLateBound ( ty:: DebruijnIndex :: new ( 1 ) , br) )
306- } ) . 0 ;
312+ // If displaying is just started, collect named late-bound regions.
313+ let display_just_started = tcx. display_used_late_bound_region_names . borrow ( ) . is_none ( ) ;
314+ if display_just_started {
315+ let mut collector = LateBoundRegionNameCollector ( FxHashSet ( ) ) ;
316+ value. visit_with ( & mut collector) ;
317+ * tcx. display_used_late_bound_region_names . borrow_mut ( ) = Some ( collector. 0 ) ;
318+ }
307319
320+ let old_region_index = tcx. display_late_bound_region_index . get ( ) ;
321+ let mut region_index = old_region_index;
322+ let new_value = {
323+ let used_region_names = tcx. display_used_late_bound_region_names . borrow ( ) ;
324+ let used_region_names = used_region_names. as_ref ( ) . unwrap ( ) ;
325+ tcx. replace_late_bound_regions ( & value, |br| {
326+ let _ = start_or_continue ( f, "for<" , ", " ) ;
327+ let br = match br {
328+ ty:: BrNamed ( _, name) => {
329+ let _ = write ! ( f, "{}" , name) ;
330+ br
331+ }
332+ ty:: BrAnon ( _) |
333+ ty:: BrFresh ( _) |
334+ ty:: BrEnv => {
335+ let name = loop {
336+ let name = name_by_region_index ( region_index) ;
337+ region_index += 1 ;
338+ if !used_region_names. contains ( & name) {
339+ break name;
340+ }
341+ } ;
342+ let _ = write ! ( f, "{}" , name) ;
343+ ty:: BrNamed ( tcx. hir . local_def_id ( CRATE_NODE_ID ) ,
344+ name)
345+ }
346+ } ;
347+ tcx. mk_region ( ty:: ReLateBound ( ty:: DebruijnIndex :: new ( 1 ) , br) )
348+ } ) . 0
349+ } ;
308350 start_or_continue ( f, "" , "> " ) ?;
309- write ! ( f, "{}" , new_value)
351+
352+ // Push current state to gcx, and restore after writing new_value.
353+ tcx. display_late_bound_region_index . set ( region_index) ;
354+ write ! ( f, "{}" , new_value) ?;
355+ tcx. display_late_bound_region_index . set ( old_region_index) ;
356+ if display_just_started {
357+ * tcx. display_used_late_bound_region_names . borrow_mut ( ) = None ;
358+ }
359+ Ok ( ( ) )
310360}
311361
312362impl < ' tcx > fmt:: Display for & ' tcx ty:: Slice < ty:: ExistentialPredicate < ' tcx > > {
@@ -782,7 +832,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
782832 write ! ( f, "}}" )
783833 }
784834 TyFnPtr ( ref bare_fn) => {
785- write ! ( f, "{}" , bare_fn. 0 )
835+ write ! ( f, "{}" , bare_fn)
786836 }
787837 TyInfer ( infer_ty) => write ! ( f, "{}" , infer_ty) ,
788838 TyError => write ! ( f, "[type error]" ) ,
0 commit comments