]> git.proxmox.com Git - rustc.git/blame - src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
New upstream version 1.34.2+dfsg1
[rustc.git] / src / librustc_mir / borrow_check / nll / type_check / constraint_conversion.rs
CommitLineData
9fa01778
XL
1use crate::borrow_check::nll::constraints::OutlivesConstraint;
2use crate::borrow_check::nll::region_infer::TypeTest;
3use crate::borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints};
4use crate::borrow_check::nll::universal_regions::UniversalRegions;
5use crate::borrow_check::nll::ToRegionVid;
8faf50e0 6use rustc::infer::canonical::QueryRegionConstraint;
0bf4aa26 7use rustc::infer::outlives::env::RegionBoundPairs;
8faf50e0
XL
8use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
9use rustc::infer::region_constraints::{GenericKind, VerifyBound};
a1dfa0c6 10use rustc::infer::{self, InferCtxt, SubregionOrigin};
0bf4aa26 11use rustc::mir::ConstraintCategory;
8faf50e0
XL
12use rustc::ty::subst::UnpackedKind;
13use rustc::ty::{self, TyCtxt};
14use syntax_pos::DUMMY_SP;
15
16crate 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 28impl<'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
148impl<'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}