Skip to content

Commit 37b0b3e

Browse files
committed
generalize region highlights into a struct
1 parent 6a6d2f4 commit 37b0b3e

File tree

3 files changed

+91
-52
lines changed

3 files changed

+91
-52
lines changed

src/librustc/util/ppaux.rs

Lines changed: 79 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,87 @@ use syntax::ast::CRATE_NODE_ID;
2121
use syntax::symbol::{Symbol, InternedString};
2222
use hir;
2323

24+
/// The "region highlights" are used to control region printing during
25+
/// specific error messages. When a "region highlight" is enabled, it
26+
/// gives an alternate way to print specific regions. For now, we
27+
/// always print those regions using a number, so something like `'0`.
28+
///
29+
/// Regions not selected by the region highlight mode are presently
30+
/// unaffected.
31+
#[derive(Copy, Clone, Default)]
32+
pub struct RegionHighlightMode {
33+
/// If enabled, when we see the selected region inference
34+
/// variable, use `"'N"`; otherwise, use an empty string `""`
35+
/// (which is our ordinary behavior).
36+
highlight_region_vid: Option<(RegionVid, usize)>,
37+
38+
/// If enabled, when printing a "free region" that originated from
39+
/// the given `ty::BoundRegion`, print it as `'1`. Free regions that would ordinarily
40+
/// have names print as normal.
41+
///
42+
/// This is used when you have a signature like `fn foo(x: &u32,
43+
/// y: &'a u32)` and we want to give a name to the region of the
44+
/// reference `x`.
45+
highlight_bound_region: Option<(ty::BoundRegion, usize)>,
46+
}
47+
2448
thread_local! {
2549
/// Mechanism for highlighting of specific regions for display in NLL region inference errors.
2650
/// Contains region to highlight and counter for number to use when highlighting.
27-
static HIGHLIGHT_REGION_FOR_REGIONVID: Cell<Option<(RegionVid, usize)>> = Cell::new(None)
51+
static REGION_HIGHLIGHT_MODE: Cell<RegionHighlightMode> =
52+
Cell::new(RegionHighlightMode::default())
2853
}
2954

