]>
Commit | Line | Data |
---|---|---|
9fa01778 XL |
1 | use crate::borrow_check::nll::constraints::OutlivesConstraint; |
2 | use crate::borrow_check::nll::region_infer::TypeTest; | |
3 | use crate::borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints}; | |
4 | use crate::borrow_check::nll::universal_regions::UniversalRegions; | |
5 | use crate::borrow_check::nll::ToRegionVid; | |
8faf50e0 | 6 | use rustc::infer::canonical::QueryRegionConstraint; |
0bf4aa26 | 7 | use rustc::infer::outlives::env::RegionBoundPairs; |
8faf50e0 XL |
8 | use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate}; |
9 | use rustc::infer::region_constraints::{GenericKind, VerifyBound}; | |
a1dfa0c6 | 10 | use rustc::infer::{self, InferCtxt, SubregionOrigin}; |
0bf4aa26 | 11 | use rustc::mir::ConstraintCategory; |
8faf50e0 XL |
12 | use rustc::ty::subst::UnpackedKind; |
13 | use rustc::ty::{self, TyCtxt}; | |
14 | use syntax_pos::DUMMY_SP; | |
15 | ||
16 | crate struct ConstraintConversion<'a, 'gcx: 'tcx, 'tcx: 'a> { | |
a1dfa0c6 | 17 | infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, |
8faf50e0 | 18 | tcx: TyCtxt<'a, 'gcx, 'tcx>, |
94b46f34 | 19 | universal_regions: &'a UniversalRegions<'tcx>, |
0bf4aa26 | 20 | region_bound_pairs: &'a RegionBoundPairs<'tcx>, |
8faf50e0 XL |
21 | implicit_region_bound: Option<ty::Region<'tcx>>, |
22 | param_env: ty::ParamEnv<'tcx>, | |
23 | locations: Locations, | |
0bf4aa26 | 24 | category: ConstraintCategory, |
a1dfa0c6 | 25 | constraints: &'a mut MirTypeckRegionConstraints<'tcx>, |
94b46f34 XL |
26 | } |
27 | ||
8faf50e0 | 28 | impl<'a, 'gcx, 'tcx> ConstraintConversion<'a, 'gcx, 'tcx> { |
94b46f34 | 29 | crate fn new( |
a1dfa0c6 | 30 | infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, |
94b46f34 | 31 | universal_regions: &'a UniversalRegions<'tcx>, |
0bf4aa26 | 32 | region_bound_pairs: &'a RegionBoundPairs<'tcx>, |
8faf50e0 XL |
33 | implicit_region_bound: Option<ty::Region<'tcx>>, |
34 | param_env: ty::ParamEnv<'tcx>, | |
35 | locations: Locations, | |
0bf4aa26 | 36 | category: ConstraintCategory, |
a1dfa0c6 | 37 | constraints: &'a mut MirTypeckRegionConstraints<'tcx>, |
94b46f34 XL |
38 | ) -> Self { |
39 | Self { | |
a1dfa0c6 XL |
40 | infcx, |
41 | tcx: infcx.tcx, | |
94b46f34 | 42 | universal_regions, |
8faf50e0 XL |
43 | region_bound_pairs, |
44 | implicit_region_bound, | |
45 | param_env, | |
46 | locations, | |
0bf4aa26 | 47 | category, |
a1dfa0c6 | 48 | constraints, |
94b46f34 XL |
49 | } |
50 | } | |
51 | ||
8faf50e0 XL |
52 | pub(super) fn convert_all(&mut self, query_constraints: &[QueryRegionConstraint<'tcx>]) { |
53 | for query_constraint in query_constraints { | |
54 | self.convert(query_constraint); | |
55 | } | |
56 | } | |
57 | ||
58 | pub(super) fn convert(&mut self, query_constraint: &QueryRegionConstraint<'tcx>) { | |
59 | debug!("generate: constraints at: {:#?}", self.locations); | |
60 | ||
61 | // Extract out various useful fields we'll need below. | |
62 | let ConstraintConversion { | |
63 | tcx, | |
64 | region_bound_pairs, | |
65 | implicit_region_bound, | |
66 | param_env, | |
67 | .. | |
68 | } = *self; | |
69 | ||
70 | // At the moment, we never generate any "higher-ranked" | |
71 | // region constraints like `for<'a> 'a: 'b`. At some point | |
72 | // when we move to universes, we will, and this assertion | |
73 | // will start to fail. | |
74 | let ty::OutlivesPredicate(k1, r2) = | |
a1dfa0c6 | 75 | query_constraint.no_bound_vars().unwrap_or_else(|| { |
8faf50e0 | 76 | bug!( |
a1dfa0c6 | 77 | "query_constraint {:?} contained bound vars", |
8faf50e0 XL |
78 | query_constraint, |
79 | ); | |
80 | }); | |
81 | ||
82 | match k1.unpack() { | |
83 | UnpackedKind::Lifetime(r1) => { | |
84 | let r1_vid = self.to_region_vid(r1); | |
85 | let r2_vid = self.to_region_vid(r2); | |
86 | self.add_outlives(r1_vid, r2_vid); | |
94b46f34 | 87 | } |
94b46f34 | 88 | |
8faf50e0 XL |
89 | UnpackedKind::Type(t1) => { |
90 | // we don't actually use this for anything, but | |
91 | // the `TypeOutlives` code needs an origin. | |
92 | let origin = infer::RelateParamBound(DUMMY_SP, t1); | |
93 | ||
94 | TypeOutlives::new( | |
95 | &mut *self, | |
96 | tcx, | |
97 | region_bound_pairs, | |
98 | implicit_region_bound, | |
99 | param_env, | |
100 | ).type_must_outlive(origin, t1, r2); | |
101 | } | |
94b46f34 | 102 | } |
94b46f34 XL |
103 | } |
104 | ||
105 | fn verify_to_type_test( | |
a1dfa0c6 | 106 | &mut self, |
8faf50e0 XL |
107 | generic_kind: GenericKind<'tcx>, |
108 | region: ty::Region<'tcx>, | |
0bf4aa26 | 109 | verify_bound: VerifyBound<'tcx>, |
94b46f34 | 110 | ) -> TypeTest<'tcx> { |
8faf50e0 | 111 | let lower_bound = self.to_region_vid(region); |
94b46f34 | 112 | |
94b46f34 XL |
113 | TypeTest { |
114 | generic_kind, | |
115 | lower_bound, | |
8faf50e0 | 116 | locations: self.locations, |
0bf4aa26 | 117 | verify_bound, |
94b46f34 XL |
118 | } |
119 | } | |
120 | ||
a1dfa0c6 XL |
121 | fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid { |
122 | if let ty::RePlaceholder(placeholder) = r { | |
123 | self.constraints | |
124 | .placeholder_region(self.infcx, *placeholder) | |
125 | .to_region_vid() | |
126 | } else { | |
127 | self.universal_regions.to_region_vid(r) | |
128 | } | |
94b46f34 XL |
129 | } |
130 | ||
8faf50e0 | 131 | fn add_outlives(&mut self, sup: ty::RegionVid, sub: ty::RegionVid) { |
a1dfa0c6 XL |
132 | self.constraints |
133 | .outlives_constraints | |
134 | .push(OutlivesConstraint { | |
135 | locations: self.locations, | |
136 | category: self.category, | |
137 | sub, | |
138 | sup, | |
139 | }); | |
94b46f34 XL |
140 | } |
141 | ||
142 | fn add_type_test(&mut self, type_test: TypeTest<'tcx>) { | |
0bf4aa26 | 143 | debug!("add_type_test(type_test={:?})", type_test); |
a1dfa0c6 | 144 | self.constraints.type_tests.push(type_test); |
94b46f34 XL |
145 | } |
146 | } | |
8faf50e0 XL |
147 | |
148 | impl<'a, 'b, 'gcx, 'tcx> TypeOutlivesDelegate<'tcx> | |
149 | for &'a mut ConstraintConversion<'b, 'gcx, 'tcx> | |
150 | { | |
151 | fn push_sub_region_constraint( | |
152 | &mut self, | |
153 | _origin: SubregionOrigin<'tcx>, | |
154 | a: ty::Region<'tcx>, | |
155 | b: ty::Region<'tcx>, | |
156 | ) { | |
a1dfa0c6 XL |
157 | let b = self.to_region_vid(b); |
158 | let a = self.to_region_vid(a); | |
8faf50e0 XL |
159 | self.add_outlives(b, a); |
160 | } | |
161 | ||
162 | fn push_verify( | |
163 | &mut self, | |
164 | _origin: SubregionOrigin<'tcx>, | |
165 | kind: GenericKind<'tcx>, | |
166 | a: ty::Region<'tcx>, | |
167 | bound: VerifyBound<'tcx>, | |
168 | ) { | |
169 | let type_test = self.verify_to_type_test(kind, a, bound); | |
170 | self.add_type_test(type_test); | |
171 | } | |
172 | } |