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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#![allow(unused)]
#[allow(dead_code)]
use hir::map as hir_map;
use rustc::dep_graph::DepKind;
use rustc::hir;
use rustc::hir::Ty_::*;
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc::ty::maps::Providers;
use rustc::ty::subst::UnpackedKind;
use rustc::ty::{self, CratePredicatesMap, TyCtxt};
use rustc_data_structures::sync::Lrc;
use util::nodemap::FxHashMap;
mod explicit;
mod implicit_empty;
mod implicit_infer;
pub mod test;
pub fn provide(providers: &mut Providers) {
*providers = Providers {
inferred_outlives_of,
inferred_outlives_crate,
..*providers
};
}
fn inferred_outlives_of<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
item_def_id: DefId,
) -> Lrc<Vec<ty::Predicate<'tcx>>> {
let id = tcx.hir
.as_local_node_id(item_def_id)
.expect("expected local def-id");
match tcx.hir.get(id) {
hir_map::NodeItem(item) => match item.node {
hir::ItemStruct(..) | hir::ItemEnum(..) | hir::ItemUnion(..) => {
let crate_map = tcx.inferred_outlives_crate(LOCAL_CRATE);
let dep_node = item_def_id.to_dep_node(tcx, DepKind::InferredOutlivesOf);
tcx.dep_graph.read(dep_node);
crate_map
.predicates
.get(&item_def_id)
.unwrap_or(&crate_map.empty_predicate)
.clone()
}
_ => Lrc::new(Vec::new()),
},
_ => Lrc::new(Vec::new()),
}
}
fn inferred_outlives_crate<'tcx>(
tcx: TyCtxt<'_, 'tcx, 'tcx>,
crate_num: CrateNum,
) -> Lrc<CratePredicatesMap<'tcx>> {
let exp = explicit::explicit_predicates(tcx, crate_num);
let mut global_inferred_outlives = implicit_infer::infer_predicates(tcx, &exp);
let mut predicates = global_inferred_outlives
.iter()
.map(|(&def_id, set)| {
let vec: Vec<ty::Predicate<'tcx>> = set.iter()
.map(
|ty::OutlivesPredicate(kind1, region2)| match kind1.unpack() {
UnpackedKind::Type(ty1) => ty::Predicate::TypeOutlives(ty::Binder::bind(
ty::OutlivesPredicate(ty1, region2),
)),
UnpackedKind::Lifetime(region1) => ty::Predicate::RegionOutlives(
ty::Binder::bind(ty::OutlivesPredicate(region1, region2)),
),
},
)
.collect();
(def_id, Lrc::new(vec))
})
.collect();
let empty_predicate = Lrc::new(Vec::new());
Lrc::new(ty::CratePredicatesMap {
predicates,
empty_predicate,
})
}