@@ -43,6 +43,13 @@ pub struct RegionHighlightMode {
4343 /// y: &'a u32)` and we want to give a name to the region of the
4444 /// reference `x`.
4545 highlight_bound_region : Option < ( ty:: BoundRegion , usize ) > ,
46+
47+ /// If enabled, when printing a "placeholder" (what we get when
48+ /// substituting a universally quantified region as in `for<'a> T:
49+ /// Foo<'a>`), print out instead `'N`.
50+ ///
51+ /// (Unlike other modes, we can highlight more than one placeholder at a time.)
52+ highlight_placeholders : [ Option < ( ty:: PlaceholderRegion , usize ) > ; 2 ] ,
4653}
4754
4855thread_local ! {
@@ -53,10 +60,12 @@ thread_local! {
5360}
5461
5562impl RegionHighlightMode {
63+ /// Read and return current region highlight settings (accesses thread-local state).a
5664 pub fn get ( ) -> Self {
5765 REGION_HIGHLIGHT_MODE . with ( |c| c. get ( ) )
5866 }
5967
68+ /// Internal helper to update current settings during the execution of `op`.
6069 fn set < R > (
6170 old_mode : Self ,
6271 new_mode : Self ,
@@ -70,6 +79,9 @@ impl RegionHighlightMode {
7079 } )
7180 }
7281
82+ /// During the execution of `op`, highlight the region inference
83+ /// vairable `vid` as `'N`. We can only highlight one region vid
84+ /// at a time.
7385 pub fn highlighting_region_vid < R > ( vid : RegionVid , number : usize , op : impl FnOnce ( ) -> R ) -> R {
7486 let old_mode = Self :: get ( ) ;
7587 assert ! ( old_mode. highlight_region_vid. is_none( ) ) ;
@@ -102,6 +114,52 @@ impl RegionHighlightMode {
102114 op,
103115 )
104116 }
117+
118+ /// During the execution of `op`, highlight the given placeholders
119+ /// with the given numbers. Unlike other modes: non-highlighted
120+ /// placeholders are printed as `'_` (where they might normally print
121+ /// differently. This may want to be tweaked; but we do it for two reasons
122+ ///
123+ /// (a) to draw attention to the placeholders we are trying to highlight
124+ /// (b) because placeholder names can come from other scopes than the one
125+ /// in which the error occurred, so that can be misleading.
126+ ///
127+ /// We can highlight up to two placeholders at a time.
128+ pub fn highlighting_placeholder < R > (
129+ placeholder : ty:: PlaceholderRegion ,
130+ number : usize ,
131+ op : impl FnOnce ( ) -> R ,
132+ ) -> R {
133+ let old_mode = Self :: get ( ) ;
134+ let mut new_mode = old_mode;
135+ let first_avail_slot = new_mode. highlight_placeholders . iter_mut ( )
136+ . filter ( |s| s. is_none ( ) )
137+ . next ( )
138+ . unwrap_or_else ( || {
139+ panic ! (
140+ "can only highlight {} placeholders at a time" ,
141+ old_mode. highlight_placeholders. len( ) ,
142+ )
143+ } ) ;
144+ * first_avail_slot = Some ( ( placeholder, number) ) ;
145+ Self :: set ( old_mode, new_mode, op)
146+ }
147+
148+ /// Returns true if any placeholders are highlighted.
149+ pub fn any_placeholders_highlighted ( & self ) -> bool {
150+ self . highlight_placeholders . iter ( ) . any ( |p| p. is_some ( ) )
151+ }
152+
153+ /// Returns `Some(N)` if the placeholder `p` is highlighted to print as `'N`.
154+ pub fn placeholder_highlight ( & self , p : ty:: PlaceholderRegion ) -> Option < usize > {
155+ self . highlight_placeholders
156+ . iter ( )
157+ . filter_map ( |h| match h {
158+ & Some ( ( h, n) ) if h == p => Some ( n) ,
159+ _ => None ,
160+ } )
161+ . next ( )
162+ }
105163}
106164
107165macro_rules! gen_display_debug_body {
@@ -802,6 +860,25 @@ define_print! {
802860 }
803861}
804862
863+ define_print ! {
864+ ( ) ty:: PlaceholderRegion , ( self , f, cx) {
865+ display {
866+ if cx. is_verbose {
867+ return self . print_debug( f, cx) ;
868+ }
869+
870+ let highlight = RegionHighlightMode :: get( ) ;
871+ if let Some ( counter) = highlight. placeholder_highlight( * self ) {
872+ write!( f, "'{}" , counter)
873+ } else if highlight. any_placeholders_highlighted( ) {
874+ write!( f, "'_" )
875+ } else {
876+ write!( f, "{}" , self . name)
877+ }
878+ }
879+ }
880+ }
881+
805882define_print ! {
806883 ( ) ty:: RegionKind , ( self , f, cx) {
807884 display {
@@ -818,10 +895,12 @@ define_print! {
818895 write!( f, "{}" , data. name)
819896 }
820897 ty:: ReLateBound ( _, br) |
821- ty:: ReFree ( ty:: FreeRegion { bound_region: br, .. } ) |
822- ty:: RePlaceholder ( ty:: PlaceholderRegion { name: br, .. } ) => {
898+ ty:: ReFree ( ty:: FreeRegion { bound_region: br, .. } ) => {
823899 write!( f, "{}" , br)
824900 }
901+ ty:: RePlaceholder ( p) => {
902+ write!( f, "{}" , p)
903+ }
825904 ty:: ReScope ( scope) if cx. identify_regions => {
826905 match scope. data {
827906 region:: ScopeData :: Node =>
0 commit comments