Skip to content

Commit cafd83d

Browse files
committed
rustc: don't keep RegionHighlightMode in a thread-local.
1 parent 7c4eece commit cafd83d

File tree

6 files changed

+334
-306
lines changed

6 files changed

+334
-306
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 crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
33
use crate::infer::InferCtxt;
44
use crate::infer::type_variable::TypeVariableOrigin;
55
use crate::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: 124 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ use crate::infer::lexical_region_resolve::RegionResolutionError;
55
use crate::infer::ValuePairs;
66
use crate::infer::{SubregionOrigin, TypeTrace};
77
use crate::traits::{ObligationCause, ObligationCauseCode};
8-
use crate::ty;
8+
use crate::ty::{self, TyCtxt};
99
use crate::ty::error::ExpectedFound;
1010
use crate::ty::subst::SubstsRef;
11-
use crate::util::ppaux::RegionHighlightMode;
11+
use crate::ty::print::{Print, RegionHighlightMode, FmtPrinter};
12+
13+
use std::fmt::{self, Write};
1214

1315
impl NiceRegionError<'me, 'gcx, 'tcx> {
1416
/// When given a `ConcreteFailure` for a function with arguments containing a named region and
@@ -309,13 +311,48 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
309311
sup_placeholder: Option<ty::Region<'tcx>>,
310312
has_sub: Option<usize>,
311313
has_sup: Option<usize>,
312-
expected_trait_ref: ty::TraitRef<'_>,
313-
actual_trait_ref: ty::TraitRef<'_>,
314+
expected_trait_ref: ty::TraitRef<'tcx>,
315+
actual_trait_ref: ty::TraitRef<'tcx>,
314316
vid: Option<ty::Region<'tcx>>,
315317
expected_has_vid: Option<usize>,
316318
actual_has_vid: Option<usize>,
317319
any_self_ty_has_vid: bool,
318320
) {
321+
// HACK(eddyb) maybe move this in a more central location.
322+
#[derive(Copy, Clone)]
323+
struct Highlighted<'a, 'gcx, 'tcx, T> {
324+
tcx: TyCtxt<'a, 'gcx, 'tcx>,
325+
highlight: RegionHighlightMode,
326+
value: T,
327+
}
328+
329+
impl<'a, 'gcx, 'tcx, T> Highlighted<'a, 'gcx, 'tcx, T> {
330+
fn map<U>(self, f: impl FnOnce(T) -> U) -> Highlighted<'a, 'gcx, 'tcx, U> {
331+
Highlighted {
332+
tcx: self.tcx,
333+
highlight: self.highlight,
334+
value: f(self.value),
335+
}
336+
}
337+
}
338+
339+
impl<'tcx, T> fmt::Display for Highlighted<'_, '_, 'tcx, T>
340+
where T: for<'a, 'b> Print<'tcx,
341+
FmtPrinter<&'a mut fmt::Formatter<'b>>,
342+
Error = fmt::Error,
343+
>,
344+
{
345+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
346+
let mut printer = ty::print::FmtPrinter::new(f);
347+
printer.region_highlight_mode = self.highlight;
348+
349+
ty::print::PrintCx::with(self.tcx, printer, |cx| {
350+
self.value.print(cx)?;
351+
Ok(())
352+
})
353+
}
354+
}
355+
319356
// The weird thing here with the `maybe_highlighting_region` calls and the
320357
// the match inside is meant to be like this:
321358
//
@@ -331,112 +368,93 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
331368
// None, an then we check again inside the closure, but this
332369
// setup sort of minimized the number of calls and so form.
333370

334-
RegionHighlightMode::maybe_highlighting_region(sub_placeholder, has_sub, || {
335-
RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || {
336-
match (has_sub, has_sup) {
337-
(Some(n1), Some(n2)) => {
338-
if any_self_ty_has_vid {
339-
err.note(&format!(
340-
"`{}` would have to be implemented for the type `{}`, \
341-
for any two lifetimes `'{}` and `'{}`",
342-
expected_trait_ref,
343-
expected_trait_ref.self_ty(),
344-
std::cmp::min(n1, n2),
345-
std::cmp::max(n1, n2),
346-
));
347-
} else {
348-
err.note(&format!(
349-
"`{}` must implement `{}`, \
350-
for any two lifetimes `'{}` and `'{}`",
351-
expected_trait_ref.self_ty(),
352-
expected_trait_ref,
353-
std::cmp::min(n1, n2),
354-
std::cmp::max(n1, n2),
355-
));
356-
}
357-
}
358-
(Some(n), _) | (_, Some(n)) => {
359-
if any_self_ty_has_vid {
360-
err.note(&format!(
361-
"`{}` would have to be implemented for the type `{}`, \
362-
for any lifetime `'{}`",
363-
expected_trait_ref,
364-
expected_trait_ref.self_ty(),
365-
n,
366-
));
367-
} else {
368-
err.note(&format!(
369-
"`{}` must implement `{}`, for any lifetime `'{}`",
370-
expected_trait_ref.self_ty(),
371-
expected_trait_ref,
372-
n,
373-
));
374-
}
375-
}
376-
(None, None) => RegionHighlightMode::maybe_highlighting_region(
377-
vid,
378-
expected_has_vid,
379-
|| {
380-
if let Some(n) = expected_has_vid {
381-
err.note(&format!(
382-
"`{}` would have to be implemented for the type `{}`, \
383-
for some specific lifetime `'{}`",
384-
expected_trait_ref,
385-
expected_trait_ref.self_ty(),
386-
n,
387-
));
388-
} else {
389-
if any_self_ty_has_vid {
390-
err.note(&format!(
391-
"`{}` would have to be implemented for the type `{}`",
392-
expected_trait_ref,
393-
expected_trait_ref.self_ty(),
394-
));
395-
} else {
396-
err.note(&format!(
397-
"`{}` must implement `{}`",
398-
expected_trait_ref.self_ty(),
399-
expected_trait_ref,
400-
));
401-
}
402-
}
403-
},
404-
),
405-
}
406-
})
407-
});
371+
let highlight_trait_ref = |trait_ref| Highlighted {
372+
tcx: self.tcx(),
373+
highlight: RegionHighlightMode::default(),
374+
value: trait_ref,
375+
};
408376

