]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/borrow_check/nll/type_check/mod.rs
Changes the type `mir::Mir` into `mir::Body`
[rust.git] / src / librustc_mir / borrow_check / nll / type_check / mod.rs
index f1bbb1c8809987abc118cd96b72f88671acef72f..84799eb97ed8aad5192e96dc4fb36ed19393077b 100644 (file)
@@ -20,7 +20,6 @@
 use crate::dataflow::move_paths::MoveData;
 use crate::dataflow::FlowAtLocation;
 use crate::dataflow::MaybeInitializedPlaces;
-use crate::transform::{MirPass, MirSource};
 use either::Either;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
@@ -30,7 +29,7 @@
 use rustc::infer::type_variable::TypeVariableOrigin;
 use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue};
 use rustc::mir::tcx::PlaceTy;
-use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext};
+use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext};
 use rustc::mir::*;
 use rustc::traits::query::type_op;
 use rustc::traits::query::type_op::custom::CustomTypeOp;
@@ -113,7 +112,7 @@ macro_rules! span_mirbug_and_err {
 pub(crate) fn type_check<'gcx, 'tcx>(
     infcx: &InferCtxt<'_, 'gcx, 'tcx>,
     param_env: ty::ParamEnv<'gcx>,
-    mir: &Mir<'tcx>,
+    mir: &Body<'tcx>,
     mir_def_id: DefId,
     universal_regions: &Rc<UniversalRegions<'tcx>>,
     location_table: &LocationTable,
@@ -159,16 +158,14 @@ pub(crate) fn type_check<'gcx, 'tcx>(
         param_env,
         mir,
         &region_bound_pairs,
-        Some(implicit_region_bound),
-        Some(&mut borrowck_context),
-        Some(&universal_region_relations),
-        |cx| {
+        implicit_region_bound,
+        &mut borrowck_context,
+        &universal_region_relations,
+        |mut cx| {
             cx.equate_inputs_and_outputs(mir, universal_regions, &normalized_inputs_and_output);
-            liveness::generate(cx, mir, elements, flow_inits, move_data, location_table);
+            liveness::generate(&mut cx, mir, elements, flow_inits, move_data, location_table);
 
-            cx.borrowck_context
-                .as_mut()
-                .map(|bcx| translate_outlives_facts(bcx));
+            translate_outlives_facts(cx.borrowck_context);
         },
     );
 
@@ -182,11 +179,11 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>(
     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
     mir_def_id: DefId,
     param_env: ty::ParamEnv<'gcx>,
-    mir: &'a Mir<'tcx>,
+    mir: &'a Body<'tcx>,
     region_bound_pairs: &'a RegionBoundPairs<'tcx>,
-    implicit_region_bound: Option<ty::Region<'tcx>>,
-    borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
-    universal_region_relations: Option<&'a UniversalRegionRelations<'tcx>>,
+    implicit_region_bound: ty::Region<'tcx>,
+    borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
+    universal_region_relations: &'a UniversalRegionRelations<'tcx>,
     mut extra: impl FnMut(&mut TypeChecker<'a, 'gcx, 'tcx>) -> R,
 ) -> R where {
     let mut checker = TypeChecker::new(
@@ -201,7 +198,7 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>(
     );
     let errors_reported = {
         let mut verifier = TypeVerifier::new(&mut checker, mir);
-        verifier.visit_mir(mir);
+        verifier.visit_body(mir);
         verifier.errors_reported
     };
 
@@ -256,7 +253,7 @@ enum FieldAccessError {
 /// is a problem.
 struct TypeVerifier<'a, 'b: 'a, 'gcx: 'tcx, 'tcx: 'b> {
     cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>,
-    mir: &'b Mir<'tcx>,
+    mir: &'b Body<'tcx>,
     last_span: Span,
     mir_def_id: DefId,
     errors_reported: bool,
@@ -371,7 +368,7 @@ fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
         }
     }
 
-    fn visit_mir(&mut self, mir: &Mir<'tcx>) {
+    fn visit_body(&mut self, mir: &Body<'tcx>) {
         self.sanitize_type(&"return type", mir.return_ty());
         for local_decl in &mir.local_decls {
             self.sanitize_type(local_decl, local_decl.ty);
@@ -379,12 +376,12 @@ fn visit_mir(&mut self, mir: &Mir<'tcx>) {
         if self.errors_reported {
             return;
         }
-        self.super_mir(mir);
+        self.super_body(mir);
     }
 }
 
 impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
-    fn new(cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>, mir: &'b Mir<'tcx>) -> Self {
+    fn new(cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>, mir: &'b Body<'tcx>) -> Self {
         TypeVerifier {
             mir,
             mir_def_id: cx.mir_def_id,
@@ -450,95 +447,98 @@ fn sanitize_place(
         context: PlaceContext,
     ) -> PlaceTy<'tcx> {
         debug!("sanitize_place: {:?}", place);
-        let place_ty = match place {
-            Place::Base(PlaceBase::Local(index)) =>
-                PlaceTy::from_ty(self.mir.local_decls[*index].ty),
-            Place::Base(PlaceBase::Static(box Static { kind, ty: sty })) => {
-                let sty = self.sanitize_type(place, sty);
-                let check_err =
-                    |verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>,
-                     place: &Place<'tcx>,
-                     ty,
-                     sty| {
-                        if let Err(terr) = verifier.cx.eq_types(
-                            sty,
-                            ty,
-                            location.to_locations(),
-                            ConstraintCategory::Boring,
-                        ) {
-                            span_mirbug!(
-                            verifier,
-                            place,
-                            "bad promoted type ({:?}: {:?}): {:?}",
-                            ty,
-                            sty,
-                            terr
-                        );
+
+        place.iterate(|place_base, place_projection| {
+            let mut place_ty = match place_base {
+                PlaceBase::Local(index) =>
+                    PlaceTy::from_ty(self.mir.local_decls[*index].ty),
+                PlaceBase::Static(box Static { kind, ty: sty }) => {
+                    let sty = self.sanitize_type(place, sty);
+                    let check_err =
+                        |verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>,
+                         place: &Place<'tcx>,
+                         ty,
+                         sty| {
+                            if let Err(terr) = verifier.cx.eq_types(
+                                sty,
+                                ty,
+                                location.to_locations(),
+                                ConstraintCategory::Boring,
+                            ) {
+                                span_mirbug!(
+                                verifier,
+                                place,
+                                "bad promoted type ({:?}: {:?}): {:?}",
+                                ty,
+                                sty,
+                                terr
+                            );
+                            };
                         };
-                    };
-                match kind {
-                    StaticKind::Promoted(promoted) => {
-                        if !self.errors_reported {
-                            let promoted_mir = &self.mir.promoted[*promoted];
-                            self.sanitize_promoted(promoted_mir, location);
-
-                            let promoted_ty = promoted_mir.return_ty();
-                            check_err(self, place, promoted_ty, sty);
+                    match kind {
+                        StaticKind::Promoted(promoted) => {
+                            if !self.errors_reported {
+                                let promoted_mir = &self.mir.promoted[*promoted];
+                                self.sanitize_promoted(promoted_mir, location);
+
+                                let promoted_ty = promoted_mir.return_ty();
+                                check_err(self, place, promoted_ty, sty);
+                            }
                         }
-                    }
-                    StaticKind::Static(def_id) => {
-                        let ty = self.tcx().type_of(*def_id);
-                        let ty = self.cx.normalize(ty, location);
+                        StaticKind::Static(def_id) => {
+                            let ty = self.tcx().type_of(*def_id);
+                            let ty = self.cx.normalize(ty, location);
 
-                        check_err(self, place, ty, sty);
+                            check_err(self, place, ty, sty);
+                        }
                     }
+                    PlaceTy::from_ty(sty)
+                }
+            };
+
+            // FIXME use place_projection.is_empty() when is available
+            if let Place::Base(_) = place {
+                if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
+                    let tcx = self.tcx();
+                    let trait_ref = ty::TraitRef {
+                        def_id: tcx.lang_items().copy_trait().unwrap(),
+                        substs: tcx.mk_substs_trait(place_ty.ty, &[]),
+                    };
+
+                    // In order to have a Copy operand, the type T of the
+                    // value must be Copy. Note that we prove that T: Copy,
+                    // rather than using the `is_copy_modulo_regions`
+                    // test. This is important because
+                    // `is_copy_modulo_regions` ignores the resulting region
+                    // obligations and assumes they pass. This can result in
+                    // bounds from Copy impls being unsoundly ignored (e.g.,
+                    // #29149). Note that we decide to use Copy before knowing
+                    // whether the bounds fully apply: in effect, the rule is
+                    // that if a value of some type could implement Copy, then
+                    // it must.
+                    self.cx.prove_trait_ref(
+                        trait_ref,
+                        location.to_locations(),
+                        ConstraintCategory::CopyBound,
+                    );
                 }
-                PlaceTy::from_ty(sty)
             }
-            Place::Projection(ref proj) => {
-                let base_context = if context.is_mutating_use() {
-                    PlaceContext::MutatingUse(MutatingUseContext::Projection)
-                } else {
-                    PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
-                };
-                let base_ty = self.sanitize_place(&proj.base, location, base_context);
-                if base_ty.variant_index.is_none() {
-                    if base_ty.ty.references_error() {
+
+            for proj in place_projection {
+                if place_ty.variant_index.is_none() {
+                    if place_ty.ty.references_error() {
                         assert!(self.errors_reported);
                         return PlaceTy::from_ty(self.tcx().types.err);
                     }
                 }
-                self.sanitize_projection(base_ty, &proj.elem, place, location)
+                place_ty = self.sanitize_projection(place_ty, &proj.elem, place, location)
             }
-        };
-        if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
-            let tcx = self.tcx();
-            let trait_ref = ty::TraitRef {
-                def_id: tcx.lang_items().copy_trait().unwrap(),
-                substs: tcx.mk_substs_trait(place_ty.ty, &[]),
-            };
 
-            // In order to have a Copy operand, the type T of the
-            // value must be Copy. Note that we prove that T: Copy,
-            // rather than using the `is_copy_modulo_regions`
-            // test. This is important because
-            // `is_copy_modulo_regions` ignores the resulting region
-            // obligations and assumes they pass. This can result in
-            // bounds from Copy impls being unsoundly ignored (e.g.,
-            // #29149). Note that we decide to use Copy before knowing
-            // whether the bounds fully apply: in effect, the rule is
-            // that if a value of some type could implement Copy, then
-            // it must.
-            self.cx.prove_trait_ref(
-                trait_ref,
-                location.to_locations(),
-                ConstraintCategory::CopyBound,
-            );
-        }
-        place_ty
+            place_ty
+        })
     }
 
-    fn sanitize_promoted(&mut self, promoted_mir: &'b Mir<'tcx>, location: Location) {
+    fn sanitize_promoted(&mut self, promoted_mir: &'b Body<'tcx>, location: Location) {
         // Determine the constraints from the promoted MIR by running the type
         // checker on the promoted MIR, then transfer the constraints back to
         // the main MIR, changing the locations to the provided location.
@@ -548,17 +548,21 @@ fn sanitize_promoted(&mut self, promoted_mir: &'b Mir<'tcx>, location: Location)
         let all_facts = &mut None;
         let mut constraints = Default::default();
         let mut closure_bounds = Default::default();
-        if let Some(ref mut bcx) = self.cx.borrowck_context {
-            // Don't try to add borrow_region facts for the promoted MIR
-            mem::swap(bcx.all_facts, all_facts);
-
-            // Use a new sets of constraints and closure bounds so that we can
-            // modify their locations.
-            mem::swap(&mut bcx.constraints.outlives_constraints, &mut constraints);
-            mem::swap(&mut bcx.constraints.closure_bounds_mapping, &mut closure_bounds);
-        };
+        // Don't try to add borrow_region facts for the promoted MIR
+        mem::swap(self.cx.borrowck_context.all_facts, all_facts);
+
+        // Use a new sets of constraints and closure bounds so that we can
+        // modify their locations.
+        mem::swap(
+            &mut self.cx.borrowck_context.constraints.outlives_constraints,
+            &mut constraints
+        );
+        mem::swap(
+            &mut self.cx.borrowck_context.constraints.closure_bounds_mapping,
+            &mut closure_bounds
+        );
 
-        self.visit_mir(promoted_mir);
+        self.visit_body(promoted_mir);
 
         if !self.errors_reported {
             // if verifier failed, don't do further checks to avoid ICEs
@@ -567,40 +571,44 @@ fn sanitize_promoted(&mut self, promoted_mir: &'b Mir<'tcx>, location: Location)
 
         self.mir = parent_mir;
         // Merge the outlives constraints back in, at the given location.
-        if let Some(ref mut base_bcx) = self.cx.borrowck_context {
-            mem::swap(base_bcx.all_facts, all_facts);
-            mem::swap(&mut base_bcx.constraints.outlives_constraints, &mut constraints);
-            mem::swap(&mut base_bcx.constraints.closure_bounds_mapping, &mut closure_bounds);
-
-            let locations = location.to_locations();
-            for constraint in constraints.iter() {
-                let mut constraint = *constraint;
-                constraint.locations = locations;
-                if let ConstraintCategory::Return
-                    | ConstraintCategory::UseAsConst
-                    | ConstraintCategory::UseAsStatic = constraint.category
-                {
-                    // "Returning" from a promoted is an assigment to a
-                    // temporary from the user's point of view.
-                    constraint.category = ConstraintCategory::Boring;
-                }
-                base_bcx.constraints.outlives_constraints.push(constraint)
-            }
+        mem::swap(self.cx.borrowck_context.all_facts, all_facts);
+        mem::swap(
+            &mut self.cx.borrowck_context.constraints.outlives_constraints,
+            &mut constraints
+        );
+        mem::swap(
+            &mut self.cx.borrowck_context.constraints.closure_bounds_mapping,
+            &mut closure_bounds
+        );
 
-            if !closure_bounds.is_empty() {
-                let combined_bounds_mapping = closure_bounds
-                    .into_iter()
-                    .flat_map(|(_, value)| value)
-                    .collect();
-                let existing = base_bcx
-                    .constraints
-                    .closure_bounds_mapping
-                    .insert(location, combined_bounds_mapping);
-                assert!(
-                    existing.is_none(),
-                    "Multiple promoteds/closures at the same location."
-                );
+        let locations = location.to_locations();
+        for constraint in constraints.iter() {
+            let mut constraint = *constraint;
+            constraint.locations = locations;
+            if let ConstraintCategory::Return
+                | ConstraintCategory::UseAsConst
+                | ConstraintCategory::UseAsStatic = constraint.category
+            {
+                // "Returning" from a promoted is an assigment to a
+                // temporary from the user's point of view.
+                constraint.category = ConstraintCategory::Boring;
             }
+            self.cx.borrowck_context.constraints.outlives_constraints.push(constraint)
+        }
+
+        if !closure_bounds.is_empty() {
+            let combined_bounds_mapping = closure_bounds
+                .into_iter()
+                .flat_map(|(_, value)| value)
+                .collect();
+            let existing = self.cx.borrowck_context
+                .constraints
+                .closure_bounds_mapping
+                .insert(location, combined_bounds_mapping);
+            assert!(
+                existing.is_none(),
+                "Multiple promoteds/closures at the same location."
+            );
         }
     }
 
@@ -684,6 +692,8 @@ fn sanitize_projection(
                         }
                     }
                 }
+                // We do not need to handle generators here, because this runs
+                // before the generator transform stage.
                 _ => {
                     let ty = if let Some(name) = maybe_name {
                         span_mirbug_and_err!(
@@ -745,11 +755,26 @@ fn field_ty(
         let tcx = self.tcx();
 
         let (variant, substs) = match base_ty {
-            PlaceTy { ty, variant_index: Some(variant_index) } => {
-                match ty.sty {
-                    ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
-                    _ => bug!("can't have downcast of non-adt type"),
+            PlaceTy { ty, variant_index: Some(variant_index) } => match ty.sty {
+                ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
+                ty::Generator(def_id, substs, _) => {
+                    let mut variants = substs.state_tys(def_id, tcx);
+                    let mut variant = match variants.nth(variant_index.into()) {
+                        Some(v) => v,
+                        None => {
+                            bug!("variant_index of generator out of range: {:?}/{:?}",
+                                 variant_index,
+                                 substs.state_tys(def_id, tcx).count())
+                        }
+                    };
+                    return match variant.nth(field.index()) {
+                        Some(ty) => Ok(ty),
+                        None => Err(FieldAccessError::OutOfRange {
+                            field_count: variant.count(),
+                        }),
+                    }
                 }
+                _ => bug!("can't have downcast of non-adt non-generator type"),
             }
             PlaceTy { ty, variant_index: None } => match ty.sty {
                 ty::Adt(adt_def, substs) if !adt_def.is_enum() =>
@@ -763,19 +788,14 @@ fn field_ty(
                     }
                 }
                 ty::Generator(def_id, substs, _) => {
-                    // Try pre-transform fields first (upvars and current state)
-                    if let Some(ty) = substs.pre_transforms_tys(def_id, tcx).nth(field.index()) {
-                        return Ok(ty);
-                    }
-
-                    // Then try `field_tys` which contains all the fields, but it
-                    // requires the final optimized MIR.
-                    return match substs.field_tys(def_id, tcx).nth(field.index()) {
+                    // Only prefix fields (upvars and current state) are
+                    // accessible without a variant index.
+                    return match substs.prefix_tys(def_id, tcx).nth(field.index()) {
                         Some(ty) => Ok(ty),
                         None => Err(FieldAccessError::OutOfRange {
-                            field_count: substs.field_tys(def_id, tcx).count(),
+                            field_count: substs.prefix_tys(def_id, tcx).count(),
                         }),
-                    };
+                    }
                 }
                 ty::Tuple(tys) => {
                     return match tys.get(field.index()) {
@@ -819,10 +839,10 @@ struct TypeChecker<'a, 'gcx: 'tcx, 'tcx: 'a> {
     user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
     mir_def_id: DefId,
     region_bound_pairs: &'a RegionBoundPairs<'tcx>,
-    implicit_region_bound: Option<ty::Region<'tcx>>,
+    implicit_region_bound: ty::Region<'tcx>,
     reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
-    borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
-    universal_region_relations: Option<&'a UniversalRegionRelations<'tcx>>,
+    borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
+    universal_region_relations: &'a UniversalRegionRelations<'tcx>,
 }
 
 struct BorrowCheckContext<'a, 'tcx: 'a> {
@@ -949,7 +969,7 @@ pub fn from_location(&self) -> Option<Location> {
     }
 
     /// Gets a span representing the location.
-    pub fn span(&self, mir: &Mir<'_>) -> Span {
+    pub fn span(&self, mir: &Body<'_>) -> Span {
         match self {
             Locations::All(span) => *span,
             Locations::Single(l) => mir.source_info(*l).span,
@@ -960,13 +980,13 @@ pub fn span(&self, mir: &Mir<'_>) -> Span {
 impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
     fn new(
         infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
-        mir: &'a Mir<'tcx>,
+        mir: &'a Body<'tcx>,
         mir_def_id: DefId,
         param_env: ty::ParamEnv<'gcx>,
         region_bound_pairs: &'a RegionBoundPairs<'tcx>,
-        implicit_region_bound: Option<ty::Region<'tcx>>,
-        borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
-        universal_region_relations: Option<&'a UniversalRegionRelations<'tcx>>,
+        implicit_region_bound: ty::Region<'tcx>,
+        borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
+        universal_region_relations: &'a UniversalRegionRelations<'tcx>,
     ) -> Self {
         let mut checker = Self {
             infcx,
@@ -1080,18 +1100,16 @@ fn push_region_constraints(
             locations, data
         );
 
-        if let Some(ref mut borrowck_context) = self.borrowck_context {
-            constraint_conversion::ConstraintConversion::new(
-                self.infcx,
-                borrowck_context.universal_regions,
-                self.region_bound_pairs,
-                self.implicit_region_bound,
-                self.param_env,
-                locations,
-                category,
-                &mut borrowck_context.constraints,
-            ).convert_all(&data);
-        }
+        constraint_conversion::ConstraintConversion::new(
+            self.infcx,
+            self.borrowck_context.universal_regions,
+            self.region_bound_pairs,
+            Some(self.implicit_region_bound),
+            self.param_env,
+            locations,
+            category,
+            &mut self.borrowck_context.constraints,
+        ).convert_all(&data);
     }
 
     /// Convenient wrapper around `relate_tys::relate_types` -- see
@@ -1111,7 +1129,7 @@ fn relate_types(
             b,
             locations,
             category,
-            self.borrowck_context.as_mut().map(|x| &mut **x),
+            Some(self.borrowck_context),
         )
     }
 
@@ -1264,10 +1282,7 @@ fn eq_opaque_type_and_type(
             ),
         )?;
 
-        let universal_region_relations = match self.universal_region_relations {
-            Some(rel) => rel,
-            None => return Ok(()),
-        };
+        let universal_region_relations = self.universal_region_relations;
 
         // Finally, if we instantiated the anon types successfully, we
         // have to solve any bounds (e.g., `-> impl Iterator` needs to
@@ -1302,7 +1317,7 @@ fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
         self.infcx.tcx
     }
 
-    fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Location) {
+    fn check_stmt(&mut self, mir: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) {
         debug!("check_stmt: {:?}", stmt);
         let tcx = self.tcx();
         match stmt.kind {
@@ -1312,14 +1327,14 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca
                 // of lowering. Assignments to other sorts of places *are* interesting
                 // though.
                 let category = match *place {
-                    Place::Base(PlaceBase::Local(RETURN_PLACE)) => if let Some(BorrowCheckContext {
+                    Place::Base(PlaceBase::Local(RETURN_PLACE)) => if let BorrowCheckContext {
                         universal_regions:
                             UniversalRegions {
                                 defining_ty: DefiningTy::Const(def_id, _),
                                 ..
                             },
                         ..
-                    }) = self.borrowck_context
+                    } = self.borrowck_context
                     {
                         if tcx.is_static(*def_id) {
                             ConstraintCategory::UseAsStatic
@@ -1441,7 +1456,7 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca
 
     fn check_terminator(
         &mut self,
-        mir: &Mir<'tcx>,
+        mir: &Body<'tcx>,
         term: &Terminator<'tcx>,
         term_location: Location,
     ) {
@@ -1547,15 +1562,13 @@ fn check_terminator(
                 // output) types in the signature must be live, since
                 // all the inputs that fed into it were live.
                 for &late_bound_region in map.values() {
-                    if let Some(ref mut borrowck_context) = self.borrowck_context {
-                        let region_vid = borrowck_context
-                            .universal_regions
-                            .to_region_vid(late_bound_region);
-                        borrowck_context
-                            .constraints
-                            .liveness_constraints
-                            .add_element(region_vid, term_location);
-                    }
+                    let region_vid = self.borrowck_context
+                        .universal_regions
+                        .to_region_vid(late_bound_region);
+                    self.borrowck_context
+                        .constraints
+                        .liveness_constraints
+                        .add_element(region_vid, term_location);
                 }
 
                 self.check_call_inputs(mir, term, &sig, args, term_location, from_hir_call);
@@ -1605,7 +1618,7 @@ fn check_terminator(
 
     fn check_call_dest(
         &mut self,
-        mir: &Mir<'tcx>,
+        mir: &Body<'tcx>,
         term: &Terminator<'tcx>,
         sig: &ty::FnSig<'tcx>,
         destination: &Option<(Place<'tcx>, BasicBlock)>,
@@ -1617,14 +1630,14 @@ fn check_call_dest(
                 let dest_ty = dest.ty(mir, tcx).ty;
                 let category = match *dest {
                     Place::Base(PlaceBase::Local(RETURN_PLACE)) => {
-                        if let Some(BorrowCheckContext {
+                        if let BorrowCheckContext {
                             universal_regions:
                                 UniversalRegions {
                                     defining_ty: DefiningTy::Const(def_id, _),
                                     ..
                                 },
                             ..
-                        }) = self.borrowck_context
+                        } = self.borrowck_context
                         {
                             if tcx.is_static(*def_id) {
                                 ConstraintCategory::UseAsStatic
@@ -1674,7 +1687,7 @@ fn check_call_dest(
 
     fn check_call_inputs(
         &mut self,
-        mir: &Mir<'tcx>,
+        mir: &Body<'tcx>,
         term: &Terminator<'tcx>,
         sig: &ty::FnSig<'tcx>,
         args: &[Operand<'tcx>],
@@ -1715,7 +1728,7 @@ fn check_call_inputs(
         }
     }
 
-    fn check_iscleanup(&mut self, mir: &Mir<'tcx>, block_data: &BasicBlockData<'tcx>) {
+    fn check_iscleanup(&mut self, mir: &Body<'tcx>, block_data: &BasicBlockData<'tcx>) {
         let is_cleanup = block_data.is_cleanup;
         self.last_span = block_data.terminator().source_info.span;
         match block_data.terminator().kind {
@@ -1807,7 +1820,7 @@ fn check_iscleanup(&mut self, mir: &Mir<'tcx>, block_data: &BasicBlockData<'tcx>
 
     fn assert_iscleanup(
         &mut self,
-        mir: &Mir<'tcx>,
+        mir: &Body<'tcx>,
         ctxt: &dyn fmt::Debug,
         bb: BasicBlock,
         iscleanuppad: bool,
@@ -1823,7 +1836,7 @@ fn assert_iscleanup(
         }
     }
 
-    fn check_local(&mut self, mir: &Mir<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>) {
+    fn check_local(&mut self, mir: &Body<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>) {
         match mir.local_kind(local) {
             LocalKind::ReturnPointer | LocalKind::Arg => {
                 // return values of normal functions are required to be
@@ -1908,18 +1921,14 @@ fn aggregate_field_ty(
                 }
             }
             AggregateKind::Generator(def_id, substs, _) => {
-                // Try pre-transform fields first (upvars and current state)
-                if let Some(ty) = substs.pre_transforms_tys(def_id, tcx).nth(field_index) {
-                    Ok(ty)
-                } else {
-                    // Then try `field_tys` which contains all the fields, but it
-                    // requires the final optimized MIR.
-                    match substs.field_tys(def_id, tcx).nth(field_index) {
-                        Some(ty) => Ok(ty),
-                        None => Err(FieldAccessError::OutOfRange {
-                            field_count: substs.field_tys(def_id, tcx).count(),
-                        }),
-                    }
+                // It doesn't make sense to look at a field beyond the prefix;
+                // these require a variant index, and are not initialized in
+                // aggregate rvalues.
+                match substs.prefix_tys(def_id, tcx).nth(field_index) {
+                    Some(ty) => Ok(ty),
+                    None => Err(FieldAccessError::OutOfRange {
+                        field_count: substs.prefix_tys(def_id, tcx).count(),
+                    }),
                 }
             }
             AggregateKind::Array(ty) => Ok(ty),
@@ -1929,7 +1938,7 @@ fn aggregate_field_ty(
         }
     }
 
-    fn check_rvalue(&mut self, mir: &Mir<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
+    fn check_rvalue(&mut self, mir: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
         let tcx = self.tcx();
 
         match rvalue {
@@ -2265,7 +2274,7 @@ fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<UserTypeAnnotationInde
 
     fn check_aggregate_rvalue(
         &mut self,
-        mir: &Mir<'tcx>,
+        mir: &Body<'tcx>,
         rvalue: &Rvalue<'tcx>,
         aggregate_kind: &AggregateKind<'tcx>,
         operands: &[Operand<'tcx>],
@@ -2323,7 +2332,7 @@ fn check_aggregate_rvalue(
     /// - `borrowed_place`: the place `P` being borrowed
     fn add_reborrow_constraint(
         &mut self,
-        mir: &Mir<'tcx>,
+        mir: &Body<'tcx>,
         location: Location,
         borrow_region: ty::Region<'tcx>,
         borrowed_place: &Place<'tcx>,
@@ -2335,10 +2344,7 @@ fn add_reborrow_constraint(
             all_facts,
             constraints,
             ..
-        } = match self.borrowck_context {
-            Some(ref mut borrowck_context) => borrowck_context,
-            None => return,
-        };
+        } = self.borrowck_context;
 
         // In Polonius mode, we also push a `borrow_region` fact
         // linking the loan to the region (in some cases, though,
@@ -2367,7 +2373,7 @@ fn add_reborrow_constraint(
             "add_reborrow_constraint({:?}, {:?}, {:?})",
             location, borrow_region, borrowed_place
         );
-        while let Place::Projection(box PlaceProjection { base, elem }) = borrowed_place {
+        while let Place::Projection(box Projection { base, elem }) = borrowed_place {
             debug!("add_reborrow_constraint - iteration {:?}", borrowed_place);
 
             match *elem {
@@ -2504,45 +2510,43 @@ fn prove_closure_bounds(
             let closure_constraints =
                 closure_region_requirements.apply_requirements(tcx, def_id, substs);
 
-            if let Some(ref mut borrowck_context) = self.borrowck_context {
-                let bounds_mapping = closure_constraints
-                    .iter()
-                    .enumerate()
-                    .filter_map(|(idx, constraint)| {
-                        let ty::OutlivesPredicate(k1, r2) =
-                            constraint.no_bound_vars().unwrap_or_else(|| {
-                                bug!("query_constraint {:?} contained bound vars", constraint,);
-                            });
-
-                        match k1.unpack() {
-                            UnpackedKind::Lifetime(r1) => {
-                                // constraint is r1: r2
-                                let r1_vid = borrowck_context.universal_regions.to_region_vid(r1);
-                                let r2_vid = borrowck_context.universal_regions.to_region_vid(r2);
-                                let outlives_requirements =
-                                    &closure_region_requirements.outlives_requirements[idx];
-                                Some((
-                                    (r1_vid, r2_vid),
-                                    (
-                                        outlives_requirements.category,
-                                        outlives_requirements.blame_span,
-                                    ),
-                                ))
-                            }
-                            UnpackedKind::Type(_) | UnpackedKind::Const(_) => None,
+            let bounds_mapping = closure_constraints
+                .iter()
+                .enumerate()
+                .filter_map(|(idx, constraint)| {
+                    let ty::OutlivesPredicate(k1, r2) =
+                        constraint.no_bound_vars().unwrap_or_else(|| {
+                            bug!("query_constraint {:?} contained bound vars", constraint,);
+                        });
+
+                    match k1.unpack() {
+                        UnpackedKind::Lifetime(r1) => {
+                            // constraint is r1: r2
+                            let r1_vid = self.borrowck_context.universal_regions.to_region_vid(r1);
+                            let r2_vid = self.borrowck_context.universal_regions.to_region_vid(r2);
+                            let outlives_requirements =
+                                &closure_region_requirements.outlives_requirements[idx];
+                            Some((
+                                (r1_vid, r2_vid),
+                                (
+                                    outlives_requirements.category,
+                                    outlives_requirements.blame_span,
+                                ),
+                            ))
                         }
-                    })
-                    .collect();
-
-                let existing = borrowck_context
-                    .constraints
-                    .closure_bounds_mapping
-                    .insert(location, bounds_mapping);
-                assert!(
-                    existing.is_none(),
-                    "Multiple closures at the same location."
-                );
-            }
+                        UnpackedKind::Type(_) | UnpackedKind::Const(_) => None,
+                    }
+                })
+                .collect();
+
+            let existing = self.borrowck_context
+                .constraints
+                .closure_bounds_mapping
+                .insert(location, bounds_mapping);
+            assert!(
+                existing.is_none(),
+                "Multiple closures at the same location."
+            );
 
             self.push_region_constraints(
                 location.to_locations(),
@@ -2617,7 +2621,7 @@ fn prove_predicate(
         })
     }
 
-    fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
+    fn typeck_mir(&mut self, mir: &Body<'tcx>) {
         self.last_span = mir.span;
         debug!("run_on_mir: {:?}", mir.span);
 
@@ -2660,56 +2664,6 @@ fn normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T
     }
 }
 
-pub struct TypeckMir;
-
-impl MirPass for TypeckMir {
-    fn run_pass<'a, 'tcx>(
-        &self,
-        tcx: TyCtxt<'a, 'tcx, 'tcx>,
-        src: MirSource<'tcx>,
-        mir: &mut Mir<'tcx>,
-    ) {
-        let def_id = src.def_id();
-        debug!("run_pass: {:?}", def_id);
-
-        // FIXME: We don't need this MIR pass anymore.
-        if true {
-            return;
-        }
-
-        if tcx.sess.err_count() > 0 {
-            // compiling a broken program can obviously result in a
-            // broken MIR, so try not to report duplicate errors.
-            return;
-        }
-
-        if tcx.is_constructor(def_id) {
-            // We just assume that the automatically generated struct/variant constructors are
-            // correct. See the comment in the `mir_borrowck` implementation for an
-            // explanation why we need this.
-            return;
-        }
-
-        let param_env = tcx.param_env(def_id);
-        tcx.infer_ctxt().enter(|infcx| {
-            type_check_internal(
-                &infcx,
-                def_id,
-                param_env,
-                mir,
-                &vec![],
-                None,
-                None,
-                None,
-                |_| (),
-            );
-
-            // For verification purposes, we just ignore the resulting
-            // region constraint sets. Not our problem. =)
-        });
-    }
-}
-
 trait NormalizeLocation: fmt::Debug + Copy {
     fn to_locations(self) -> Locations;
 }