diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-06-19 04:42:21 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-06-26 10:59:40 -0400 |
| commit | 7c72e778ab3cfa0dc7dc2226952c6b9f1e1c76b6 (patch) | |
| tree | 46cb5b3c9bbb60ce5804fb2ccb65e15664bbdf8f | |
| parent | 3e32d42532c9499066c1f45f8a301c2a81e45ec8 (diff) | |
| download | rust-7c72e778ab3cfa0dc7dc2226952c6b9f1e1c76b6.tar.gz rust-7c72e778ab3cfa0dc7dc2226952c6b9f1e1c76b6.zip | |
instantiate closure requirements as query-region-constraints [WIP]
Marked as WIP because it invalidates some tests.
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/region_infer/mod.rs | 90 | ||||
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/type_check/mod.rs | 12 | ||||
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/universal_regions.rs | 6 |
3 files changed, 48 insertions, 60 deletions
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 0eeacda467e..2e1f7fc9e70 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -11,25 +11,22 @@ use super::universal_regions::UniversalRegions; use borrow_check::nll::region_infer::values::ToElementIndex; use rustc::hir::def_id::DefId; +use rustc::infer::canonical::QueryRegionConstraint; use rustc::infer::error_reporting::nice_region_error::NiceRegionError; use rustc::infer::region_constraints::{GenericKind, VarInfos}; use rustc::infer::InferCtxt; use rustc::infer::NLLRegionVariableOrigin; -use rustc::infer::RegionObligation; use rustc::infer::RegionVariableOrigin; -use rustc::infer::SubregionOrigin; use rustc::mir::{ ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements, Local, Location, Mir, }; -use rustc::traits::ObligationCause; -use rustc::ty::{self, RegionVid, Ty, TypeFoldable}; +use rustc::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable}; use rustc::util::common::{self, ErrorReported}; use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use std::fmt; use std::rc::Rc; -use syntax::ast; use syntax_pos::Span; mod annotation; @@ -1162,16 +1159,15 @@ impl fmt::Debug for OutlivesConstraint { pub trait ClosureRegionRequirementsExt<'gcx, 'tcx> { fn apply_requirements( &self, - infcx: &InferCtxt<'_, 'gcx, 'tcx>, - body_id: ast::NodeId, + tcx: TyCtxt<'_, 'gcx, 'tcx>, location: Location, closure_def_id: DefId, closure_substs: ty::ClosureSubsts<'tcx>, - ); + ) -> Vec<QueryRegionConstraint<'tcx>>; fn subst_closure_mapping<T>( &self, - infcx: &InferCtxt<'_, 'gcx, 'tcx>, + tcx: TyCtxt<'_, 'gcx, 'tcx>, closure_mapping: &IndexVec<RegionVid, ty::Region<'tcx>>, value: &T, ) -> T @@ -1194,14 +1190,11 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi /// requirements. fn apply_requirements( &self, - infcx: &InferCtxt<'_, 'gcx, 'tcx>, - body_id: ast::NodeId, + tcx: TyCtxt<'_, 'gcx, 'tcx>, location: Location, closure_def_id: DefId, closure_substs: ty::ClosureSubsts<'tcx>, - ) { - let tcx = infcx.tcx; - + ) -> Vec<QueryRegionConstraint<'tcx>> { debug!( "apply_requirements(location={:?}, closure_def_id={:?}, closure_substs={:?})", location, closure_def_id, closure_substs @@ -1215,59 +1208,52 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi // into a vector. These are the regions that we will be // relating to one another. let closure_mapping = - &UniversalRegions::closure_mapping(infcx, user_closure_ty, self.num_external_vids); + &UniversalRegions::closure_mapping(tcx, user_closure_ty, self.num_external_vids); debug!("apply_requirements: closure_mapping={:?}", closure_mapping); // Create the predicates. - for outlives_requirement in &self.outlives_requirements { - let outlived_region = closure_mapping[outlives_requirement.outlived_free_region]; - - // FIXME, this origin is not entirely suitable. - let origin = SubregionOrigin::CallRcvr(outlives_requirement.blame_span); - - match outlives_requirement.subject { - ClosureOutlivesSubject::Region(region) => { - let region = closure_mapping[region]; - debug!( - "apply_requirements: region={:?} \ - outlived_region={:?} \ - outlives_requirement={:?}", - region, outlived_region, outlives_requirement, - ); - infcx.sub_regions(origin, outlived_region, region); - } + self.outlives_requirements + .iter() + .map(|outlives_requirement| { + let outlived_region = closure_mapping[outlives_requirement.outlived_free_region]; + + match outlives_requirement.subject { + ClosureOutlivesSubject::Region(region) => { + let region = closure_mapping[region]; + debug!( + "apply_requirements: region={:?} \ + outlived_region={:?} \ + outlives_requirement={:?}", + region, outlived_region, outlives_requirement, + ); + ty::Binder::dummy(ty::OutlivesPredicate(region.into(), outlived_region)) + } - ClosureOutlivesSubject::Ty(ty) => { - let ty = self.subst_closure_mapping(infcx, closure_mapping, &ty); - debug!( - "apply_requirements: ty={:?} \ - outlived_region={:?} \ - outlives_requirement={:?}", - ty, outlived_region, outlives_requirement, - ); - infcx.register_region_obligation( - body_id, - RegionObligation { - sup_type: ty, - sub_region: outlived_region, - cause: ObligationCause::misc(outlives_requirement.blame_span, body_id), - }, - ); + ClosureOutlivesSubject::Ty(ty) => { + let ty = self.subst_closure_mapping(tcx, closure_mapping, &ty); + debug!( + "apply_requirements: ty={:?} \ + outlived_region={:?} \ + outlives_requirement={:?}", + ty, outlived_region, outlives_requirement, + ); + ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region)) + } } - } - } + }) + .collect() } fn subst_closure_mapping<T>( &self, - infcx: &InferCtxt<'_, 'gcx, 'tcx>, + tcx: TyCtxt<'_, 'gcx, 'tcx>, closure_mapping: &IndexVec<RegionVid, ty::Region<'tcx>>, value: &T, ) -> T where T: TypeFoldable<'tcx>, { - infcx.tcx.fold_regions(value, &mut false, |r, _depth| { + tcx.fold_regions(value, &mut false, |r, _depth| { if let ty::ReClosureBound(vid) = r { closure_mapping[*vid] } else { diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 7a8337b2498..843fadf6227 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -29,7 +29,6 @@ use rustc::mir::visit::{PlaceContext, Visitor}; use rustc::mir::*; use rustc::traits::query::type_op; use rustc::traits::query::{Fallible, NoSolution}; -use rustc::traits::ObligationCause; use rustc::ty::fold::TypeFoldable; use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeVariants}; use std::fmt; @@ -1507,14 +1506,17 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { if let Some(closure_region_requirements) = tcx.mir_borrowck(*def_id).closure_requirements { - let dummy_body_id = ObligationCause::dummy().body_id; - closure_region_requirements.apply_requirements( - self.infcx, - dummy_body_id, + let closure_constraints = closure_region_requirements.apply_requirements( + self.infcx.tcx, location, *def_id, *substs, ); + + self.push_region_constraints( + location.at_self(), + &closure_constraints, + ); } tcx.predicates_of(*def_id).instantiate(tcx, substs.substs) diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index 2bb96a856ce..ec8cd386679 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -238,13 +238,13 @@ impl<'tcx> UniversalRegions<'tcx> { /// `'1: '2`, then the caller would impose the constraint that /// `V[1]: V[2]`. pub fn closure_mapping( - infcx: &InferCtxt<'_, '_, 'tcx>, + tcx: TyCtxt<'_, '_, 'tcx>, closure_ty: Ty<'tcx>, expected_num_vars: usize, ) -> IndexVec<RegionVid, ty::Region<'tcx>> { let mut region_mapping = IndexVec::with_capacity(expected_num_vars); - region_mapping.push(infcx.tcx.types.re_static); - infcx.tcx.for_each_free_region(&closure_ty, |fr| { + region_mapping.push(tcx.types.re_static); + tcx.for_each_free_region(&closure_ty, |fr| { region_mapping.push(fr); }); |
