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;
6 use rustc::infer::canonical::QueryRegionConstraint;
7 use rustc::infer::outlives::env::RegionBoundPairs;
8 use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
9 use rustc::infer::region_constraints::{GenericKind, VerifyBound};
10 use rustc::infer::{self, InferCtxt, SubregionOrigin};
11 use rustc::mir::ConstraintCategory;
12 use rustc::ty::subst::UnpackedKind;
13 use rustc::ty::{self, TyCtxt};
14 use syntax_pos::DUMMY_SP;
16 crate struct ConstraintConversion<'a, 'gcx: 'tcx, 'tcx: 'a> {
17 infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
18 tcx: TyCtxt<'a, 'gcx, 'tcx>,
19 universal_regions: &'a UniversalRegions<'tcx>,
20 region_bound_pairs: &'a RegionBoundPairs<'tcx>,
21 implicit_region_bound: Option<ty::Region<'tcx>>,
22 param_env: ty::ParamEnv<'tcx>,
24 category: ConstraintCategory,
25 constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
28 impl<'a, 'gcx, 'tcx> ConstraintConversion<'a, 'gcx, 'tcx> {
30 infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
31 universal_regions: &'a UniversalRegions<'tcx>,
32 region_bound_pairs: &'a RegionBoundPairs<'tcx>,
33 implicit_region_bound: Option<ty::Region<'tcx>>,
34 param_env: ty::ParamEnv<'tcx>,
36 category: ConstraintCategory,
37 constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
44 implicit_region_bound,
52 pub(super) fn convert_all(&mut self, query_constraints: &[QueryRegionConstraint<'tcx>]) {
53 for query_constraint in query_constraints {
54 self.convert(query_constraint);
58 pub(super) fn convert(&mut self, query_constraint: &QueryRegionConstraint<'tcx>) {
59 debug!("generate: constraints at: {:#?}", self.locations);
61 // Extract out various useful fields we'll need below.
62 let ConstraintConversion {
65 implicit_region_bound,
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) =
75 query_constraint.no_bound_vars().unwrap_or_else(|| {
77 "query_constraint {:?} contained bound vars",
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);
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);
98 implicit_region_bound,
100 ).type_must_outlive(origin, t1, r2);
103 UnpackedKind::Const(_) => {
104 // Consts cannot outlive one another, so we
105 // don't need to handle any relations here.
110 fn verify_to_type_test(
112 generic_kind: GenericKind<'tcx>,
113 region: ty::Region<'tcx>,
114 verify_bound: VerifyBound<'tcx>,
115 ) -> TypeTest<'tcx> {
116 let lower_bound = self.to_region_vid(region);
121 locations: self.locations,
126 fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid {
127 if let ty::RePlaceholder(placeholder) = r {
129 .placeholder_region(self.infcx, *placeholder)
132 self.universal_regions.to_region_vid(r)
136 fn add_outlives(&mut self, sup: ty::RegionVid, sub: ty::RegionVid) {
138 .outlives_constraints
139 .push(OutlivesConstraint {
140 locations: self.locations,
141 category: self.category,
147 fn add_type_test(&mut self, type_test: TypeTest<'tcx>) {
148 debug!("add_type_test(type_test={:?})", type_test);
149 self.constraints.type_tests.push(type_test);
153 impl<'a, 'b, 'gcx, 'tcx> TypeOutlivesDelegate<'tcx>
154 for &'a mut ConstraintConversion<'b, 'gcx, 'tcx>
156 fn push_sub_region_constraint(
158 _origin: SubregionOrigin<'tcx>,
162 let b = self.to_region_vid(b);
163 let a = self.to_region_vid(a);
164 self.add_outlives(b, a);
169 _origin: SubregionOrigin<'tcx>,
170 kind: GenericKind<'tcx>,
172 bound: VerifyBound<'tcx>,
174 let type_test = self.verify_to_type_test(kind, a, bound);
175 self.add_type_test(type_test);