@@ -39,13 +39,14 @@ use rustc::ty::fold::TypeFoldable;
3939use  rustc:: ty:: subst:: { Subst ,  SubstsRef ,  UnpackedKind ,  UserSubsts } ; 
4040use  rustc:: ty:: { 
4141    self ,  RegionVid ,  ToPolyTraitRef ,  Ty ,  TyCtxt ,  TyKind ,  UserType , 
42-     CanonicalUserTypeAnnotation ,  UserTypeAnnotationIndex , 
42+     CanonicalUserTypeAnnotation ,  CanonicalUserTypeAnnotations , 
43+     UserTypeAnnotationIndex , 
4344} ; 
4445use  rustc_data_structures:: fx:: { FxHashMap ,  FxHashSet } ; 
4546use  rustc_data_structures:: indexed_vec:: { IndexVec ,  Idx } ; 
4647use  rustc:: ty:: layout:: VariantIdx ; 
4748use  std:: rc:: Rc ; 
48- use  std:: { fmt,  iter} ; 
49+ use  std:: { fmt,  iter,  mem } ; 
4950use  syntax_pos:: { Span ,  DUMMY_SP } ; 
5051
5152macro_rules!  span_mirbug { 
@@ -124,7 +125,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
124125    let  mut  constraints = MirTypeckRegionConstraints  { 
125126        placeholder_indices :  PlaceholderIndices :: default ( ) , 
126127        placeholder_index_to_region :  IndexVec :: default ( ) , 
127-         liveness_constraints :  LivenessValues :: new ( elements) , 
128+         liveness_constraints :  LivenessValues :: new ( elements. clone ( ) ) , 
128129        outlives_constraints :  ConstraintSet :: default ( ) , 
129130        closure_bounds_mapping :  Default :: default ( ) , 
130131        type_tests :  Vec :: default ( ) , 
@@ -253,7 +254,7 @@ enum FieldAccessError {
253254/// is a problem. 
254255struct  TypeVerifier < ' a ,  ' b :  ' a ,  ' gcx :  ' tcx ,  ' tcx :  ' b >  { 
255256    cx :  & ' a  mut  TypeChecker < ' b ,  ' gcx ,  ' tcx > , 
256-     mir :  & ' a  Mir < ' tcx > , 
257+     mir :  & ' b  Mir < ' tcx > , 
257258    last_span :  Span , 
258259    mir_def_id :  DefId , 
259260    errors_reported :  bool , 
@@ -283,7 +284,7 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
283284                location. to_locations ( ) , 
284285                ConstraintCategory :: Boring , 
285286            )  { 
286-                 let  annotation = & self . mir . user_type_annotations [ annotation_index] ; 
287+                 let  annotation = & self . cx . user_type_annotations [ annotation_index] ; 
287288                span_mirbug ! ( 
288289                    self , 
289290                    constant, 
@@ -385,7 +386,7 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
385386} 
386387
387388impl < ' a ,  ' b ,  ' gcx ,  ' tcx >  TypeVerifier < ' a ,  ' b ,  ' gcx ,  ' tcx >  { 
388-     fn  new ( cx :  & ' a  mut  TypeChecker < ' b ,  ' gcx ,  ' tcx > ,  mir :  & ' a  Mir < ' tcx > )  -> Self  { 
389+     fn  new ( cx :  & ' a  mut  TypeChecker < ' b ,  ' gcx ,  ' tcx > ,  mir :  & ' b  Mir < ' tcx > )  -> Self  { 
389390        TypeVerifier  { 
390391            mir, 
391392            mir_def_id :  cx. mir_def_id , 
@@ -454,19 +455,31 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
454455            Place :: Base ( PlaceBase :: Local ( index) )  => PlaceTy :: Ty  { 
455456                ty :  self . mir . local_decls [ index] . ty , 
456457            } , 
457-             Place :: Base ( PlaceBase :: Promoted ( box ( _index ,  sty) ) )  => { 
458+             Place :: Base ( PlaceBase :: Promoted ( box ( index ,  sty) ) )  => { 
458459                let  sty = self . sanitize_type ( place,  sty) ; 
459-                 // FIXME -- promoted MIR return types reference 
460-                 // various "free regions" (e.g., scopes and things) 
461-                 // that they ought not to do. We have to figure out 
462-                 // how best to handle that -- probably we want treat 
463-                 // promoted MIR much like closures, renumbering all 
464-                 // their free regions and propagating constraints 
465-                 // upwards. We have the same acyclic guarantees, so 
466-                 // that should be possible. But for now, ignore them. 
467-                 // 
468-                 // let promoted_mir = &self.mir.promoted[index]; 
469-                 // promoted_mir.return_ty() 
460+ 
461+                 if  !self . errors_reported  { 
462+                     let  promoted_mir = & self . mir . promoted [ index] ; 
463+                     self . sanitize_promoted ( promoted_mir,  location) ; 
464+ 
465+                     let  promoted_ty = promoted_mir. return_ty ( ) ; 
466+ 
467+                     if  let  Err ( terr)  = self . cx . eq_types ( 
468+                         sty, 
469+                         promoted_ty, 
470+                         location. to_locations ( ) , 
471+                         ConstraintCategory :: Boring , 
472+                     )  { 
473+                         span_mirbug ! ( 
474+                             self , 
475+                             place, 
476+                             "bad promoted type ({:?}: {:?}): {:?}" , 
477+                             promoted_ty, 
478+                             sty, 
479+                             terr
480+                         ) ; 
481+                     } ; 
482+                 } 
470483                PlaceTy :: Ty  {  ty :  sty } 
471484            } 
472485            Place :: Base ( PlaceBase :: Static ( box Static  {  def_id,  ty :  sty } ) )  => { 
@@ -533,6 +546,72 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
533546        place_ty
534547    } 
535548
549+     fn  sanitize_promoted ( & mut  self ,  promoted_mir :  & ' b  Mir < ' tcx > ,  location :  Location )  { 
550+         // Determine the constraints from the promoted MIR by running the type 
551+         // checker on the promoted MIR, then transfer the constraints back to 
552+         // the main MIR, changing the locations to the provided location. 
553+ 
554+         let  parent_mir = mem:: replace ( & mut  self . mir ,  promoted_mir) ; 
555+ 
556+         let  all_facts = & mut  None ; 
557+         let  mut  constraints = Default :: default ( ) ; 
558+         let  mut  closure_bounds = Default :: default ( ) ; 
559+         if  let  Some ( ref  mut  bcx)  = self . cx . borrowck_context  { 
560+             // Don't try to add borrow_region facts for the promoted MIR 
561+             mem:: swap ( bcx. all_facts ,  all_facts) ; 
562+ 
563+             // Use a new sets of constraints and closure bounds so that we can 
564+             // modify their locations. 
565+             mem:: swap ( & mut  bcx. constraints . outlives_constraints ,  & mut  constraints) ; 
566+             mem:: swap ( & mut  bcx. constraints . closure_bounds_mapping ,  & mut  closure_bounds) ; 
567+         } ; 
568+ 
569+         self . visit_mir ( promoted_mir) ; 
570+ 
571+         if  !self . errors_reported  { 
572+             // if verifier failed, don't do further checks to avoid ICEs 
573+             self . cx . typeck_mir ( promoted_mir) ; 
574+         } 
575+ 
576+         self . mir  = parent_mir; 
577+         // Merge the outlives constraints back in, at the given location. 
578+         if  let  Some ( ref  mut  base_bcx)  = self . cx . borrowck_context  { 
579+             mem:: swap ( base_bcx. all_facts ,  all_facts) ; 
580+             mem:: swap ( & mut  base_bcx. constraints . outlives_constraints ,  & mut  constraints) ; 
581+             mem:: swap ( & mut  base_bcx. constraints . closure_bounds_mapping ,  & mut  closure_bounds) ; 
582+ 
583+             let  locations = location. to_locations ( ) ; 
584+             for  constraint in  constraints. iter ( )  { 
585+                 let  mut  constraint = * constraint; 
586+                 constraint. locations  = locations; 
587+                 if  let  ConstraintCategory :: Return 
588+                     | ConstraintCategory :: UseAsConst 
589+                     | ConstraintCategory :: UseAsStatic  = constraint. category 
590+                 { 
591+                     // "Returning" from a promoted is an assigment to a 
592+                     // temporary from the user's point of view. 
593+                     constraint. category  = ConstraintCategory :: Boring ; 
594+                 } 
595+                 base_bcx. constraints . outlives_constraints . push ( constraint) 
596+             } 
597+ 
598+             if  !closure_bounds. is_empty ( )  { 
599+                 let  combined_bounds_mapping = closure_bounds
600+                     . into_iter ( ) 
601+                     . flat_map ( |( _,  value) | value) 
602+                     . collect ( ) ; 
603+                 let  existing = base_bcx
604+                     . constraints 
605+                     . closure_bounds_mapping 
606+                     . insert ( location,  combined_bounds_mapping) ; 
607+                 assert ! ( 
608+                     existing. is_none( ) , 
609+                     "Multiple promoteds/closures at the same location." 
610+                 ) ; 
611+             } 
612+         } 
613+     } 
614+ 
536615    fn  sanitize_projection ( 
537616        & mut  self , 
538617        base :  PlaceTy < ' tcx > , 
@@ -738,7 +817,9 @@ struct TypeChecker<'a, 'gcx: 'tcx, 'tcx: 'a> {
738817    infcx :  & ' a  InferCtxt < ' a ,  ' gcx ,  ' tcx > , 
739818    param_env :  ty:: ParamEnv < ' gcx > , 
740819    last_span :  Span , 
741-     mir :  & ' a  Mir < ' tcx > , 
820+     /// User type annotations are shared between the main MIR and the MIR of 
821+      /// all of the promoted items. 
822+      user_type_annotations :  & ' a  CanonicalUserTypeAnnotations < ' tcx > , 
742823    mir_def_id :  DefId , 
743824    region_bound_pairs :  & ' a  RegionBoundPairs < ' tcx > , 
744825    implicit_region_bound :  Option < ty:: Region < ' tcx > > , 
@@ -893,8 +974,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
893974        let  mut  checker = Self  { 
894975            infcx, 
895976            last_span :  DUMMY_SP , 
896-             mir, 
897977            mir_def_id, 
978+             user_type_annotations :  & mir. user_type_annotations , 
898979            param_env, 
899980            region_bound_pairs, 
900981            implicit_region_bound, 
@@ -910,9 +991,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
910991     fn  check_user_type_annotations ( & mut  self )  { 
911992        debug ! ( 
912993            "check_user_type_annotations: user_type_annotations={:?}" , 
913-              self . mir . user_type_annotations
994+              self . user_type_annotations
914995        ) ; 
915-         for  user_annotation in  & self . mir . user_type_annotations  { 
996+         for  user_annotation in  self . user_type_annotations  { 
916997            let  CanonicalUserTypeAnnotation  {  span,  ref  user_ty,  inferred_ty }  = * user_annotation; 
917998            let  ( annotation,  _)  = self . infcx . instantiate_canonical_with_fresh_inference_vars ( 
918999                span,  user_ty
@@ -1095,7 +1176,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
10951176            a,  v,  user_ty,  locations, 
10961177        ) ; 
10971178
1098-         let  annotated_type = self . mir . user_type_annotations [ user_ty. base ] . inferred_ty ; 
1179+         let  annotated_type = self . user_type_annotations [ user_ty. base ] . inferred_ty ; 
10991180        let  mut  curr_projected_ty = PlaceTy :: from_ty ( annotated_type) ; 
11001181
11011182        let  tcx = self . infcx . tcx ; 
@@ -1281,7 +1362,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
12811362                        location. to_locations ( ) , 
12821363                        ConstraintCategory :: Boring , 
12831364                    )  { 
1284-                         let  annotation = & mir . user_type_annotations [ annotation_index] ; 
1365+                         let  annotation = & self . user_type_annotations [ annotation_index] ; 
12851366                        span_mirbug ! ( 
12861367                            self , 
12871368                            stmt, 
@@ -1340,7 +1421,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
13401421                    Locations :: All ( stmt. source_info . span ) , 
13411422                    ConstraintCategory :: TypeAnnotation , 
13421423                )  { 
1343-                     let  annotation = & mir . user_type_annotations [ projection. base ] ; 
1424+                     let  annotation = & self . user_type_annotations [ projection. base ] ; 
13441425                    span_mirbug ! ( 
13451426                        self , 
13461427                        stmt, 
@@ -1998,7 +2079,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
19982079            } 
19992080
20002081            Rvalue :: Ref ( region,  _borrow_kind,  borrowed_place)  => { 
2001-                 self . add_reborrow_constraint ( location,  region,  borrowed_place) ; 
2082+                 self . add_reborrow_constraint ( mir ,   location,  region,  borrowed_place) ; 
20022083            } 
20032084
20042085            // FIXME: These other cases have to be implemented in future PRs 
@@ -2097,6 +2178,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
20972178     /// - `borrowed_place`: the place `P` being borrowed 
20982179     fn  add_reborrow_constraint ( 
20992180        & mut  self , 
2181+         mir :  & Mir < ' tcx > , 
21002182        location :  Location , 
21012183        borrow_region :  ty:: Region < ' tcx > , 
21022184        borrowed_place :  & Place < ' tcx > , 
@@ -2146,7 +2228,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
21462228            match  * elem { 
21472229                ProjectionElem :: Deref  => { 
21482230                    let  tcx = self . infcx . tcx ; 
2149-                     let  base_ty = base. ty ( self . mir ,  tcx) . to_ty ( tcx) ; 
2231+                     let  base_ty = base. ty ( mir,  tcx) . to_ty ( tcx) ; 
21502232
21512233                    debug ! ( "add_reborrow_constraint - base_ty = {:?}" ,  base_ty) ; 
21522234                    match  base_ty. sty  { 
@@ -2275,7 +2357,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
22752357    )  -> ty:: InstantiatedPredicates < ' tcx >  { 
22762358        if  let  Some ( closure_region_requirements)  = tcx. mir_borrowck ( def_id) . closure_requirements  { 
22772359            let  closure_constraints =
2278-                 closure_region_requirements. apply_requirements ( tcx,  location ,   def_id,  substs) ; 
2360+                 closure_region_requirements. apply_requirements ( tcx,  def_id,  substs) ; 
22792361
22802362            if  let  Some ( ref  mut  borrowck_context)  = self . borrowck_context  { 
22812363                let  bounds_mapping = closure_constraints
0 commit comments