@@ -42,15 +42,15 @@ use rustc::traits::query::type_op::custom::CustomTypeOp;
4242use rustc:: traits:: query:: { Fallible , NoSolution } ;
4343use rustc:: traits:: { ObligationCause , PredicateObligations } ;
4444use rustc:: ty:: fold:: TypeFoldable ;
45- use rustc:: ty:: subst:: Subst ;
45+ use rustc:: ty:: subst:: { Subst , UnpackedKind } ;
4646use rustc:: ty:: { self , CanonicalTy , RegionVid , ToPolyTraitRef , Ty , TyCtxt , TyKind } ;
4747use std:: rc:: Rc ;
4848use std:: { fmt, iter} ;
4949use syntax_pos:: { Span , DUMMY_SP } ;
5050use transform:: { MirPass , MirSource } ;
5151
5252use either:: Either ;
53- use rustc_data_structures:: fx:: FxHashSet ;
53+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
5454
5555macro_rules! span_mirbug {
5656 ( $context: expr, $elem: expr, $( $message: tt) * ) => ( {
@@ -128,6 +128,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
128128 let mut constraints = MirTypeckRegionConstraints {
129129 liveness_constraints : LivenessValues :: new ( elements) ,
130130 outlives_constraints : ConstraintSet :: default ( ) ,
131+ closure_bounds_mapping : FxHashMap ( ) ,
131132 type_tests : Vec :: default ( ) ,
132133 } ;
133134 let mut placeholder_indices = PlaceholderIndices :: default ( ) ;
@@ -752,6 +753,11 @@ crate struct MirTypeckRegionConstraints<'tcx> {
752753
753754 crate outlives_constraints : ConstraintSet ,
754755
756+ crate closure_bounds_mapping : FxHashMap <
757+ Location ,
758+ FxHashMap < ( RegionVid , RegionVid ) , ( ConstraintCategory , Span ) > ,
759+ > ,
760+
755761 crate type_tests : Vec < TypeTest < ' tcx > > ,
756762}
757763
@@ -860,7 +866,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
860866 & mut self ,
861867 locations : Locations ,
862868 category : ConstraintCategory ,
863- op : impl type_op:: TypeOp < ' gcx , ' tcx , Output = R > ,
869+ op : impl type_op:: TypeOp < ' gcx , ' tcx , Output = R > ,
864870 ) -> Fallible < R > {
865871 let ( r, opt_data) = op. fully_perform ( self . infcx ) ?;
866872
@@ -1103,17 +1109,17 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
11031109 let place_ty = place. ty ( mir, tcx) . to_ty ( tcx) ;
11041110 let rv_ty = rv. ty ( mir, tcx) ;
11051111 if let Err ( terr) =
1106- self . sub_types_or_anon ( rv_ty, place_ty, location. to_locations ( ) , category)
1107- {
1108- span_mirbug ! (
1112+ self . sub_types_or_anon ( rv_ty, place_ty, location. to_locations ( ) , category)
1113+ {
1114+ span_mirbug ! (
11091115 self ,
11101116 stmt,
11111117 "bad assignment ({:?} = {:?}): {:?}" ,
11121118 place_ty,
11131119 rv_ty,
11141120 terr
11151121 ) ;
1116- }
1122+ }
11171123
11181124 if let Some ( user_ty) = self . rvalue_user_ty ( rv) {
11191125 if let Err ( terr) = self . relate_type_and_user_type (
@@ -1233,17 +1239,17 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
12331239
12341240 let locations = term_location. to_locations ( ) ;
12351241 if let Err ( terr) =
1236- self . sub_types ( rv_ty, place_ty, locations, ConstraintCategory :: Assignment )
1237- {
1238- span_mirbug ! (
1242+ self . sub_types ( rv_ty, place_ty, locations, ConstraintCategory :: Assignment )
1243+ {
1244+ span_mirbug ! (
12391245 self ,
12401246 term,
12411247 "bad DropAndReplace ({:?} = {:?}): {:?}" ,
12421248 place_ty,
12431249 rv_ty,
12441250 terr
12451251 ) ;
1246- }
1252+ }
12471253 }
12481254 TerminatorKind :: SwitchInt {
12491255 ref discr,
@@ -1387,17 +1393,17 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
13871393 let locations = term_location. to_locations ( ) ;
13881394
13891395 if let Err ( terr) =
1390- self . sub_types_or_anon ( sig. output ( ) , dest_ty, locations, category)
1391- {
1392- span_mirbug ! (
1396+ self . sub_types_or_anon ( sig. output ( ) , dest_ty, locations, category)
1397+ {
1398+ span_mirbug ! (
13931399 self ,
13941400 term,
13951401 "call dest mismatch ({:?} <- {:?}): {:?}" ,
13961402 dest_ty,
13971403 sig. output( ) ,
13981404 terr
13991405 ) ;
1400- }
1406+ }
14011407
14021408 // When `#![feature(unsized_locals)]` is not enabled,
14031409 // this check is done at `check_local`.
@@ -2038,7 +2044,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
20382044 aggregate_kind, location
20392045 ) ;
20402046
2041- let instantiated_predicates = match aggregate_kind {
2047+ let instantiated_predicates = match aggregate_kind {
20422048 AggregateKind :: Adt ( def, _, substs, _, _) => {
20432049 tcx. predicates_of ( def. did ) . instantiate ( tcx, substs)
20442050 }
@@ -2064,24 +2070,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
20642070 // these extra requirements are basically like where
20652071 // clauses on the struct.
20662072 AggregateKind :: Closure ( def_id, substs) => {
2067- if let Some ( closure_region_requirements) =
2068- tcx. mir_borrowck ( * def_id) . closure_requirements
2069- {
2070- let closure_constraints = closure_region_requirements. apply_requirements (
2071- self . infcx . tcx ,
2072- location,
2073- * def_id,
2074- * substs,
2075- ) ;
2076-
2077- self . push_region_constraints (
2078- location. to_locations ( ) ,
2079- ConstraintCategory :: ClosureBounds ,
2080- & closure_constraints,
2081- ) ;
2082- }
2083-
2084- tcx. predicates_of ( * def_id) . instantiate ( tcx, substs. substs )
2073+ self . prove_closure_bounds ( tcx, * def_id, * substs, location)
20852074 }
20862075
20872076 AggregateKind :: Generator ( def_id, substs, _) => {
@@ -2097,6 +2086,72 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
20972086 ) ;
20982087 }
20992088
2089+ fn prove_closure_bounds (
2090+ & mut self ,
2091+ tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
2092+ def_id : DefId ,
2093+ substs : ty:: ClosureSubsts < ' tcx > ,
2094+ location : Location ,
2095+ ) -> ty:: InstantiatedPredicates < ' tcx > {
2096+ if let Some ( closure_region_requirements) =
2097+ tcx. mir_borrowck ( def_id) . closure_requirements
2098+ {
2099+ let closure_constraints = closure_region_requirements. apply_requirements (
2100+ tcx,
2101+ location,
2102+ def_id,
2103+ substs,
2104+ ) ;
2105+
2106+ if let Some ( ref mut borrowck_context) = self . borrowck_context {
2107+ let bounds_mapping = closure_constraints
2108+ . iter ( )
2109+ . enumerate ( )
2110+ . filter_map ( |( idx, constraint) | {
2111+ let ty:: OutlivesPredicate ( k1, r2) =
2112+ constraint. no_late_bound_regions ( ) . unwrap_or_else ( || {
2113+ bug ! (
2114+ "query_constraint {:?} contained bound regions" ,
2115+ constraint,
2116+ ) ;
2117+ } ) ;
2118+
2119+ match k1. unpack ( ) {
2120+ UnpackedKind :: Lifetime ( r1) => {
2121+ // constraint is r1: r2
2122+ let r1_vid = borrowck_context. universal_regions . to_region_vid ( r1) ;
2123+ let r2_vid = borrowck_context. universal_regions . to_region_vid ( r2) ;
2124+ let outlives_requirements = & closure_region_requirements
2125+ . outlives_requirements [ idx] ;
2126+ Some ( (
2127+ ( r1_vid, r2_vid) ,
2128+ (
2129+ outlives_requirements. category ,
2130+ outlives_requirements. blame_span ,
2131+ ) ,
2132+ ) )
2133+ }
2134+ UnpackedKind :: Type ( _) => None ,
2135+ }
2136+ } )
2137+ . collect ( ) ;
2138+
2139+ let existing = borrowck_context. constraints
2140+ . closure_bounds_mapping
2141+ . insert ( location, bounds_mapping) ;
2142+ assert ! ( existing. is_none( ) , "Multiple closures at the same location." ) ;
2143+ }
2144+
2145+ self . push_region_constraints (
2146+ location. to_locations ( ) ,
2147+ ConstraintCategory :: ClosureBounds ,
2148+ & closure_constraints,
2149+ ) ;
2150+ }
2151+
2152+ tcx. predicates_of ( def_id) . instantiate ( tcx, substs. substs )
2153+ }
2154+
21002155 fn prove_trait_ref (
21012156 & mut self ,
21022157 trait_ref : ty:: TraitRef < ' tcx > ,
0 commit comments