Skip to content

Commit 400b50d

Browse files
committed
rustc: don't keep RegionHighlightMode in a thread-local.
1 parent 3cbe070 commit 400b50d

File tree

6 files changed

+267
-257
lines changed

6 files changed

+267
-257
lines changed

src/librustc/infer/error_reporting/need_type_info.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use hir::intravisit::{self, Visitor, NestedVisitorMap};
33
use infer::InferCtxt;
44
use infer::type_variable::TypeVariableOrigin;
55
use ty::{self, Ty, Infer, TyVar};
6+
use ty::print::Print;
67
use syntax::source_map::CompilerDesugaringKind;
78
use syntax_pos::Span;
89
use errors::DiagnosticBuilder;
@@ -64,18 +65,28 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
6465

6566

6667
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
67-
pub fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String {
68+
pub fn extract_type_name(
69+
&self,
70+
ty: &'a Ty<'tcx>,
71+
highlight: Option<ty::print::RegionHighlightMode>,
72+
) -> String {
6873
if let ty::Infer(ty::TyVar(ty_vid)) = (*ty).sty {
6974
let ty_vars = self.type_variables.borrow();
7075
if let TypeVariableOrigin::TypeParameterDefinition(_, name) =
7176
*ty_vars.var_origin(ty_vid) {
72-
name.to_string()
73-
} else {
74-
ty.to_string()
77+
return name.to_string();
7578
}
76-
} else {
77-
ty.to_string()
7879
}
80+
81+
let mut s = String::new();
82+
let mut printer = ty::print::FmtPrinter::new(&mut s);
83+
if let Some(highlight) = highlight {
84+
printer.region_highlight_mode = highlight;
85+
}
86+
let _ = ty::print::PrintCx::with(self.tcx, printer, |cx| {
87+
ty.print(cx)
88+
});
89+
s
7990
}
8091

8192
pub fn need_type_info_err(&self,
@@ -84,7 +95,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
8495
ty: Ty<'tcx>)
8596
-> DiagnosticBuilder<'gcx> {
8697
let ty = self.resolve_type_vars_if_possible(&ty);
87-
let name = self.extract_type_name(&ty);
98+
let name = self.extract_type_name(&ty, None);
8899

89100
let mut err_span = span;
90101
let mut labels = vec![(

src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ use traits::{ObligationCause, ObligationCauseCode};
77
use ty;
88
use ty::error::ExpectedFound;
99
use ty::subst::Substs;
10+
use ty::print::{Print, PrettyPrinter};
1011
use util::common::ErrorReported;
11-
use util::ppaux::RegionHighlightMode;
12+
13+
use std::fmt::Write;
1214

1315
impl NiceRegionError<'me, 'gcx, 'tcx> {
1416
/// When given a `ConcreteFailure` for a function with arguments containing a named region and
@@ -241,65 +243,63 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
241243
.tcx
242244
.any_free_region_meets(&actual_trait_ref.self_ty(), |r| Some(r) == vid);
243245

244-
RegionHighlightMode::maybe_highlighting_region(sub_placeholder, has_sub, || {
245-
RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || {
246-
match (has_sub, has_sup) {
247-
(Some(n1), Some(n2)) => {
248-
err.note(&format!(
249-
"`{}` must implement `{}` \
250-
for any two lifetimes `'{}` and `'{}`",
251-
expected_trait_ref.self_ty(),
252-
expected_trait_ref,
253-
std::cmp::min(n1, n2),
254-
std::cmp::max(n1, n2),
255-
));
256-
}
257-
(Some(n), _) | (_, Some(n)) => {
258-
err.note(&format!(
259-
"`{}` must implement `{}` \
260-
for any lifetime `'{}`",
261-
expected_trait_ref.self_ty(),
262-
expected_trait_ref,
263-
n,
264-
));
265-
}
266-
(None, None) => {
267-
err.note(&format!(
268-
"`{}` must implement `{}`",
269-
expected_trait_ref.self_ty(),
270-
expected_trait_ref,
271-
));
272-
}
273-
}
274-
})
275-
});
246+
{
247+
let mut note = String::new();
248+
let mut printer = ty::print::FmtPrinter::new(&mut note);
249+
printer.region_highlight_mode.maybe_highlighting_region(sub_placeholder, has_sub);
250+
printer.region_highlight_mode.maybe_highlighting_region(sup_placeholder, has_sup);
251+
252+
let _ = ty::print::PrintCx::with(self.tcx, printer, |mut cx| {
253+
write!(cx.printer, "`")?;
254+
cx = cx.nest(|cx| expected_trait_ref.self_ty().print(cx))?;
255+
write!(cx.printer, "` must implement `")?;
256+
cx = cx.nest(|cx| expected_trait_ref.print(cx))?;
257+
write!(cx.printer, "`")
258+
});
276259

277-
RegionHighlightMode::maybe_highlighting_region(vid, has_vid, || match has_vid {
278-
Some(n) => {
279-
if self_ty_has_vid {
280-
err.note(&format!(
281-
"but `{}` only implements `{}` for the lifetime `'{}`",
282-
actual_trait_ref.self_ty(),
283-
actual_trait_ref,
284-
n
285-
));
286-
} else {
287-
err.note(&format!(
288-
"but `{}` only implements `{}` for some lifetime `'{}`",
289-
actual_trait_ref.self_ty(),
290-
actual_trait_ref,
291-
n
292-
));
260+
match (has_sub, has_sup) {
261+
(Some(n1), Some(n2)) => {
262+
let _ = write!(note,
263+
" for any two lifetimes `'{}` and `'{}`",
264+
std::cmp::min(n1, n2),
265+
std::cmp::max(n1, n2),
266+
);
293267
}
268+
(Some(n), _) | (_, Some(n)) => {
269+
let _ = write!(note,
270+
" for any lifetime `'{}`",
271+
n,
272+
);
273+
}
274+
(None, None) => {}
294275
}
295-
None => {
296-
err.note(&format!(
297-
"but `{}` only implements `{}`",
298-
actual_trait_ref.self_ty(),
299-
actual_trait_ref,
300-
));
276+
277+
err.note(&note);
278+
}
279+
280+
{
281+
let mut note = String::new();
282+
let mut printer = ty::print::FmtPrinter::new(&mut note);
283+
printer.region_highlight_mode.maybe_highlighting_region(vid, has_vid);
284+
285+
let _ = ty::print::PrintCx::with(self.tcx, printer, |mut cx| {
286+
write!(cx.printer, "but `")?;
287+
cx = cx.nest(|cx| actual_trait_ref.self_ty().print(cx))?;
288+
write!(cx.printer, "` only implements `")?;
289+
cx = cx.nest(|cx| actual_trait_ref.print(cx))?;
290+
write!(cx.printer, "`")
291+
});
292+
293+
if let Some(n) = has_vid {
294+
let _ = write!(note,
295+
" for {} lifetime `'{}`",
296+
if self_ty_has_vid { "the" } else { "some" },
297+
n
298+
);
301299
}
302-
});
300+
301+
err.note(&note);
302+
}
303303

304304
err.emit();
305305
ErrorReported

src/librustc/ty/print.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,103 @@ pub fn with_crate_prefix<F: FnOnce() -> R, R>(f: F) -> R {
4848
// FIXME(eddyb) this module uses `pub(crate)` for things used only
4949
// from `ppaux` - when that is removed, they can be re-privatized.
5050

51+
/// The "region highlights" are used to control region printing during
52+
/// specific error messages. When a "region highlight" is enabled, it
53+
/// gives an alternate way to print specific regions. For now, we
54+
/// always print those regions using a number, so something like `'0`.
55+
///
56+
/// Regions not selected by the region highlight mode are presently
57+
/// unaffected.
58+
#[derive(Copy, Clone, Default)]
59+
pub struct RegionHighlightMode {
60+
/// If enabled, when we see the selected region, use `"'N"`
61+
/// instead of the ordinary behavior.
62+
highlight_regions: [Option<(ty::RegionKind, usize)>; 3],
63+
64+
/// If enabled, when printing a "free region" that originated from
65+
/// the given `ty::BoundRegion`, print it as `'1`. Free regions that would ordinarily
66+
/// have names print as normal.
67+
///
68+
/// This is used when you have a signature like `fn foo(x: &u32,
69+
/// y: &'a u32)` and we want to give a name to the region of the
70+
/// reference `x`.
71+
pub(crate) highlight_bound_region: Option<(ty::BoundRegion, usize)>,
72+
}
73+
74+
impl RegionHighlightMode {
75+
/// If `region` and `number` are both `Some`, invoke
76+
/// `highlighting_region`.
77+
pub fn maybe_highlighting_region(
78+
&mut self,
79+
region: Option<ty::Region<'_>>,
80+
number: Option<usize>,
81+
) {
82+
if let Some(k) = region {
83+
if let Some(n) = number {
84+
self.highlighting_region(k, n);
85+
}
86+
}
87+
}
88+
89+
/// Highlight the region inference variable `vid` as `'N`.
90+
pub fn highlighting_region(
91+
&mut self,
92+
region: ty::Region<'_>,
93+
number: usize,
94+
) {
95+
let num_slots = self.highlight_regions.len();
96+
let first_avail_slot = self.highlight_regions.iter_mut()
97+
.filter(|s| s.is_none())
98+
.next()
99+
.unwrap_or_else(|| {
100+
bug!(
101+
"can only highlight {} placeholders at a time",
102+
num_slots,
103+
)
104+
});
105+
*first_avail_slot = Some((*region, number));
106+
}
107+
108+
/// Convenience wrapper for `highlighting_region`
109+
pub fn highlighting_region_vid(
110+
&mut self,
111+
vid: ty::RegionVid,
112+
number: usize,
113+
) {
114+
self.highlighting_region(&ty::ReVar(vid), number)
115+
}
116+
117+
/// Returns `Some(n)` with the number to use for the given region,
118+
/// if any.
119+
pub(crate) fn region_highlighted(&self, region: ty::Region<'_>) -> Option<usize> {
120+
self
121+
.highlight_regions
122+
.iter()
123+
.filter_map(|h| match h {
124+
Some((r, n)) if r == region => Some(*n),
125+
_ => None,
126+
})
127+
.next()
128+
}
129+
130+
/// Highlight the given bound region.
131+
/// We can only highlight one bound region at a time. See
132+
/// the field `highlight_bound_region` for more detailed notes.
133+
pub fn highlighting_bound_region(
134+
&mut self,
135+
br: ty::BoundRegion,
136+
number: usize,
137+
) {
138+
assert!(self.highlight_bound_region.is_none());
139+
self.highlight_bound_region = Some((br, number));
140+
}
141+
142+
/// Returns `Some(N)` if the placeholder `p` is highlighted to print as `'N`.
143+
pub(crate) fn placeholder_highlight(&self, p: ty::PlaceholderRegion) -> Option<usize> {
144+
self.region_highlighted(&ty::RePlaceholder(p))
145+
}
146+
}
147+
51148
struct LateBoundRegionNameCollector(FxHashSet<InternedString>);
52149
impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector {
53150
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
@@ -238,6 +335,10 @@ pub trait PrettyPrinter: Printer<Error = fmt::Error, Path = Self> + fmt::Write {
238335
config: self.config,
239336
})
240337
}
338+
339+
fn region_highlight_mode(&self) -> RegionHighlightMode {
340+
RegionHighlightMode::default()
341+
}
241342
}
242343

243344
macro_rules! nest {
@@ -450,13 +551,15 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
450551
pub struct FmtPrinter<F: fmt::Write> {
451552
pub(crate) fmt: F,
452553
empty: bool,
554+
pub region_highlight_mode: RegionHighlightMode,
453555
}
454556

455557
impl<F: fmt::Write> FmtPrinter<F> {
456558
pub fn new(fmt: F) -> Self {
457559
FmtPrinter {
458560
fmt,
459561
empty: true,
562+
region_highlight_mode: RegionHighlightMode::default(),
460563
}
461564
}
462565
}
@@ -918,4 +1021,8 @@ impl<F: fmt::Write> PrettyPrinter for FmtPrinter<F> {
9181021
config: self.config,
9191022
})
9201023
}
1024+
1025+
fn region_highlight_mode(&self) -> RegionHighlightMode {
1026+
self.region_highlight_mode
1027+
}
9211028
}

0 commit comments

Comments
 (0)