@@ -39,13 +39,14 @@ use rustc::ty::fold::TypeFoldable;
39
39
use rustc:: ty:: subst:: { Subst , SubstsRef , UnpackedKind , UserSubsts } ;
40
40
use rustc:: ty:: {
41
41
self , RegionVid , ToPolyTraitRef , Ty , TyCtxt , TyKind , UserType ,
42
- CanonicalUserTypeAnnotation , UserTypeAnnotationIndex ,
42
+ CanonicalUserTypeAnnotation , CanonicalUserTypeAnnotations ,
43
+ UserTypeAnnotationIndex ,
43
44
} ;
44
45
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
45
46
use rustc_data_structures:: indexed_vec:: { IndexVec , Idx } ;
46
47
use rustc:: ty:: layout:: VariantIdx ;
47
48
use std:: rc:: Rc ;
48
- use std:: { fmt, iter} ;
49
+ use std:: { fmt, iter, mem } ;
49
50
use syntax_pos:: { Span , DUMMY_SP } ;
50
51
51
52
macro_rules! span_mirbug {
@@ -124,7 +125,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
124
125
let mut constraints = MirTypeckRegionConstraints {
125
126
placeholder_indices : PlaceholderIndices :: default ( ) ,
126
127
placeholder_index_to_region : IndexVec :: default ( ) ,
127
- liveness_constraints : LivenessValues :: new ( elements) ,
128
+ liveness_constraints : LivenessValues :: new ( elements. clone ( ) ) ,
128
129
outlives_constraints : ConstraintSet :: default ( ) ,
129
130
closure_bounds_mapping : Default :: default ( ) ,
130
131
type_tests : Vec :: default ( ) ,
@@ -253,7 +254,7 @@ enum FieldAccessError {
253
254
/// is a problem.
254
255
struct TypeVerifier < ' a , ' b : ' a , ' gcx : ' tcx , ' tcx : ' b > {
255
256
cx : & ' a mut TypeChecker < ' b , ' gcx , ' tcx > ,
256
- mir : & ' a Mir < ' tcx > ,
257
+ mir : & ' b Mir < ' tcx > ,
257
258
last_span : Span ,
258
259
mir_def_id : DefId ,
259
260
errors_reported : bool ,
@@ -283,7 +284,7 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
283
284
location. to_locations ( ) ,
284
285
ConstraintCategory :: Boring ,
285
286
) {
286
- let annotation = & self . mir . user_type_annotations [ annotation_index] ;
287
+ let annotation = & self . cx . user_type_annotations [ annotation_index] ;
287
288
span_mirbug ! (
288
289
self ,
289
290
constant,
@@ -385,7 +386,7 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
385
386
}
386
387
387
388
impl < ' 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 {
389
390
TypeVerifier {
390
391
mir,
391
392
mir_def_id : cx. mir_def_id ,
@@ -454,19 +455,31 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
454
455
Place :: Base ( PlaceBase :: Local ( index) ) => PlaceTy :: Ty {
455
456
ty : self . mir . local_decls [ index] . ty ,
456
457
} ,
457
- Place :: Base ( PlaceBase :: Promoted ( box ( _index , sty) ) ) => {
458
+ Place :: Base ( PlaceBase :: Promoted ( box ( index , sty) ) ) => {
458
459
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
+ }
470
483
PlaceTy :: Ty { ty : sty }
471
484
}
472
485
Place :: Base ( PlaceBase :: Static ( box Static { def_id, ty : sty } ) ) => {
@@ -533,6 +546,72 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
533
546
place_ty
534
547
}
535
548
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
+
536
615
fn sanitize_projection (
537
616
& mut self ,
538
617
base : PlaceTy < ' tcx > ,
@@ -738,7 +817,9 @@ struct TypeChecker<'a, 'gcx: 'tcx, 'tcx: 'a> {
738
817
infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > ,
739
818
param_env : ty:: ParamEnv < ' gcx > ,
740
819
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 > ,
742
823
mir_def_id : DefId ,
743
824
region_bound_pairs : & ' a RegionBoundPairs < ' tcx > ,
744
825
implicit_region_bound : Option < ty:: Region < ' tcx > > ,
@@ -893,8 +974,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
893
974
let mut checker = Self {
894
975
infcx,
895
976
last_span : DUMMY_SP ,
896
- mir,
897
977
mir_def_id,
978
+ user_type_annotations : & mir. user_type_annotations ,
898
979
param_env,
899
980
region_bound_pairs,
900
981
implicit_region_bound,
@@ -910,9 +991,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
910
991
fn check_user_type_annotations ( & mut self ) {
911
992
debug ! (
912
993
"check_user_type_annotations: user_type_annotations={:?}" ,
913
- self . mir . user_type_annotations
994
+ self . user_type_annotations
914
995
) ;
915
- for user_annotation in & self . mir . user_type_annotations {
996
+ for user_annotation in self . user_type_annotations {
916
997
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = * user_annotation;
917
998
let ( annotation, _) = self . infcx . instantiate_canonical_with_fresh_inference_vars (
918
999
span, user_ty
@@ -1095,7 +1176,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
1095
1176
a, v, user_ty, locations,
1096
1177
) ;
1097
1178
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 ;
1099
1180
let mut curr_projected_ty = PlaceTy :: from_ty ( annotated_type) ;
1100
1181
1101
1182
let tcx = self . infcx . tcx ;
@@ -1281,7 +1362,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
1281
1362
location. to_locations ( ) ,
1282
1363
ConstraintCategory :: Boring ,
1283
1364
) {
1284
- let annotation = & mir . user_type_annotations [ annotation_index] ;
1365
+ let annotation = & self . user_type_annotations [ annotation_index] ;
1285
1366
span_mirbug ! (
1286
1367
self ,
1287
1368
stmt,
@@ -1340,7 +1421,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
1340
1421
Locations :: All ( stmt. source_info . span ) ,
1341
1422
ConstraintCategory :: TypeAnnotation ,
1342
1423
) {
1343
- let annotation = & mir . user_type_annotations [ projection. base ] ;
1424
+ let annotation = & self . user_type_annotations [ projection. base ] ;
1344
1425
span_mirbug ! (
1345
1426
self ,
1346
1427
stmt,
@@ -1998,7 +2079,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
1998
2079
}
1999
2080
2000
2081
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) ;
2002
2083
}
2003
2084
2004
2085
// FIXME: These other cases have to be implemented in future PRs
@@ -2097,6 +2178,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
2097
2178
/// - `borrowed_place`: the place `P` being borrowed
2098
2179
fn add_reborrow_constraint (
2099
2180
& mut self ,
2181
+ mir : & Mir < ' tcx > ,
2100
2182
location : Location ,
2101
2183
borrow_region : ty:: Region < ' tcx > ,
2102
2184
borrowed_place : & Place < ' tcx > ,
@@ -2146,7 +2228,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
2146
2228
match * elem {
2147
2229
ProjectionElem :: Deref => {
2148
2230
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) ;
2150
2232
2151
2233
debug ! ( "add_reborrow_constraint - base_ty = {:?}" , base_ty) ;
2152
2234
match base_ty. sty {
@@ -2275,7 +2357,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
2275
2357
) -> ty:: InstantiatedPredicates < ' tcx > {
2276
2358
if let Some ( closure_region_requirements) = tcx. mir_borrowck ( def_id) . closure_requirements {
2277
2359
let closure_constraints =
2278
- closure_region_requirements. apply_requirements ( tcx, location , def_id, substs) ;
2360
+ closure_region_requirements. apply_requirements ( tcx, def_id, substs) ;
2279
2361
2280
2362
if let Some ( ref mut borrowck_context) = self . borrowck_context {
2281
2363
let bounds_mapping = closure_constraints
0 commit comments