30-
thread_local! {
31-
/// Mechanism for highlighting of specific regions for display in NLL's 'borrow does not live
32-
/// long enough' errors. Contains a region to highlight and a counter to use.
33-
static HIGHLIGHT_REGION_FOR_BOUND_REGION: Cell<Option<(ty::BoundRegion, usize)>> =
34-
Cell::new(None)
55+
impl RegionHighlightMode {
56+
pub fn get() -> Self {
57+
REGION_HIGHLIGHT_MODE.with(|c| c.get())
58+
}
59+
60+
fn set<R>(
61+
old_mode: Self,
62+
new_mode: Self,
63+
op: impl FnOnce() -> R,
64+
) -> R {
65+
REGION_HIGHLIGHT_MODE.with(|c| {
66+
c.set(new_mode);
67+
let result = op();
68+
c.set(old_mode);
69+
result
70+
})
71+
}
72+
73+
pub fn highlighting_region_vid<R>(vid: RegionVid, number: usize, op: impl FnOnce() -> R) -> R {
74+
let old_mode = Self::get();
75+
assert!(old_mode.highlight_region_vid.is_none());
76+
Self::set(
77+
old_mode,
78+
Self {
79+
highlight_region_vid: Some((vid, number)),
80+
..old_mode
81+
},
82+
op,
83+
)
84+
}
85+
86+
/// During the execution of `op`, highlight the given bound
87+
/// region. We can only highlight one bound region at a time. See
88+
/// the field `highlight_bound_region` for more detailed notes.
89+
pub fn highlighting_bound_region<R>(
90+
br: ty::BoundRegion,
91+
number: usize,
92+
op: impl FnOnce() -> R,
93+
) -> R {
94+
let old_mode = Self::get();
95+
assert!(old_mode.highlight_bound_region.is_none());
96+
Self::set(
97+
old_mode,
98+
Self {
99+
highlight_bound_region: Some((br, number)),
100+
..old_mode
101+
},
102+
op,
103+
)
104+
}
35105
}
36106

37107
macro_rules! gen_display_debug_body {
@@ -553,42 +623,6 @@ pub fn parameterized<F: fmt::Write>(f: &mut F,
553623
PrintContext::new().parameterized(f, substs, did, projections)
554624
}
555625

556-
fn get_highlight_region_for_regionvid() -> Option<(RegionVid, usize)> {
557-
HIGHLIGHT_REGION_FOR_REGIONVID.with(|hr| hr.get())
558-
}
559-
560-
pub fn with_highlight_region_for_regionvid<R>(
561-
r: RegionVid,
562-
counter: usize,
563-
op: impl FnOnce() -> R
564-
) -> R {
565-
HIGHLIGHT_REGION_FOR_REGIONVID.with(|hr| {
566-
assert_eq!(hr.get(), None);
567-
hr.set(Some((r, counter)));
568-
let r = op();
569-
hr.set(None);
570-
r
571-
})
572-
}
573-
574-
fn get_highlight_region_for_bound_region() -> Option<(ty::BoundRegion, usize)> {
575-
HIGHLIGHT_REGION_FOR_BOUND_REGION.with(|hr| hr.get())
576-
}
577-
578-
pub fn with_highlight_region_for_bound_region<R>(
579-
r: ty::BoundRegion,
580-
counter: usize,
581-
op: impl Fn() -> R
582-
) -> R {
583-
HIGHLIGHT_REGION_FOR_BOUND_REGION.with(|hr| {
584-
assert_eq!(hr.get(), None);
585-
hr.set(Some((r, counter)));
586-
let r = op();
587-
hr.set(None);
588-
r
589-
})
590-
}
591-
592626
impl<'a, T: Print> Print for &'a T {
593627
fn print<F: fmt::Write>(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result {
594628
(*self).print(f, cx)
@@ -740,7 +774,7 @@ define_print! {
740774
return self.print_debug(f, cx);
741775
}
742776

743-
if let Some((region, counter)) = get_highlight_region_for_bound_region() {
777+
if let Some((region, counter)) = RegionHighlightMode::get().highlight_bound_region {
744778
if *self == region {
745779
return match *self {
746780
BrNamed(_, name) => write!(f, "{}", name),
@@ -807,7 +841,7 @@ define_print! {
807841
}
808842
}
809843
ty::ReVar(region_vid) => {
810-
if get_highlight_region_for_regionvid().is_some() {
844+
if RegionHighlightMode::get().highlight_region_vid.is_some() {
811845
write!(f, "{:?}", region_vid)
812846
} else if cx.identify_regions {
813847
write!(f, "'{}rv", region_vid.index())
@@ -944,7 +978,7 @@ impl fmt::Debug for ty::FloatVid {
944978

945979
impl fmt::Debug for ty::RegionVid {
946980
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
947-
if let Some((region, counter)) = get_highlight_region_for_regionvid() {
981+
if let Some((region, counter)) = RegionHighlightMode::get().highlight_region_vid {
948982
debug!("RegionVid.fmt: region={:?} self={:?} counter={:?}", region, self, counter);
949983
return if *self == region {
950984
write!(f, "'{:?}", counter)

src/librustc_mir/borrow_check/error_reporting.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc::mir::{
1212
TerminatorKind, VarBindingForm,
1313
};
1414
use rustc::ty::{self, DefIdTree};
15-
use rustc::util::ppaux::with_highlight_region_for_bound_region;
15+
use rustc::util::ppaux::RegionHighlightMode;
1616
use rustc_data_structures::fx::FxHashSet;
1717
use rustc_data_structures::indexed_vec::Idx;
1818
use rustc_data_structures::sync::Lrc;
@@ -2177,7 +2177,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
21772177
ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }),
21782178
_,
21792179
_,
2180-
) => with_highlight_region_for_bound_region(*br, counter, || ty.to_string()),
2180+
) => RegionHighlightMode::highlighting_bound_region(*br, counter, || ty.to_string()),
21812181
_ => ty.to_string(),
21822182
}
21832183
}
@@ -2189,7 +2189,11 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
21892189
ty::TyKind::Ref(region, _, _) => match region {
21902190
ty::RegionKind::ReLateBound(_, br)
21912191
| ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
2192-
with_highlight_region_for_bound_region(*br, counter, || region.to_string())
2192+
RegionHighlightMode::highlighting_bound_region(
2193+
*br,
2194+
counter,
2195+
|| region.to_string(),
2196+
)
21932197
}
21942198
_ => region.to_string(),
21952199
},

src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc::infer::InferCtxt;
88
use rustc::mir::Mir;
99
use rustc::ty::subst::{Substs, UnpackedKind};
1010
use rustc::ty::{self, RegionKind, RegionVid, Ty, TyCtxt};
11-
use rustc::util::ppaux::with_highlight_region_for_regionvid;
11+
use rustc::util::ppaux::RegionHighlightMode;
1212
use rustc_errors::DiagnosticBuilder;
1313
use syntax::ast::{Name, DUMMY_NODE_ID};
1414
use syntax::symbol::keywords;
@@ -396,7 +396,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
396396
argument_ty: Ty<'tcx>,
397397
counter: &mut usize,
398398
) -> Option<RegionName> {
399-
let type_name = with_highlight_region_for_regionvid(needle_fr, *counter, || {
399+
let type_name = RegionHighlightMode::highlighting_region_vid(needle_fr, *counter, || {
400400
infcx.extract_type_name(&argument_ty)
401401
});
402402

@@ -673,8 +673,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
673673
return None;
674674
}
675675

676-
let type_name = with_highlight_region_for_regionvid(
677-
fr, *counter, || infcx.extract_type_name(&return_ty));
676+
let type_name = RegionHighlightMode::highlighting_region_vid(
677+
fr, *counter, || infcx.extract_type_name(&return_ty),
678+
);
678679

679680
let mir_node_id = tcx.hir().as_local_node_id(mir_def_id).expect("non-local mir");
680681

0 commit comments

Comments
 (0)