Skip to content

Commit 89bcc9f

Browse files
committed
instantiate closure requirements as query-region-constraints [WIP]
Marked as WIP because it invalidates some tests.
1 parent d702227 commit 89bcc9f

File tree

3 files changed

+48
-60
lines changed

3 files changed

+48
-60
lines changed

src/librustc_mir/borrow_check/nll/region_infer/mod.rs

Lines changed: 38 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,22 @@
1111
use super::universal_regions::UniversalRegions;
1212
use borrow_check::nll::region_infer::values::ToElementIndex;
1313
use rustc::hir::def_id::DefId;
14+
use rustc::infer::canonical::QueryRegionConstraint;
1415
use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
1516
use rustc::infer::region_constraints::{GenericKind, VarInfos};
1617
use rustc::infer::InferCtxt;
1718
use rustc::infer::NLLRegionVariableOrigin;
18-
use rustc::infer::RegionObligation;
1919
use rustc::infer::RegionVariableOrigin;
20-
use rustc::infer::SubregionOrigin;
2120
use rustc::mir::{
2221
ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, Local, Location,
2322
Mir,
2423
};
25-
use rustc::traits::ObligationCause;
26-
use rustc::ty::{self, RegionVid, Ty, TypeFoldable};
24+
use rustc::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable};
2725
use rustc::util::common::{self, ErrorReported};
2826
use rustc_data_structures::bitvec::BitVector;
2927
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
3028
use std::fmt;
3129
use std::rc::Rc;
32-
use syntax::ast;
3330
use syntax_pos::Span;
3431

3532
mod annotation;
@@ -1162,16 +1159,15 @@ impl fmt::Debug for OutlivesConstraint {
11621159
pub trait ClosureRegionRequirementsExt<'gcx, 'tcx> {
11631160
fn apply_requirements(
11641161
&self,
1165-
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
1166-
body_id: ast::NodeId,
1162+
tcx: TyCtxt<'_, 'gcx, 'tcx>,
11671163
location: Location,
11681164
closure_def_id: DefId,
11691165
closure_substs: ty::ClosureSubsts<'tcx>,
1170-
);
1166+
) -> Vec<QueryRegionConstraint<'tcx>>;
11711167

11721168
fn subst_closure_mapping<T>(
11731169
&self,
1174-
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
1170+
tcx: TyCtxt<'_, 'gcx, 'tcx>,
11751171
closure_mapping: &IndexVec<RegionVid, ty::Region<'tcx>>,
11761172
value: &T,
11771173
) -> T
@@ -1194,14 +1190,11 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi
11941190
/// requirements.
11951191
fn apply_requirements(
11961192
&self,
1197-
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
1198-
body_id: ast::NodeId,
1193+
tcx: TyCtxt<'_, 'gcx, 'tcx>,
11991194
location: Location,
12001195
closure_def_id: DefId,
12011196
closure_substs: ty::ClosureSubsts<'tcx>,
1202-
) {
1203-
let tcx = infcx.tcx;
1204-
1197+
) -> Vec<QueryRegionConstraint<'tcx>> {
12051198
debug!(
12061199
"apply_requirements(location={:?}, closure_def_id={:?}, closure_substs={:?})",
12071200
location, closure_def_id, closure_substs
@@ -1215,59 +1208,52 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi
12151208
// into a vector. These are the regions that we will be
12161209
// relating to one another.
12171210
let closure_mapping =
1218-
&UniversalRegions::closure_mapping(infcx, user_closure_ty, self.num_external_vids);
1211+
&UniversalRegions::closure_mapping(tcx, user_closure_ty, self.num_external_vids);
12191212
debug!("apply_requirements: closure_mapping={:?}", closure_mapping);
12201213

12211214
// Create the predicates.
1222-
for outlives_requirement in &self.outlives_requirements {
1223-
let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
1224-
1225-
// FIXME, this origin is not entirely suitable.
1226-
let origin = SubregionOrigin::CallRcvr(outlives_requirement.blame_span);
1227-
1228-
match outlives_requirement.subject {
1229-
ClosureOutlivesSubject::Region(region) => {
1230-
let region = closure_mapping[region];
1231-
debug!(
1232-
"apply_requirements: region={:?} \
1233-
outlived_region={:?} \
1234-
outlives_requirement={:?}",
1235-
region, outlived_region, outlives_requirement,
1236-
);
1237-
infcx.sub_regions(origin, outlived_region, region);
1238-
}
1215+
self.outlives_requirements
1216+
.iter()
1217+
.map(|outlives_requirement| {
1218+
let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
1219+
1220+
match outlives_requirement.subject {
1221+
ClosureOutlivesSubject::Region(region) => {
1222+
let region = closure_mapping[region];
1223+
debug!(
1224+
"apply_requirements: region={:?} \
1225+
outlived_region={:?} \
1226+
outlives_requirement={:?}",
1227+
region, outlived_region, outlives_requirement,
1228+
);
1229+
ty::Binder::dummy(ty::OutlivesPredicate(region.into(), outlived_region))
1230+
}
12391231

1240-
ClosureOutlivesSubject::Ty(ty) => {
1241-
let ty = self.subst_closure_mapping(infcx, closure_mapping, &ty);
1242-
debug!(
1243-
"apply_requirements: ty={:?} \
1244-
outlived_region={:?} \
1245-
outlives_requirement={:?}",
1246-
ty, outlived_region, outlives_requirement,
1247-
);
1248-
infcx.register_region_obligation(
1249-
body_id,
1250-
RegionObligation {
1251-
sup_type: ty,
1252-
sub_region: outlived_region,
1253-
cause: ObligationCause::misc(outlives_requirement.blame_span, body_id),
1254-
},
1255-
);
1232+
ClosureOutlivesSubject::Ty(ty) => {
1233+
let ty = self.subst_closure_mapping(tcx, closure_mapping, &ty);
1234+
debug!(
1235+
"apply_requirements: ty={:?} \
1236+
outlived_region={:?} \
1237+
outlives_requirement={:?}",
1238+
ty, outlived_region, outlives_requirement,
1239+
);
1240+
ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region))
1241+
}
12561242
}
1257-
}
1258-
}
1243+
})
1244+
.collect()
12591245
}
12601246

