1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use infer::InferCtxt;
use infer::lexical_region_resolve::RegionResolutionError;
use infer::lexical_region_resolve::RegionResolutionError::*;
use syntax::source_map::Span;
use ty::{self, TyCtxt};
use util::common::ErrorReported;
mod different_lifetimes;
mod find_anon_type;
mod named_anon_conflict;
mod outlives_closure;
mod static_impl_trait;
mod util;
impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
pub fn try_report_nice_region_error(&self, error: &RegionResolutionError<'tcx>) -> bool {
match *error {
ConcreteFailure(..) | SubSupConflict(..) => {}
_ => return false,
}
if let Some(tables) = self.in_progress_tables {
let tables = tables.borrow();
NiceRegionError::new(self.tcx, error.clone(), Some(&tables)).try_report().is_some()
} else {
NiceRegionError::new(self.tcx, error.clone(), None).try_report().is_some()
}
}
}
pub struct NiceRegionError<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
error: Option<RegionResolutionError<'tcx>>,
regions: Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)>,
tables: Option<&'cx ty::TypeckTables<'tcx>>,
}
impl<'cx, 'gcx, 'tcx> NiceRegionError<'cx, 'gcx, 'tcx> {
pub fn new(
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
error: RegionResolutionError<'tcx>,
tables: Option<&'cx ty::TypeckTables<'tcx>>,
) -> Self {
Self { tcx, error: Some(error), regions: None, tables }
}
pub fn new_from_span(
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
span: Span,
sub: ty::Region<'tcx>,
sup: ty::Region<'tcx>,
tables: Option<&'cx ty::TypeckTables<'tcx>>,
) -> Self {
Self { tcx, error: None, regions: Some((span, sub, sup)), tables }
}
pub fn try_report_from_nll(&self) -> Option<ErrorReported> {
self.try_report_named_anon_conflict()
}
pub fn try_report(&self) -> Option<ErrorReported> {
self.try_report_named_anon_conflict()
.or_else(|| self.try_report_anon_anon_conflict())
.or_else(|| self.try_report_outlives_closure())
.or_else(|| self.try_report_static_impl_trait())
}
pub fn get_regions(&self) -> (Span, ty::Region<'tcx>, ty::Region<'tcx>) {
match (&self.error, self.regions) {
(&Some(ConcreteFailure(ref origin, sub, sup)), None) => (origin.span(), sub, sup),
(&Some(SubSupConflict(_, ref origin, sub, _, sup)), None) => (origin.span(), sub, sup),
(None, Some((span, sub, sup))) => (span, sub, sup),
(Some(_), Some(_)) => panic!("incorrectly built NiceRegionError"),
_ => panic!("trying to report on an incorrect lifetime failure"),
}
}
}