409-
RegionHighlightMode::maybe_highlighting_region(
410-
vid,
411-
actual_has_vid,
412-
|| match actual_has_vid {
413-
Some(n) => {
414-
if any_self_ty_has_vid {
415-
err.note(&format!(
416-
"but `{}` is actually implemented for the type `{}`, \
417-
for some specific lifetime `'{}`",
418-
actual_trait_ref,
419-
actual_trait_ref.self_ty(),
420-
n
421-
));
422-
} else {
423-
err.note(&format!(
424-
"but `{}` actually implements `{}`, for some specific lifetime `'{}`",
425-
actual_trait_ref.self_ty(),
426-
actual_trait_ref,
427-
n
428-
));
377+
let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref);
378+
expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub);
379+
expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup);
380+
err.note(&{
381+
let passive_voice = match (has_sub, has_sup) {
382+
(Some(_), _) | (_, Some(_)) => any_self_ty_has_vid,
383+
(None, None) => {
384+
expected_trait_ref.highlight.maybe_highlighting_region(vid, expected_has_vid);
385+
match expected_has_vid {
386+
Some(_) => true,
387+
None => any_self_ty_has_vid,
429388
}
430389
}
390+
};
431391

432-
_ => {
433-
err.note(&format!(
434-
"but `{}` is actually implemented for the type `{}`",
435-
actual_trait_ref,
436-
actual_trait_ref.self_ty(),
437-
));
392+
let mut note = if passive_voice {
393+
format!(
394+
"`{}` would have to be implemented for the type `{}`",
395+
expected_trait_ref,
396+
expected_trait_ref.map(|tr| tr.self_ty()),
397+
)
398+
} else {
399+
format!(
400+
"`{}` must implement `{}`",
401+
expected_trait_ref.map(|tr| tr.self_ty()),
402+
expected_trait_ref,
403+
)
404+
};
405+
406+
match (has_sub, has_sup) {
407+
(Some(n1), Some(n2)) => {
408+
let _ = write!(note,
409+
", for any two lifetimes `'{}` and `'{}`",
410+
std::cmp::min(n1, n2),
411+
std::cmp::max(n1, n2),
412+
);
438413
}
439-
},
440-
);
414+
(Some(n), _) | (_, Some(n)) => {
415+
let _ = write!(note,
416+
", for any lifetime `'{}`",
417+
n,
418+
);
419+
}
420+
(None, None) => if let Some(n) = expected_has_vid {
421+
let _ = write!(note,
422+
", for some specific lifetime `'{}`",
423+
n,
424+
);
425+
},
426+
}
427+
428+
note
429+
});
430+
431+
let mut actual_trait_ref = highlight_trait_ref(actual_trait_ref);
432+
actual_trait_ref.highlight.maybe_highlighting_region(vid, actual_has_vid);
433+
err.note(&{
434+
let passive_voice = match actual_has_vid {
435+
Some(_) => any_self_ty_has_vid,
436+
None => true,
437+
};
438+
439+
let mut note = if passive_voice {
440+
format!(
441+
"but `{}` is actually implemented for the type `{}`",
442+
actual_trait_ref,
443+
actual_trait_ref.map(|tr| tr.self_ty()),
444+
)
445+
} else {
446+
format!(
447+
"but `{}` actually implements `{}`",
448+
actual_trait_ref.map(|tr| tr.self_ty()),
449+
actual_trait_ref,
450+
)
451+
};
452+
453+
if let Some(n) = actual_has_vid {
454+
let _ = write!(note, ", for some specific lifetime `'{}`", n);
455+
}
456+
457+
note
458+
});
441459
}
442460
}

0 commit comments

Comments
 (0)