12611247
fn subst_closure_mapping<T>(
12621248
&self,
1263-
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
1249+
tcx: TyCtxt<'_, 'gcx, 'tcx>,
12641250
closure_mapping: &IndexVec<RegionVid, ty::Region<'tcx>>,
12651251
value: &T,
12661252
) -> T
12671253
where
12681254
T: TypeFoldable<'tcx>,
12691255
{
1270-
infcx.tcx.fold_regions(value, &mut false, |r, _depth| {
1256+
tcx.fold_regions(value, &mut false, |r, _depth| {
12711257
if let ty::ReClosureBound(vid) = r {
12721258
closure_mapping[*vid]
12731259
} else {

src/librustc_mir/borrow_check/nll/type_check/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ use rustc::mir::visit::{PlaceContext, Visitor};
2929
use rustc::mir::*;
3030
use rustc::traits::query::type_op;
3131
use rustc::traits::query::{Fallible, NoSolution};
32-
use rustc::traits::ObligationCause;
3332
use rustc::ty::fold::TypeFoldable;
3433
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeVariants};
3534
use std::fmt;
@@ -1507,14 +1506,17 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
15071506
if let Some(closure_region_requirements) =
15081507
tcx.mir_borrowck(*def_id).closure_requirements
15091508
{
1510-
let dummy_body_id = ObligationCause::dummy().body_id;
1511-
closure_region_requirements.apply_requirements(
1512-
self.infcx,
1513-
dummy_body_id,
1509+
let closure_constraints = closure_region_requirements.apply_requirements(
1510+
self.infcx.tcx,
15141511
location,
15151512
*def_id,
15161513
*substs,
15171514
);
1515+
1516+
self.push_region_constraints(
1517+
location.at_self(),
1518+
&closure_constraints,
1519+
);
15181520
}
15191521

15201522
tcx.predicates_of(*def_id).instantiate(tcx, substs.substs)

src/librustc_mir/borrow_check/nll/universal_regions.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,13 +238,13 @@ impl<'tcx> UniversalRegions<'tcx> {
238238
/// `'1: '2`, then the caller would impose the constraint that
239239
/// `V[1]: V[2]`.
240240
pub fn closure_mapping(
241-
infcx: &InferCtxt<'_, '_, 'tcx>,
241+
tcx: TyCtxt<'_, '_, 'tcx>,
242242
closure_ty: Ty<'tcx>,
243243
expected_num_vars: usize,
244244
) -> IndexVec<RegionVid, ty::Region<'tcx>> {
245245
let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
246-
region_mapping.push(infcx.tcx.types.re_static);
247-
infcx.tcx.for_each_free_region(&closure_ty, |fr| {
246+
region_mapping.push(tcx.types.re_static);
247+
tcx.for_each_free_region(&closure_ty, |fr| {
248248
region_mapping.push(fr);
249249
});
250250

0 commit comments

Comments
 (0)