@@ -43,6 +43,13 @@ pub struct RegionHighlightMode {
43
43
/// y: &'a u32)` and we want to give a name to the region of the
44
44
/// reference `x`.
45
45
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 ] ,
46
53
}
47
54
48
55
thread_local ! {
@@ -53,10 +60,12 @@ thread_local! {
53
60
}
54
61
55
62
impl RegionHighlightMode {
63
+ /// Read and return current region highlight settings (accesses thread-local state).a
56
64
pub fn get ( ) -> Self {
57
65
REGION_HIGHLIGHT_MODE . with ( |c| c. get ( ) )
58
66
}
59
67
68
+ /// Internal helper to update current settings during the execution of `op`.
60
69
fn set < R > (
61
70
old_mode : Self ,
62
71
new_mode : Self ,
@@ -70,6 +79,9 @@ impl RegionHighlightMode {
70
79
} )
71
80
}
72
81
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.
73
85
pub fn highlighting_region_vid < R > ( vid : RegionVid , number : usize , op : impl FnOnce ( ) -> R ) -> R {
74
86
let old_mode = Self :: get ( ) ;
75
87
assert ! ( old_mode. highlight_region_vid. is_none( ) ) ;
@@ -102,6 +114,52 @@ impl RegionHighlightMode {
102
114
op,
103
115
)
104
116
}
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
+ }
105
163
}
106
164
107
165
macro_rules! gen_display_debug_body {
@@ -802,6 +860,25 @@ define_print! {
802
860
}
803
861
}
804
862
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
+
805
882
define_print ! {
806
883
( ) ty:: RegionKind , ( self , f, cx) {
807
884
display {
@@ -818,10 +895,12 @@ define_print! {
818
895
write!( f, "{}" , data. name)
819
896
}
820
897
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, .. } ) => {
823
899
write!( f, "{}" , br)
824
900
}
901
+ ty:: RePlaceholder ( p) => {
902
+ write!( f, "{}" , p)
903
+ }
825
904
ty:: ReScope ( scope) if cx. identify_regions => {
826
905
match scope. data {
827
906
region:: ScopeData :: Node =>
0 commit comments