Skip to content

Commit 1597f2a

Browse files
committed
add the ability to highlight placeholders
1 parent 37b0b3e commit 1597f2a

File tree

1 file changed

+81
-2
lines changed

1 file changed

+81
-2
lines changed

src/librustc/util/ppaux.rs

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4855
thread_local! {
@@ -53,10 +60,12 @@ thread_local! {
5360
}
5461

5562
impl 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

107165
macro_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+
805882
define_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

Comments
 (0)