]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/borrow_check/nll/type_check/mod.rs
Address review comments
[rust.git] / src / librustc_mir / borrow_check / nll / type_check / mod.rs
1 //! This pass type-checks the MIR to ensure it is not broken.
2
3 #![allow(unreachable_code)]
4
5 use crate::borrow_check::borrow_set::BorrowSet;
6 use crate::borrow_check::location::LocationTable;
7 use crate::borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
8 use crate::borrow_check::nll::facts::AllFacts;
9 use crate::borrow_check::nll::region_infer::values::LivenessValues;
10 use crate::borrow_check::nll::region_infer::values::PlaceholderIndex;
11 use crate::borrow_check::nll::region_infer::values::PlaceholderIndices;
12 use crate::borrow_check::nll::region_infer::values::RegionValueElements;
13 use crate::borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest};
14 use crate::borrow_check::nll::renumber;
15 use crate::borrow_check::nll::type_check::free_region_relations::{
16     CreateResult, UniversalRegionRelations,
17 };
18 use crate::borrow_check::nll::universal_regions::{DefiningTy, UniversalRegions};
19 use crate::borrow_check::nll::ToRegionVid;
20 use crate::dataflow::move_paths::MoveData;
21 use crate::dataflow::FlowAtLocation;
22 use crate::dataflow::MaybeInitializedPlaces;
23 use crate::transform::{MirPass, MirSource};
24 use either::Either;
25 use rustc::hir;
26 use rustc::hir::def_id::DefId;
27 use rustc::infer::canonical::QueryRegionConstraint;
28 use rustc::infer::outlives::env::RegionBoundPairs;
29 use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
30 use rustc::infer::type_variable::TypeVariableOrigin;
31 use rustc::mir::interpret::{InterpError::BoundsCheck, ConstValue};
32 use rustc::mir::tcx::PlaceTy;
33 use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext};
34 use rustc::mir::*;
35 use rustc::traits::query::type_op;
36 use rustc::traits::query::type_op::custom::CustomTypeOp;
37 use rustc::traits::query::{Fallible, NoSolution};
38 use rustc::traits::{ObligationCause, PredicateObligations};
39 use rustc::ty::adjustment::{PointerCast};
40 use rustc::ty::fold::TypeFoldable;
41 use rustc::ty::subst::{Subst, SubstsRef, UnpackedKind, UserSubsts};
42 use rustc::ty::{
43     self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, UserType,
44     CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
45     UserTypeAnnotationIndex,
46 };
47 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
48 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
49 use rustc::ty::layout::VariantIdx;
50 use std::rc::Rc;
51 use std::{fmt, iter, mem};
52 use syntax_pos::{Span, DUMMY_SP};
53
54 macro_rules! span_mirbug {
55     ($context:expr, $elem:expr, $($message:tt)*) => ({
56         $crate::borrow_check::nll::type_check::mirbug(
57             $context.tcx(),
58             $context.last_span,
59             &format!(
60                 "broken MIR in {:?} ({:?}): {}",
61                 $context.mir_def_id,
62                 $elem,
63                 format_args!($($message)*),
64             ),
65         )
66     })
67 }
68
69 macro_rules! span_mirbug_and_err {
70     ($context:expr, $elem:expr, $($message:tt)*) => ({
71         {
72             span_mirbug!($context, $elem, $($message)*);
73             $context.error()
74         }
75     })
76 }
77
78 mod constraint_conversion;
79 pub mod free_region_relations;
80 mod input_output;
81 crate mod liveness;
82 mod relate_tys;
83
84 /// Type checks the given `mir` in the context of the inference
85 /// context `infcx`. Returns any region constraints that have yet to
86 /// be proven. This result is includes liveness constraints that
87 /// ensure that regions appearing in the types of all local variables
88 /// are live at all points where that local variable may later be
89 /// used.
90 ///
91 /// This phase of type-check ought to be infallible -- this is because
92 /// the original, HIR-based type-check succeeded. So if any errors
93 /// occur here, we will get a `bug!` reported.
94 ///
95 /// # Parameters
96 ///
97 /// - `infcx` -- inference context to use
98 /// - `param_env` -- parameter environment to use for trait solving
99 /// - `mir` -- MIR to type-check
100 /// - `mir_def_id` -- DefId from which the MIR is derived (must be local)
101 /// - `region_bound_pairs` -- the implied outlives obligations between type parameters
102 ///   and lifetimes (e.g., `&'a T` implies `T: 'a`)
103 /// - `implicit_region_bound` -- a region which all generic parameters are assumed
104 ///   to outlive; should represent the fn body
105 /// - `input_tys` -- fully liberated, but **not** normalized, expected types of the arguments;
106 ///   the types of the input parameters found in the MIR itself will be equated with these
107 /// - `output_ty` -- fully liberated, but **not** normalized, expected return type;
108 ///   the type for the RETURN_PLACE will be equated with this
109 /// - `liveness` -- results of a liveness computation on the MIR; used to create liveness
110 ///   constraints for the regions in the types of variables
111 /// - `flow_inits` -- results of a maybe-init dataflow analysis
112 /// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
113 pub(crate) fn type_check<'gcx, 'tcx>(
114     infcx: &InferCtxt<'_, 'gcx, 'tcx>,
115     param_env: ty::ParamEnv<'gcx>,
116     mir: &Mir<'tcx>,
117     mir_def_id: DefId,
118     universal_regions: &Rc<UniversalRegions<'tcx>>,
119     location_table: &LocationTable,
120     borrow_set: &BorrowSet<'tcx>,
121     all_facts: &mut Option<AllFacts>,
122     flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
123     move_data: &MoveData<'tcx>,
124     elements: &Rc<RegionValueElements>,
125 ) -> MirTypeckResults<'tcx> {
126     let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
127     let mut constraints = MirTypeckRegionConstraints {
128         placeholder_indices: PlaceholderIndices::default(),
129         placeholder_index_to_region: IndexVec::default(),
130         liveness_constraints: LivenessValues::new(elements.clone()),
131         outlives_constraints: ConstraintSet::default(),
132         closure_bounds_mapping: Default::default(),
133         type_tests: Vec::default(),
134     };
135
136     let CreateResult {
137         universal_region_relations,
138         region_bound_pairs,
139         normalized_inputs_and_output,
140     } = free_region_relations::create(
141         infcx,
142         param_env,
143         Some(implicit_region_bound),
144         universal_regions,
145         &mut constraints,
146     );
147
148     let mut borrowck_context = BorrowCheckContext {
149         universal_regions,
150         location_table,
151         borrow_set,
152         all_facts,
153         constraints: &mut constraints,
154     };
155
156     type_check_internal(
157         infcx,
158         mir_def_id,
159         param_env,
160         mir,
161         &region_bound_pairs,
162         Some(implicit_region_bound),
163         Some(&mut borrowck_context),
164         Some(&universal_region_relations),
165         |cx| {
166             cx.equate_inputs_and_outputs(mir, universal_regions, &normalized_inputs_and_output);
167             liveness::generate(cx, mir, elements, flow_inits, move_data, location_table);
168
169             cx.borrowck_context
170                 .as_mut()
171                 .map(|bcx| translate_outlives_facts(bcx));
172         },
173     );
174
175     MirTypeckResults {
176         constraints,
177         universal_region_relations,
178     }
179 }
180
181 fn type_check_internal<'a, 'gcx, 'tcx, R>(
182     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
183     mir_def_id: DefId,
184     param_env: ty::ParamEnv<'gcx>,
185     mir: &'a Mir<'tcx>,
186     region_bound_pairs: &'a RegionBoundPairs<'tcx>,
187     implicit_region_bound: Option<ty::Region<'tcx>>,
188     borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
189     universal_region_relations: Option<&'a UniversalRegionRelations<'tcx>>,
190     mut extra: impl FnMut(&mut TypeChecker<'a, 'gcx, 'tcx>) -> R,
191 ) -> R where {
192     let mut checker = TypeChecker::new(
193         infcx,
194         mir,
195         mir_def_id,
196         param_env,
197         region_bound_pairs,
198         implicit_region_bound,
199         borrowck_context,
200         universal_region_relations,
201     );
202     let errors_reported = {
203         let mut verifier = TypeVerifier::new(&mut checker, mir);
204         verifier.visit_mir(mir);
205         verifier.errors_reported
206     };
207
208     if !errors_reported {
209         // if verifier failed, don't do further checks to avoid ICEs
210         checker.typeck_mir(mir);
211     }
212
213     extra(&mut checker)
214 }
215
216 fn translate_outlives_facts(cx: &mut BorrowCheckContext<'_, '_>) {
217     if let Some(facts) = cx.all_facts {
218         let location_table = cx.location_table;
219         facts
220             .outlives
221             .extend(cx.constraints.outlives_constraints.iter().flat_map(
222                 |constraint: &OutlivesConstraint| {
223                     if let Some(from_location) = constraint.locations.from_location() {
224                         Either::Left(iter::once((
225                             constraint.sup,
226                             constraint.sub,
227                             location_table.mid_index(from_location),
228                         )))
229                     } else {
230                         Either::Right(
231                             location_table
232                                 .all_points()
233                                 .map(move |location| (constraint.sup, constraint.sub, location)),
234                         )
235                     }
236                 },
237             ));
238     }
239 }
240
241 fn mirbug(tcx: TyCtxt<'_, '_, '_>, span: Span, msg: &str) {
242     // We sometimes see MIR failures (notably predicate failures) due to
243     // the fact that we check rvalue sized predicates here. So use `delay_span_bug`
244     // to avoid reporting bugs in those cases.
245     tcx.sess.diagnostic().delay_span_bug(span, msg);
246 }
247
248 enum FieldAccessError {
249     OutOfRange { field_count: usize },
250 }
251
252 /// Verifies that MIR types are sane to not crash further checks.
253 ///
254 /// The sanitize_XYZ methods here take an MIR object and compute its
255 /// type, calling `span_mirbug` and returning an error type if there
256 /// is a problem.
257 struct TypeVerifier<'a, 'b: 'a, 'gcx: 'tcx, 'tcx: 'b> {
258     cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>,
259     mir: &'b Mir<'tcx>,
260     last_span: Span,
261     mir_def_id: DefId,
262     errors_reported: bool,
263 }
264
265 impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
266     fn visit_span(&mut self, span: &Span) {
267         if !span.is_dummy() {
268             self.last_span = *span;
269         }
270     }
271
272     fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext<'_>, location: Location) {
273         self.sanitize_place(place, location, context);
274     }
275
276     fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
277         self.super_constant(constant, location);
278         self.sanitize_constant(constant, location);
279         self.sanitize_type(constant, constant.ty);
280
281         if let Some(annotation_index) = constant.user_ty {
282             if let Err(terr) = self.cx.relate_type_and_user_type(
283                 constant.ty,
284                 ty::Variance::Invariant,
285                 &UserTypeProjection { base: annotation_index, projs: vec![], },
286                 location.to_locations(),
287                 ConstraintCategory::Boring,
288             ) {
289                 let annotation = &self.cx.user_type_annotations[annotation_index];
290                 span_mirbug!(
291                     self,
292                     constant,
293                     "bad constant user type {:?} vs {:?}: {:?}",
294                     annotation,
295                     constant.ty,
296                     terr,
297                 );
298             }
299         } else {
300             if let ConstValue::Unevaluated(def_id, substs) = constant.literal.val {
301                 if let Err(terr) = self.cx.fully_perform_op(
302                     location.to_locations(),
303                     ConstraintCategory::Boring,
304                     self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
305                         constant.ty, def_id, UserSubsts { substs, user_self_ty: None },
306                     )),
307                 ) {
308                     span_mirbug!(
309                         self,
310                         constant,
311                         "bad constant type {:?} ({:?})",
312                         constant,
313                         terr
314                     );
315                 }
316             }
317             if let ty::FnDef(def_id, substs) = constant.literal.ty.sty {
318                 let tcx = self.tcx();
319
320                 let instantiated_predicates = tcx
321                     .predicates_of(def_id)
322                     .instantiate(tcx, substs);
323                 self.cx.normalize_and_prove_instantiated_predicates(
324                     instantiated_predicates,
325                     location.to_locations(),
326                 );
327             }
328         }
329     }
330
331     fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
332         self.super_rvalue(rvalue, location);
333         let rval_ty = rvalue.ty(self.mir, self.tcx());
334         self.sanitize_type(rvalue, rval_ty);
335     }
336
337     fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
338         self.super_local_decl(local, local_decl);
339         self.sanitize_type(local_decl, local_decl.ty);
340
341         for (user_ty, span) in local_decl.user_ty.projections_and_spans() {
342             let ty = if !local_decl.is_nonref_binding() {
343                 // If we have a binding of the form `let ref x: T = ..` then remove the outermost
344                 // reference so we can check the type annotation for the remaining type.
345                 if let ty::Ref(_, rty, _) = local_decl.ty.sty {
346                     rty
347                 } else {
348                     bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty);
349                 }
350             } else {
351                 local_decl.ty
352             };
353
354             if let Err(terr) = self.cx.relate_type_and_user_type(
355                 ty,
356                 ty::Variance::Invariant,
357                 user_ty,
358                 Locations::All(*span),
359                 ConstraintCategory::TypeAnnotation,
360             ) {
361                 span_mirbug!(
362                     self,
363                     local,
364                     "bad user type on variable {:?}: {:?} != {:?} ({:?})",
365                     local,
366                     local_decl.ty,
367                     local_decl.user_ty,
368                     terr,
369                 );
370             }
371         }
372     }
373
374     fn visit_mir(&mut self, mir: &Mir<'tcx>) {
375         self.sanitize_type(&"return type", mir.return_ty());
376         for local_decl in &mir.local_decls {
377             self.sanitize_type(local_decl, local_decl.ty);
378         }
379         if self.errors_reported {
380             return;
381         }
382         self.super_mir(mir);
383     }
384 }
385
386 impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
387     fn new(cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>, mir: &'b Mir<'tcx>) -> Self {
388         TypeVerifier {
389             mir,
390             mir_def_id: cx.mir_def_id,
391             cx,
392             last_span: mir.span,
393             errors_reported: false,
394         }
395     }
396
397     fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
398         self.cx.infcx.tcx
399     }
400
401     fn sanitize_type(&mut self, parent: &dyn fmt::Debug, ty: Ty<'tcx>) -> Ty<'tcx> {
402         if ty.has_escaping_bound_vars() || ty.references_error() {
403             span_mirbug_and_err!(self, parent, "bad type {:?}", ty)
404         } else {
405             ty
406         }
407     }
408
409     /// Checks that the constant's `ty` field matches up with what would be
410     /// expected from its literal. Unevaluated constants and well-formed
411     /// constraints are checked by `visit_constant`.
412     fn sanitize_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
413         debug!(
414             "sanitize_constant(constant={:?}, location={:?})",
415             constant, location
416         );
417
418         let literal = constant.literal;
419
420         if let ConstValue::Unevaluated(..) = literal.val {
421             return;
422         }
423
424         debug!("sanitize_constant: expected_ty={:?}", literal.ty);
425
426         if let Err(terr) = self.cx.eq_types(
427             literal.ty,
428             constant.ty,
429             location.to_locations(),
430             ConstraintCategory::Boring,
431         ) {
432             span_mirbug!(
433                 self,
434                 constant,
435                 "constant {:?} should have type {:?} but has {:?} ({:?})",
436                 constant,
437                 literal.ty,
438                 constant.ty,
439                 terr,
440             );
441         }
442     }
443
444     /// Checks that the types internal to the `place` match up with
445     /// what would be expected.
446     fn sanitize_place(
447         &mut self,
448         place: &Place<'tcx>,
449         location: Location,
450         context: PlaceContext<'_>,
451     ) -> PlaceTy<'tcx> {
452         debug!("sanitize_place: {:?}", place);
453         let place_ty = match place {
454             Place::Base(PlaceBase::Local(index)) =>
455                 PlaceTy::from_ty(self.mir.local_decls[*index].ty),
456             Place::Base(PlaceBase::Static(box Static { kind, ty: sty })) => {
457                 let sty = self.sanitize_type(place, sty);
458                 let check_err =
459                     |verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>,
460                      place: &Place<'tcx>,
461                      ty,
462                      sty| {
463                         if let Err(terr) = verifier.cx.eq_types(
464                             sty,
465                             ty,
466                             location.to_locations(),
467                             ConstraintCategory::Boring,
468                         ) {
469                             span_mirbug!(
470                             verifier,
471                             place,
472                             "bad promoted type ({:?}: {:?}): {:?}",
473                             ty,
474                             sty,
475                             terr
476                         );
477                         };
478                     };
479                 match kind {
480                     StaticKind::Promoted(promoted) => {
481                         if !self.errors_reported {
482                             let promoted_mir = &self.mir.promoted[*promoted];
483                             self.sanitize_promoted(promoted_mir, location);
484
485                             let promoted_ty = promoted_mir.return_ty();
486                             check_err(self, place, promoted_ty, sty);
487                         }
488                     }
489                     StaticKind::Static(def_id) => {
490                         let ty = self.tcx().type_of(*def_id);
491                         let ty = self.cx.normalize(ty, location);
492
493                         check_err(self, place, ty, sty);
494                     }
495                 }
496                 PlaceTy::from_ty(sty)
497             }
498             Place::Projection(ref proj) => {
499                 let base_context = if context.is_mutating_use() {
500                     PlaceContext::MutatingUse(MutatingUseContext::Projection)
501                 } else {
502                     PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
503                 };
504                 let base_ty = self.sanitize_place(&proj.base, location, base_context);
505                 if base_ty.variant_index.is_none() {
506                     if base_ty.ty.references_error() {
507                         assert!(self.errors_reported);
508                         return PlaceTy::from_ty(self.tcx().types.err);
509                     }
510                 }
511                 self.sanitize_projection(base_ty, &proj.elem, place, location)
512             }
513         };
514         if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
515             let tcx = self.tcx();
516             let trait_ref = ty::TraitRef {
517                 def_id: tcx.lang_items().copy_trait().unwrap(),
518                 substs: tcx.mk_substs_trait(place_ty.ty, &[]),
519             };
520
521             // In order to have a Copy operand, the type T of the
522             // value must be Copy. Note that we prove that T: Copy,
523             // rather than using the `is_copy_modulo_regions`
524             // test. This is important because
525             // `is_copy_modulo_regions` ignores the resulting region
526             // obligations and assumes they pass. This can result in
527             // bounds from Copy impls being unsoundly ignored (e.g.,
528             // #29149). Note that we decide to use Copy before knowing
529             // whether the bounds fully apply: in effect, the rule is
530             // that if a value of some type could implement Copy, then
531             // it must.
532             self.cx.prove_trait_ref(
533                 trait_ref,
534                 location.to_locations(),
535                 ConstraintCategory::CopyBound,
536             );
537         }
538         place_ty
539     }
540
541     fn sanitize_promoted(&mut self, promoted_mir: &'b Mir<'tcx>, location: Location) {
542         // Determine the constraints from the promoted MIR by running the type
543         // checker on the promoted MIR, then transfer the constraints back to
544         // the main MIR, changing the locations to the provided location.
545
546         let parent_mir = mem::replace(&mut self.mir, promoted_mir);
547
548         let all_facts = &mut None;
549         let mut constraints = Default::default();
550         let mut closure_bounds = Default::default();
551         if let Some(ref mut bcx) = self.cx.borrowck_context {
552             // Don't try to add borrow_region facts for the promoted MIR
553             mem::swap(bcx.all_facts, all_facts);
554
555             // Use a new sets of constraints and closure bounds so that we can
556             // modify their locations.
557             mem::swap(&mut bcx.constraints.outlives_constraints, &mut constraints);
558             mem::swap(&mut bcx.constraints.closure_bounds_mapping, &mut closure_bounds);
559         };
560
561         self.visit_mir(promoted_mir);
562
563         if !self.errors_reported {
564             // if verifier failed, don't do further checks to avoid ICEs
565             self.cx.typeck_mir(promoted_mir);
566         }
567
568         self.mir = parent_mir;
569         // Merge the outlives constraints back in, at the given location.
570         if let Some(ref mut base_bcx) = self.cx.borrowck_context {
571             mem::swap(base_bcx.all_facts, all_facts);
572             mem::swap(&mut base_bcx.constraints.outlives_constraints, &mut constraints);
573             mem::swap(&mut base_bcx.constraints.closure_bounds_mapping, &mut closure_bounds);
574
575             let locations = location.to_locations();
576             for constraint in constraints.iter() {
577                 let mut constraint = *constraint;
578                 constraint.locations = locations;
579                 if let ConstraintCategory::Return
580                     | ConstraintCategory::UseAsConst
581                     | ConstraintCategory::UseAsStatic = constraint.category
582                 {
583                     // "Returning" from a promoted is an assigment to a
584                     // temporary from the user's point of view.
585                     constraint.category = ConstraintCategory::Boring;
586                 }
587                 base_bcx.constraints.outlives_constraints.push(constraint)
588             }
589
590             if !closure_bounds.is_empty() {
591                 let combined_bounds_mapping = closure_bounds
592                     .into_iter()
593                     .flat_map(|(_, value)| value)
594                     .collect();
595                 let existing = base_bcx
596                     .constraints
597                     .closure_bounds_mapping
598                     .insert(location, combined_bounds_mapping);
599                 assert!(
600                     existing.is_none(),
601                     "Multiple promoteds/closures at the same location."
602                 );
603             }
604         }
605     }
606
607     fn sanitize_projection(
608         &mut self,
609         base: PlaceTy<'tcx>,
610         pi: &PlaceElem<'tcx>,
611         place: &Place<'tcx>,
612         location: Location,
613     ) -> PlaceTy<'tcx> {
614         debug!("sanitize_projection: {:?} {:?} {:?}", base, pi, place);
615         let tcx = self.tcx();
616         let base_ty = base.ty;
617         match *pi {
618             ProjectionElem::Deref => {
619                 let deref_ty = base_ty.builtin_deref(true);
620                 PlaceTy::from_ty(
621                     deref_ty.map(|t| t.ty).unwrap_or_else(|| {
622                         span_mirbug_and_err!(self, place, "deref of non-pointer {:?}", base_ty)
623                     })
624                 )
625             }
626             ProjectionElem::Index(i) => {
627                 let index_ty = Place::Base(PlaceBase::Local(i)).ty(self.mir, tcx).ty;
628                 if index_ty != tcx.types.usize {
629                     PlaceTy::from_ty(
630                         span_mirbug_and_err!(self, i, "index by non-usize {:?}", i),
631                     )
632                 } else {
633                     PlaceTy::from_ty(
634                         base_ty.builtin_index().unwrap_or_else(|| {
635                             span_mirbug_and_err!(self, place, "index of non-array {:?}", base_ty)
636                         }),
637                     )
638                 }
639             }
640             ProjectionElem::ConstantIndex { .. } => {
641                 // consider verifying in-bounds
642                 PlaceTy::from_ty(
643                     base_ty.builtin_index().unwrap_or_else(|| {
644                         span_mirbug_and_err!(self, place, "index of non-array {:?}", base_ty)
645                     }),
646                 )
647             }
648             ProjectionElem::Subslice { from, to } => PlaceTy::from_ty(
649                 match base_ty.sty {
650                     ty::Array(inner, size) => {
651                         let size = size.unwrap_usize(tcx);
652                         let min_size = (from as u64) + (to as u64);
653                         if let Some(rest_size) = size.checked_sub(min_size) {
654                             tcx.mk_array(inner, rest_size)
655                         } else {
656                             span_mirbug_and_err!(
657                                 self,
658                                 place,
659                                 "taking too-small slice of {:?}",
660                                 base_ty
661                             )
662                         }
663                     }
664                     ty::Slice(..) => base_ty,
665                     _ => span_mirbug_and_err!(self, place, "slice of non-array {:?}", base_ty),
666                 },
667             ),
668             ProjectionElem::Downcast(maybe_name, index) => match base_ty.sty {
669                 ty::Adt(adt_def, _substs) if adt_def.is_enum() => {
670                     if index.as_usize() >= adt_def.variants.len() {
671                         PlaceTy::from_ty(
672                             span_mirbug_and_err!(
673                                 self,
674                                 place,
675                                 "cast to variant #{:?} but enum only has {:?}",
676                                 index,
677                                 adt_def.variants.len()
678                             ),
679                         )
680                     } else {
681                         PlaceTy {
682                             ty: base_ty,
683                             variant_index: Some(index),
684                         }
685                     }
686                 }
687                 // We do not need to handle generators here, because this runs
688                 // before the generator transform stage.
689                 _ => {
690                     let ty = if let Some(name) = maybe_name {
691                         span_mirbug_and_err!(
692                             self,
693                             place,
694                             "can't downcast {:?} as {:?}",
695                             base_ty,
696                             name
697                         )
698                     } else {
699                         span_mirbug_and_err!(self, place, "can't downcast {:?}", base_ty)
700                     };
701                     PlaceTy::from_ty(ty)
702                 },
703             },
704             ProjectionElem::Field(field, fty) => {
705                 let fty = self.sanitize_type(place, fty);
706                 match self.field_ty(place, base, field, location) {
707                     Ok(ty) => if let Err(terr) = self.cx.eq_types(
708                         ty,
709                         fty,
710                         location.to_locations(),
711                         ConstraintCategory::Boring,
712                     ) {
713                         span_mirbug!(
714                             self,
715                             place,
716                             "bad field access ({:?}: {:?}): {:?}",
717                             ty,
718                             fty,
719                             terr
720                         );
721                     },
722                     Err(FieldAccessError::OutOfRange { field_count }) => span_mirbug!(
723                         self,
724                         place,
725                         "accessed field #{} but variant only has {}",
726                         field.index(),
727                         field_count
728                     ),
729                 }
730                 PlaceTy::from_ty(fty)
731             }
732         }
733     }
734
735     fn error(&mut self) -> Ty<'tcx> {
736         self.errors_reported = true;
737         self.tcx().types.err
738     }
739
740     fn field_ty(
741         &mut self,
742         parent: &dyn fmt::Debug,
743         base_ty: PlaceTy<'tcx>,
744         field: Field,
745         location: Location,
746     ) -> Result<Ty<'tcx>, FieldAccessError> {
747         let tcx = self.tcx();
748
749         let (variant, substs) = match base_ty {
750             PlaceTy { ty, variant_index: Some(variant_index) } => match ty.sty {
751                 ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
752                 ty::Generator(def_id, substs, _) => {
753                     let mut variants = substs.state_tys(def_id, tcx);
754                     let mut variant = match variants.nth(variant_index.into()) {
755                         Some(v) => v,
756                         None => {
757                             bug!("variant_index of generator out of range: {:?}/{:?}",
758                                  variant_index,
759                                  substs.state_tys(def_id, tcx).count())
760                         }
761                     };
762                     return match variant.nth(field.index()) {
763                         Some(ty) => Ok(ty),
764                         None => Err(FieldAccessError::OutOfRange {
765                             field_count: variant.count(),
766                         }),
767                     }
768                 }
769                 _ => bug!("can't have downcast of non-adt non-generator type"),
770             }
771             PlaceTy { ty, variant_index: None } => match ty.sty {
772                 ty::Adt(adt_def, substs) if !adt_def.is_enum() =>
773                     (&adt_def.variants[VariantIdx::new(0)], substs),
774                 ty::Closure(def_id, substs) => {
775                     return match substs.upvar_tys(def_id, tcx).nth(field.index()) {
776                         Some(ty) => Ok(ty),
777                         None => Err(FieldAccessError::OutOfRange {
778                             field_count: substs.upvar_tys(def_id, tcx).count(),
779                         }),
780                     }
781                 }
782                 ty::Generator(def_id, substs, _) => {
783                     // Only prefix fields (upvars and current state) are
784                     // accessible without a variant index.
785                     return match substs.prefix_tys(def_id, tcx).nth(field.index()) {
786                         Some(ty) => Ok(ty),
787                         None => Err(FieldAccessError::OutOfRange {
788                             field_count: substs.prefix_tys(def_id, tcx).count(),
789                         }),
790                     }
791                 }
792                 ty::Tuple(tys) => {
793                     return match tys.get(field.index()) {
794                         Some(&ty) => Ok(ty),
795                         None => Err(FieldAccessError::OutOfRange {
796                             field_count: tys.len(),
797                         }),
798                     }
799                 }
800                 _ => {
801                     return Ok(span_mirbug_and_err!(
802                         self,
803                         parent,
804                         "can't project out of {:?}",
805                         base_ty
806                     ))
807                 }
808             },
809         };
810
811         if let Some(field) = variant.fields.get(field.index()) {
812             Ok(self.cx.normalize(&field.ty(tcx, substs), location))
813         } else {
814             Err(FieldAccessError::OutOfRange {
815                 field_count: variant.fields.len(),
816             })
817         }
818     }
819 }
820
821 /// The MIR type checker. Visits the MIR and enforces all the
822 /// constraints needed for it to be valid and well-typed. Along the
823 /// way, it accrues region constraints -- these can later be used by
824 /// NLL region checking.
825 struct TypeChecker<'a, 'gcx: 'tcx, 'tcx: 'a> {
826     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
827     param_env: ty::ParamEnv<'gcx>,
828     last_span: Span,
829     /// User type annotations are shared between the main MIR and the MIR of
830     /// all of the promoted items.
831     user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
832     mir_def_id: DefId,
833     region_bound_pairs: &'a RegionBoundPairs<'tcx>,
834     implicit_region_bound: Option<ty::Region<'tcx>>,
835     reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
836     borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
837     universal_region_relations: Option<&'a UniversalRegionRelations<'tcx>>,
838 }
839
840 struct BorrowCheckContext<'a, 'tcx: 'a> {
841     universal_regions: &'a UniversalRegions<'tcx>,
842     location_table: &'a LocationTable,
843     all_facts: &'a mut Option<AllFacts>,
844     borrow_set: &'a BorrowSet<'tcx>,
845     constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
846 }
847
848 crate struct MirTypeckResults<'tcx> {
849     crate constraints: MirTypeckRegionConstraints<'tcx>,
850     crate universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
851 }
852
853 /// A collection of region constraints that must be satisfied for the
854 /// program to be considered well-typed.
855 crate struct MirTypeckRegionConstraints<'tcx> {
856     /// Maps from a `ty::Placeholder` to the corresponding
857     /// `PlaceholderIndex` bit that we will use for it.
858     ///
859     /// To keep everything in sync, do not insert this set
860     /// directly. Instead, use the `placeholder_region` helper.
861     crate placeholder_indices: PlaceholderIndices,
862
863     /// Each time we add a placeholder to `placeholder_indices`, we
864     /// also create a corresponding "representative" region vid for
865     /// that wraps it. This vector tracks those. This way, when we
866     /// convert the same `ty::RePlaceholder(p)` twice, we can map to
867     /// the same underlying `RegionVid`.
868     crate placeholder_index_to_region: IndexVec<PlaceholderIndex, ty::Region<'tcx>>,
869
870     /// In general, the type-checker is not responsible for enforcing
871     /// liveness constraints; this job falls to the region inferencer,
872     /// which performs a liveness analysis. However, in some limited
873     /// cases, the MIR type-checker creates temporary regions that do
874     /// not otherwise appear in the MIR -- in particular, the
875     /// late-bound regions that it instantiates at call-sites -- and
876     /// hence it must report on their liveness constraints.
877     crate liveness_constraints: LivenessValues<RegionVid>,
878
879     crate outlives_constraints: ConstraintSet,
880
881     crate closure_bounds_mapping:
882         FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
883
884     crate type_tests: Vec<TypeTest<'tcx>>,
885 }
886
887 impl MirTypeckRegionConstraints<'tcx> {
888     fn placeholder_region(
889         &mut self,
890         infcx: &InferCtxt<'_, '_, 'tcx>,
891         placeholder: ty::PlaceholderRegion,
892     ) -> ty::Region<'tcx> {
893         let placeholder_index = self.placeholder_indices.insert(placeholder);
894         match self.placeholder_index_to_region.get(placeholder_index) {
895             Some(&v) => v,
896             None => {
897                 let origin = NLLRegionVariableOrigin::Placeholder(placeholder);
898                 let region = infcx.next_nll_region_var_in_universe(origin, placeholder.universe);
899                 self.placeholder_index_to_region.push(region);
900                 region
901             }
902         }
903     }
904 }
905
906 /// The `Locations` type summarizes *where* region constraints are
907 /// required to hold. Normally, this is at a particular point which
908 /// created the obligation, but for constraints that the user gave, we
909 /// want the constraint to hold at all points.
910 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
911 pub enum Locations {
912     /// Indicates that a type constraint should always be true. This
913     /// is particularly important in the new borrowck analysis for
914     /// things like the type of the return slot. Consider this
915     /// example:
916     ///
917     /// ```
918     /// fn foo<'a>(x: &'a u32) -> &'a u32 {
919     ///     let y = 22;
920     ///     return &y; // error
921     /// }
922     /// ```
923     ///
924     /// Here, we wind up with the signature from the return type being
925     /// something like `&'1 u32` where `'1` is a universal region. But
926     /// the type of the return slot `_0` is something like `&'2 u32`
927     /// where `'2` is an existential region variable. The type checker
928     /// requires that `&'2 u32 = &'1 u32` -- but at what point? In the
929     /// older NLL analysis, we required this only at the entry point
930     /// to the function. By the nature of the constraints, this wound
931     /// up propagating to all points reachable from start (because
932     /// `'1` -- as a universal region -- is live everywhere). In the
933     /// newer analysis, though, this doesn't work: `_0` is considered
934     /// dead at the start (it has no usable value) and hence this type
935     /// equality is basically a no-op. Then, later on, when we do `_0
936     /// = &'3 y`, that region `'3` never winds up related to the
937     /// universal region `'1` and hence no error occurs. Therefore, we
938     /// use Locations::All instead, which ensures that the `'1` and
939     /// `'2` are equal everything. We also use this for other
940     /// user-given type annotations; e.g., if the user wrote `let mut
941     /// x: &'static u32 = ...`, we would ensure that all values
942     /// assigned to `x` are of `'static` lifetime.
943     ///
944     /// The span points to the place the constraint arose. For example,
945     /// it points to the type in a user-given type annotation. If
946     /// there's no sensible span then it's DUMMY_SP.
947     All(Span),
948
949     /// An outlives constraint that only has to hold at a single location,
950     /// usually it represents a point where references flow from one spot to
951     /// another (e.g., `x = y`)
952     Single(Location),
953 }
954
955 impl Locations {
956     pub fn from_location(&self) -> Option<Location> {
957         match self {
958             Locations::All(_) => None,
959             Locations::Single(from_location) => Some(*from_location),
960         }
961     }
962
963     /// Gets a span representing the location.
964     pub fn span(&self, mir: &Mir<'_>) -> Span {
965         match self {
966             Locations::All(span) => *span,
967             Locations::Single(l) => mir.source_info(*l).span,
968         }
969     }
970 }
971
972 impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
973     fn new(
974         infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
975         mir: &'a Mir<'tcx>,
976         mir_def_id: DefId,
977         param_env: ty::ParamEnv<'gcx>,
978         region_bound_pairs: &'a RegionBoundPairs<'tcx>,
979         implicit_region_bound: Option<ty::Region<'tcx>>,
980         borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>,
981         universal_region_relations: Option<&'a UniversalRegionRelations<'tcx>>,
982     ) -> Self {
983         let mut checker = Self {
984             infcx,
985             last_span: DUMMY_SP,
986             mir_def_id,
987             user_type_annotations: &mir.user_type_annotations,
988             param_env,
989             region_bound_pairs,
990             implicit_region_bound,
991             borrowck_context,
992             reported_errors: Default::default(),
993             universal_region_relations,
994         };
995         checker.check_user_type_annotations();
996         checker
997     }
998
999     /// Equate the inferred type and the annotated type for user type annotations
1000     fn check_user_type_annotations(&mut self) {
1001         debug!(
1002             "check_user_type_annotations: user_type_annotations={:?}",
1003              self.user_type_annotations
1004         );
1005         for user_annotation in self.user_type_annotations {
1006             let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
1007             let (annotation, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(
1008                 span, user_ty
1009             );
1010             match annotation {
1011                 UserType::Ty(mut ty) => {
1012                     ty = self.normalize(ty, Locations::All(span));
1013
1014                     if let Err(terr) = self.eq_types(
1015                         ty,
1016                         inferred_ty,
1017                         Locations::All(span),
1018                         ConstraintCategory::BoringNoLocation,
1019                     ) {
1020                         span_mirbug!(
1021                             self,
1022                             user_annotation,
1023                             "bad user type ({:?} = {:?}): {:?}",
1024                             ty,
1025                             inferred_ty,
1026                             terr
1027                         );
1028                     }
1029
1030                     self.prove_predicate(
1031                         ty::Predicate::WellFormed(inferred_ty),
1032                         Locations::All(span),
1033                         ConstraintCategory::TypeAnnotation,
1034                     );
1035                 },
1036                 UserType::TypeOf(def_id, user_substs) => {
1037                     if let Err(terr) = self.fully_perform_op(
1038                         Locations::All(span),
1039                         ConstraintCategory::BoringNoLocation,
1040                         self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
1041                             inferred_ty, def_id, user_substs,
1042                         )),
1043                     ) {
1044                         span_mirbug!(
1045                             self,
1046                             user_annotation,
1047                             "bad user type AscribeUserType({:?}, {:?} {:?}): {:?}",
1048                             inferred_ty,
1049                             def_id,
1050                             user_substs,
1051                             terr
1052                         );
1053                     }
1054                 },
1055             }
1056         }
1057     }
1058
1059     /// Given some operation `op` that manipulates types, proves
1060     /// predicates, or otherwise uses the inference context, executes
1061     /// `op` and then executes all the further obligations that `op`
1062     /// returns. This will yield a set of outlives constraints amongst
1063     /// regions which are extracted and stored as having occurred at
1064     /// `locations`.
1065     ///
1066     /// **Any `rustc::infer` operations that might generate region
1067     /// constraints should occur within this method so that those
1068     /// constraints can be properly localized!**
1069     fn fully_perform_op<R>(
1070         &mut self,
1071         locations: Locations,
1072         category: ConstraintCategory,
1073         op: impl type_op::TypeOp<'gcx, 'tcx, Output = R>,
1074     ) -> Fallible<R> {
1075         let (r, opt_data) = op.fully_perform(self.infcx)?;
1076
1077         if let Some(data) = &opt_data {
1078             self.push_region_constraints(locations, category, data);
1079         }
1080
1081         Ok(r)
1082     }
1083
1084     fn push_region_constraints(
1085         &mut self,
1086         locations: Locations,
1087         category: ConstraintCategory,
1088         data: &[QueryRegionConstraint<'tcx>],
1089     ) {
1090         debug!(
1091             "push_region_constraints: constraints generated at {:?} are {:#?}",
1092             locations, data
1093         );
1094
1095         if let Some(ref mut borrowck_context) = self.borrowck_context {
1096             constraint_conversion::ConstraintConversion::new(
1097                 self.infcx,
1098                 borrowck_context.universal_regions,
1099                 self.region_bound_pairs,
1100                 self.implicit_region_bound,
1101                 self.param_env,
1102                 locations,
1103                 category,
1104                 &mut borrowck_context.constraints,
1105             ).convert_all(&data);
1106         }
1107     }
1108
1109     /// Convenient wrapper around `relate_tys::relate_types` -- see
1110     /// that fn for docs.
1111     fn relate_types(
1112         &mut self,
1113         a: Ty<'tcx>,
1114         v: ty::Variance,
1115         b: Ty<'tcx>,
1116         locations: Locations,
1117         category: ConstraintCategory,
1118     ) -> Fallible<()> {
1119         relate_tys::relate_types(
1120             self.infcx,
1121             a,
1122             v,
1123             b,
1124             locations,
1125             category,
1126             self.borrowck_context.as_mut().map(|x| &mut **x),
1127         )
1128     }
1129
1130     fn sub_types(
1131         &mut self,
1132         sub: Ty<'tcx>,
1133         sup: Ty<'tcx>,
1134         locations: Locations,
1135         category: ConstraintCategory,
1136     ) -> Fallible<()> {
1137         self.relate_types(sub, ty::Variance::Covariant, sup, locations, category)
1138     }
1139
1140     /// Try to relate `sub <: sup`; if this fails, instantiate opaque
1141     /// variables in `sub` with their inferred definitions and try
1142     /// again. This is used for opaque types in places (e.g., `let x:
1143     /// impl Foo = ..`).
1144     fn sub_types_or_anon(
1145         &mut self,
1146         sub: Ty<'tcx>,
1147         sup: Ty<'tcx>,
1148         locations: Locations,
1149         category: ConstraintCategory,
1150     ) -> Fallible<()> {
1151         if let Err(terr) = self.sub_types(sub, sup, locations, category) {
1152             if let ty::Opaque(..) = sup.sty {
1153                 // When you have `let x: impl Foo = ...` in a closure,
1154                 // the resulting inferend values are stored with the
1155                 // def-id of the base function.
1156                 let parent_def_id = self.tcx().closure_base_def_id(self.mir_def_id);
1157                 return self.eq_opaque_type_and_type(sub, sup, parent_def_id, locations, category);
1158             } else {
1159                 return Err(terr);
1160             }
1161         }
1162         Ok(())
1163     }
1164
1165     fn eq_types(
1166         &mut self,
1167         a: Ty<'tcx>,
1168         b: Ty<'tcx>,
1169         locations: Locations,
1170         category: ConstraintCategory,
1171     ) -> Fallible<()> {
1172         self.relate_types(a, ty::Variance::Invariant, b, locations, category)
1173     }
1174
1175     fn relate_type_and_user_type(
1176         &mut self,
1177         a: Ty<'tcx>,
1178         v: ty::Variance,
1179         user_ty: &UserTypeProjection,
1180         locations: Locations,
1181         category: ConstraintCategory,
1182     ) -> Fallible<()> {
1183         debug!(
1184             "relate_type_and_user_type(a={:?}, v={:?}, user_ty={:?}, locations={:?})",
1185             a, v, user_ty, locations,
1186         );
1187
1188         let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty;
1189         let mut curr_projected_ty = PlaceTy::from_ty(annotated_type);
1190
1191         let tcx = self.infcx.tcx;
1192
1193         for proj in &user_ty.projs {
1194             let projected_ty = curr_projected_ty.projection_ty_core(tcx, proj, |this, field, &()| {
1195                 let ty = this.field_ty(tcx, field);
1196                 self.normalize(ty, locations)
1197             });
1198             curr_projected_ty = projected_ty;
1199         }
1200         debug!("user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}",
1201                 user_ty.base, annotated_type, user_ty.projs, curr_projected_ty);
1202
1203         let ty = curr_projected_ty.ty;
1204         self.relate_types(a, v, ty, locations, category)?;
1205
1206         Ok(())
1207     }
1208
1209     fn eq_opaque_type_and_type(
1210         &mut self,
1211         revealed_ty: Ty<'tcx>,
1212         anon_ty: Ty<'tcx>,
1213         anon_owner_def_id: DefId,
1214         locations: Locations,
1215         category: ConstraintCategory,
1216     ) -> Fallible<()> {
1217         debug!(
1218             "eq_opaque_type_and_type( \
1219              revealed_ty={:?}, \
1220              anon_ty={:?})",
1221             revealed_ty, anon_ty
1222         );
1223         let infcx = self.infcx;
1224         let tcx = infcx.tcx;
1225         let param_env = self.param_env;
1226         debug!("eq_opaque_type_and_type: mir_def_id={:?}", self.mir_def_id);
1227         let opaque_type_map = self.fully_perform_op(
1228             locations,
1229             category,
1230             CustomTypeOp::new(
1231                 |infcx| {
1232                     let mut obligations = ObligationAccumulator::default();
1233
1234                     let dummy_body_id = ObligationCause::dummy().body_id;
1235                     let (output_ty, opaque_type_map) =
1236                         obligations.add(infcx.instantiate_opaque_types(
1237                             anon_owner_def_id,
1238                             dummy_body_id,
1239                             param_env,
1240                             &anon_ty,
1241                         ));
1242                     debug!(
1243                         "eq_opaque_type_and_type: \
1244                          instantiated output_ty={:?} \
1245                          opaque_type_map={:#?} \
1246                          revealed_ty={:?}",
1247                         output_ty, opaque_type_map, revealed_ty
1248                     );
1249                     obligations.add(infcx
1250                         .at(&ObligationCause::dummy(), param_env)
1251                         .eq(output_ty, revealed_ty)?);
1252
1253                     for (&opaque_def_id, opaque_decl) in &opaque_type_map {
1254                         let opaque_defn_ty = tcx.type_of(opaque_def_id);
1255                         let opaque_defn_ty = opaque_defn_ty.subst(tcx, opaque_decl.substs);
1256                         let opaque_defn_ty = renumber::renumber_regions(infcx, &opaque_defn_ty);
1257                         debug!(
1258                             "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}",
1259                             opaque_decl.concrete_ty,
1260                             infcx.resolve_type_vars_if_possible(&opaque_decl.concrete_ty),
1261                             opaque_defn_ty
1262                         );
1263                         obligations.add(infcx
1264                             .at(&ObligationCause::dummy(), param_env)
1265                             .eq(opaque_decl.concrete_ty, opaque_defn_ty)?);
1266                     }
1267
1268                     debug!("eq_opaque_type_and_type: equated");
1269
1270                     Ok(InferOk {
1271                         value: Some(opaque_type_map),
1272                         obligations: obligations.into_vec(),
1273                     })
1274                 },
1275                 || "input_output".to_string(),
1276             ),
1277         )?;
1278
1279         let universal_region_relations = match self.universal_region_relations {
1280             Some(rel) => rel,
1281             None => return Ok(()),
1282         };
1283
1284         // Finally, if we instantiated the anon types successfully, we
1285         // have to solve any bounds (e.g., `-> impl Iterator` needs to
1286         // prove that `T: Iterator` where `T` is the type we
1287         // instantiated it with).
1288         if let Some(opaque_type_map) = opaque_type_map {
1289             for (opaque_def_id, opaque_decl) in opaque_type_map {
1290                 self.fully_perform_op(
1291                     locations,
1292                     ConstraintCategory::OpaqueType,
1293                     CustomTypeOp::new(
1294                         |_cx| {
1295                             infcx.constrain_opaque_type(
1296                                 opaque_def_id,
1297                                 &opaque_decl,
1298                                 universal_region_relations,
1299                             );
1300                             Ok(InferOk {
1301                                 value: (),
1302                                 obligations: vec![],
1303                             })
1304                         },
1305                         || "opaque_type_map".to_string(),
1306                     ),
1307                 )?;
1308             }
1309         }
1310         Ok(())
1311     }
1312
1313     fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
1314         self.infcx.tcx
1315     }
1316
1317     fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Location) {
1318         debug!("check_stmt: {:?}", stmt);
1319         let tcx = self.tcx();
1320         match stmt.kind {
1321             StatementKind::Assign(ref place, ref rv) => {
1322                 // Assignments to temporaries are not "interesting";
1323                 // they are not caused by the user, but rather artifacts
1324                 // of lowering. Assignments to other sorts of places *are* interesting
1325                 // though.
1326                 let category = match *place {
1327                     Place::Base(PlaceBase::Local(RETURN_PLACE)) => if let Some(BorrowCheckContext {
1328                         universal_regions:
1329                             UniversalRegions {
1330                                 defining_ty: DefiningTy::Const(def_id, _),
1331                                 ..
1332                             },
1333                         ..
1334                     }) = self.borrowck_context
1335                     {
1336                         if tcx.is_static(*def_id) {
1337                             ConstraintCategory::UseAsStatic
1338                         } else {
1339                             ConstraintCategory::UseAsConst
1340                         }
1341                     } else {
1342                         ConstraintCategory::Return
1343                     },
1344                     Place::Base(PlaceBase::Local(l))
1345                         if !mir.local_decls[l].is_user_variable.is_some() => {
1346                         ConstraintCategory::Boring
1347                     }
1348                     _ => ConstraintCategory::Assignment,
1349                 };
1350
1351                 let place_ty = place.ty(mir, tcx).ty;
1352                 let rv_ty = rv.ty(mir, tcx);
1353                 if let Err(terr) =
1354                     self.sub_types_or_anon(rv_ty, place_ty, location.to_locations(), category)
1355                 {
1356                     span_mirbug!(
1357                         self,
1358                         stmt,
1359                         "bad assignment ({:?} = {:?}): {:?}",
1360                         place_ty,
1361                         rv_ty,
1362                         terr
1363                     );
1364                 }
1365
1366                 if let Some(annotation_index) = self.rvalue_user_ty(rv) {
1367                     if let Err(terr) = self.relate_type_and_user_type(
1368                         rv_ty,
1369                         ty::Variance::Invariant,
1370                         &UserTypeProjection { base: annotation_index, projs: vec![], },
1371                         location.to_locations(),
1372                         ConstraintCategory::Boring,
1373                     ) {
1374                         let annotation = &self.user_type_annotations[annotation_index];
1375                         span_mirbug!(
1376                             self,
1377                             stmt,
1378                             "bad user type on rvalue ({:?} = {:?}): {:?}",
1379                             annotation,
1380                             rv_ty,
1381                             terr
1382                         );
1383                     }
1384                 }
1385
1386                 self.check_rvalue(mir, rv, location);
1387                 if !self.tcx().features().unsized_locals {
1388                     let trait_ref = ty::TraitRef {
1389                         def_id: tcx.lang_items().sized_trait().unwrap(),
1390                         substs: tcx.mk_substs_trait(place_ty, &[]),
1391                     };
1392                     self.prove_trait_ref(
1393                         trait_ref,
1394                         location.to_locations(),
1395                         ConstraintCategory::SizedBound,
1396                     );
1397                 }
1398             }
1399             StatementKind::SetDiscriminant {
1400                 ref place,
1401                 variant_index,
1402             } => {
1403                 let place_type = place.ty(mir, tcx).ty;
1404                 let adt = match place_type.sty {
1405                     ty::Adt(adt, _) if adt.is_enum() => adt,
1406                     _ => {
1407                         span_bug!(
1408                             stmt.source_info.span,
1409                             "bad set discriminant ({:?} = {:?}): lhs is not an enum",
1410                             place,
1411                             variant_index
1412                         );
1413                     }
1414                 };
1415                 if variant_index.as_usize() >= adt.variants.len() {
1416                     span_bug!(
1417                         stmt.source_info.span,
1418                         "bad set discriminant ({:?} = {:?}): value of of range",
1419                         place,
1420                         variant_index
1421                     );
1422                 };
1423             }
1424             StatementKind::AscribeUserType(ref place, variance, box ref projection) => {
1425                 let place_ty = place.ty(mir, tcx).ty;
1426                 if let Err(terr) = self.relate_type_and_user_type(
1427                     place_ty,
1428                     variance,
1429                     projection,
1430                     Locations::All(stmt.source_info.span),
1431                     ConstraintCategory::TypeAnnotation,
1432                 ) {
1433                     let annotation = &self.user_type_annotations[projection.base];
1434                     span_mirbug!(
1435                         self,
1436                         stmt,
1437                         "bad type assert ({:?} <: {:?} with projections {:?}): {:?}",
1438                         place_ty,
1439                         annotation,
1440                         projection.projs,
1441                         terr
1442                     );
1443                 }
1444             }
1445             StatementKind::FakeRead(..)
1446             | StatementKind::StorageLive(..)
1447             | StatementKind::StorageDead(..)
1448             | StatementKind::InlineAsm { .. }
1449             | StatementKind::Retag { .. }
1450             | StatementKind::Nop => {}
1451         }
1452     }
1453
1454     fn check_terminator(
1455         &mut self,
1456         mir: &Mir<'tcx>,
1457         term: &Terminator<'tcx>,
1458         term_location: Location,
1459     ) {
1460         debug!("check_terminator: {:?}", term);
1461         let tcx = self.tcx();
1462         match term.kind {
1463             TerminatorKind::Goto { .. }
1464             | TerminatorKind::Resume
1465             | TerminatorKind::Abort
1466             | TerminatorKind::Return
1467             | TerminatorKind::GeneratorDrop
1468             | TerminatorKind::Unreachable
1469             | TerminatorKind::Drop { .. }
1470             | TerminatorKind::FalseEdges { .. }
1471             | TerminatorKind::FalseUnwind { .. } => {
1472                 // no checks needed for these
1473             }
1474
1475             TerminatorKind::DropAndReplace {
1476                 ref location,
1477                 ref value,
1478                 target: _,
1479                 unwind: _,
1480             } => {
1481                 let place_ty = location.ty(mir, tcx).ty;
1482                 let rv_ty = value.ty(mir, tcx);
1483
1484                 let locations = term_location.to_locations();
1485                 if let Err(terr) =
1486                     self.sub_types(rv_ty, place_ty, locations, ConstraintCategory::Assignment)
1487                 {
1488                     span_mirbug!(
1489                         self,
1490                         term,
1491                         "bad DropAndReplace ({:?} = {:?}): {:?}",
1492                         place_ty,
1493                         rv_ty,
1494                         terr
1495                     );
1496                 }
1497             }
1498             TerminatorKind::SwitchInt {
1499                 ref discr,
1500                 switch_ty,
1501                 ..
1502             } => {
1503                 let discr_ty = discr.ty(mir, tcx);
1504                 if let Err(terr) = self.sub_types(
1505                     discr_ty,
1506                     switch_ty,
1507                     term_location.to_locations(),
1508                     ConstraintCategory::Assignment,
1509                 ) {
1510                     span_mirbug!(
1511                         self,
1512                         term,
1513                         "bad SwitchInt ({:?} on {:?}): {:?}",
1514                         switch_ty,
1515                         discr_ty,
1516                         terr
1517                     );
1518                 }
1519                 if !switch_ty.is_integral() && !switch_ty.is_char() && !switch_ty.is_bool() {
1520                     span_mirbug!(self, term, "bad SwitchInt discr ty {:?}", switch_ty);
1521                 }
1522                 // FIXME: check the values
1523             }
1524             TerminatorKind::Call {
1525                 ref func,
1526                 ref args,
1527                 ref destination,
1528                 from_hir_call,
1529                 ..
1530             } => {
1531                 let func_ty = func.ty(mir, tcx);
1532                 debug!("check_terminator: call, func_ty={:?}", func_ty);
1533                 let sig = match func_ty.sty {
1534                     ty::FnDef(..) | ty::FnPtr(_) => func_ty.fn_sig(tcx),
1535                     _ => {
1536                         span_mirbug!(self, term, "call to non-function {:?}", func_ty);
1537                         return;
1538                     }
1539                 };
1540                 let (sig, map) = self.infcx.replace_bound_vars_with_fresh_vars(
1541                     term.source_info.span,
1542                     LateBoundRegionConversionTime::FnCall,
1543                     &sig,
1544                 );
1545                 let sig = self.normalize(sig, term_location);
1546                 self.check_call_dest(mir, term, &sig, destination, term_location);
1547
1548                 self.prove_predicates(
1549                     sig.inputs_and_output.iter().map(|ty| ty::Predicate::WellFormed(ty)),
1550                     term_location.to_locations(),
1551                     ConstraintCategory::Boring,
1552                 );
1553
1554                 // The ordinary liveness rules will ensure that all
1555                 // regions in the type of the callee are live here. We
1556                 // then further constrain the late-bound regions that
1557                 // were instantiated at the call site to be live as
1558                 // well. The resulting is that all the input (and
1559                 // output) types in the signature must be live, since
1560                 // all the inputs that fed into it were live.
1561                 for &late_bound_region in map.values() {
1562                     if let Some(ref mut borrowck_context) = self.borrowck_context {
1563                         let region_vid = borrowck_context
1564                             .universal_regions
1565                             .to_region_vid(late_bound_region);
1566                         borrowck_context
1567                             .constraints
1568                             .liveness_constraints
1569                             .add_element(region_vid, term_location);
1570                     }
1571                 }
1572
1573                 self.check_call_inputs(mir, term, &sig, args, term_location, from_hir_call);
1574             }
1575             TerminatorKind::Assert {
1576                 ref cond, ref msg, ..
1577             } => {
1578                 let cond_ty = cond.ty(mir, tcx);
1579                 if cond_ty != tcx.types.bool {
1580                     span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
1581                 }
1582
1583                 if let BoundsCheck { ref len, ref index } = *msg {
1584                     if len.ty(mir, tcx) != tcx.types.usize {
1585                         span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
1586                     }
1587                     if index.ty(mir, tcx) != tcx.types.usize {
1588                         span_mirbug!(self, index, "bounds-check index non-usize {:?}", index)
1589                     }
1590                 }
1591             }
1592             TerminatorKind::Yield { ref value, .. } => {
1593                 let value_ty = value.ty(mir, tcx);
1594                 match mir.yield_ty {
1595                     None => span_mirbug!(self, term, "yield in non-generator"),
1596                     Some(ty) => {
1597                         if let Err(terr) = self.sub_types(
1598                             value_ty,
1599                             ty,
1600                             term_location.to_locations(),
1601                             ConstraintCategory::Yield,
1602                         ) {
1603                             span_mirbug!(
1604                                 self,
1605                                 term,
1606                                 "type of yield value is {:?}, but the yield type is {:?}: {:?}",
1607                                 value_ty,
1608                                 ty,
1609                                 terr
1610                             );
1611                         }
1612                     }
1613                 }
1614             }
1615         }
1616     }
1617
1618     fn check_call_dest(
1619         &mut self,
1620         mir: &Mir<'tcx>,
1621         term: &Terminator<'tcx>,
1622         sig: &ty::FnSig<'tcx>,
1623         destination: &Option<(Place<'tcx>, BasicBlock)>,
1624         term_location: Location,
1625     ) {
1626         let tcx = self.tcx();
1627         match *destination {
1628             Some((ref dest, _target_block)) => {
1629                 let dest_ty = dest.ty(mir, tcx).ty;
1630                 let category = match *dest {
1631                     Place::Base(PlaceBase::Local(RETURN_PLACE)) => {
1632                         if let Some(BorrowCheckContext {
1633                             universal_regions:
1634                                 UniversalRegions {
1635                                     defining_ty: DefiningTy::Const(def_id, _),
1636                                     ..
1637                                 },
1638                             ..
1639                         }) = self.borrowck_context
1640                         {
1641                             if tcx.is_static(*def_id) {
1642                                 ConstraintCategory::UseAsStatic
1643                             } else {
1644                                 ConstraintCategory::UseAsConst
1645                             }
1646                         } else {
1647                             ConstraintCategory::Return
1648                         }
1649                     }
1650                     Place::Base(PlaceBase::Local(l))
1651                         if !mir.local_decls[l].is_user_variable.is_some() => {
1652                         ConstraintCategory::Boring
1653                     }
1654                     _ => ConstraintCategory::Assignment,
1655                 };
1656
1657                 let locations = term_location.to_locations();
1658
1659                 if let Err(terr) =
1660                     self.sub_types_or_anon(sig.output(), dest_ty, locations, category)
1661                 {
1662                     span_mirbug!(
1663                         self,
1664                         term,
1665                         "call dest mismatch ({:?} <- {:?}): {:?}",
1666                         dest_ty,
1667                         sig.output(),
1668                         terr
1669                     );
1670                 }
1671
1672                 // When `#![feature(unsized_locals)]` is not enabled,
1673                 // this check is done at `check_local`.
1674                 if self.tcx().features().unsized_locals {
1675                     let span = term.source_info.span;
1676                     self.ensure_place_sized(dest_ty, span);
1677                 }
1678             }
1679             None => {
1680                 if !sig.output().conservative_is_privately_uninhabited(self.tcx()) {
1681                     span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
1682                 }
1683             }
1684         }
1685     }
1686
1687     fn check_call_inputs(
1688         &mut self,
1689         mir: &Mir<'tcx>,
1690         term: &Terminator<'tcx>,
1691         sig: &ty::FnSig<'tcx>,
1692         args: &[Operand<'tcx>],
1693         term_location: Location,
1694         from_hir_call: bool,
1695     ) {
1696         debug!("check_call_inputs({:?}, {:?})", sig, args);
1697         // Do not count the `VaList` argument as a "true" argument to
1698         // a C-variadic function.
1699         let inputs = if sig.c_variadic {
1700             &sig.inputs()[..sig.inputs().len() - 1]
1701         } else {
1702             &sig.inputs()[..]
1703         };
1704         if args.len() < inputs.len() || (args.len() > inputs.len() && !sig.c_variadic) {
1705             span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
1706         }
1707         for (n, (fn_arg, op_arg)) in inputs.iter().zip(args).enumerate() {
1708             let op_arg_ty = op_arg.ty(mir, self.tcx());
1709             let category = if from_hir_call {
1710                 ConstraintCategory::CallArgument
1711             } else {
1712                 ConstraintCategory::Boring
1713             };
1714             if let Err(terr) =
1715                 self.sub_types(op_arg_ty, fn_arg, term_location.to_locations(), category)
1716             {
1717                 span_mirbug!(
1718                     self,
1719                     term,
1720                     "bad arg #{:?} ({:?} <- {:?}): {:?}",
1721                     n,
1722                     fn_arg,
1723                     op_arg_ty,
1724                     terr
1725                 );
1726             }
1727         }
1728     }
1729
1730     fn check_iscleanup(&mut self, mir: &Mir<'tcx>, block_data: &BasicBlockData<'tcx>) {
1731         let is_cleanup = block_data.is_cleanup;
1732         self.last_span = block_data.terminator().source_info.span;
1733         match block_data.terminator().kind {
1734             TerminatorKind::Goto { target } => {
1735                 self.assert_iscleanup(mir, block_data, target, is_cleanup)
1736             }
1737             TerminatorKind::SwitchInt { ref targets, .. } => for target in targets {
1738                 self.assert_iscleanup(mir, block_data, *target, is_cleanup);
1739             },
1740             TerminatorKind::Resume => if !is_cleanup {
1741                 span_mirbug!(self, block_data, "resume on non-cleanup block!")
1742             },
1743             TerminatorKind::Abort => if !is_cleanup {
1744                 span_mirbug!(self, block_data, "abort on non-cleanup block!")
1745             },
1746             TerminatorKind::Return => if is_cleanup {
1747                 span_mirbug!(self, block_data, "return on cleanup block")
1748             },
1749             TerminatorKind::GeneratorDrop { .. } => if is_cleanup {
1750                 span_mirbug!(self, block_data, "generator_drop in cleanup block")
1751             },
1752             TerminatorKind::Yield { resume, drop, .. } => {
1753                 if is_cleanup {
1754                     span_mirbug!(self, block_data, "yield in cleanup block")
1755                 }
1756                 self.assert_iscleanup(mir, block_data, resume, is_cleanup);
1757                 if let Some(drop) = drop {
1758                     self.assert_iscleanup(mir, block_data, drop, is_cleanup);
1759                 }
1760             }
1761             TerminatorKind::Unreachable => {}
1762             TerminatorKind::Drop { target, unwind, .. }
1763             | TerminatorKind::DropAndReplace { target, unwind, .. }
1764             | TerminatorKind::Assert {
1765                 target,
1766                 cleanup: unwind,
1767                 ..
1768             } => {
1769                 self.assert_iscleanup(mir, block_data, target, is_cleanup);
1770                 if let Some(unwind) = unwind {
1771                     if is_cleanup {
1772                         span_mirbug!(self, block_data, "unwind on cleanup block")
1773                     }
1774                     self.assert_iscleanup(mir, block_data, unwind, true);
1775                 }
1776             }
1777             TerminatorKind::Call {
1778                 ref destination,
1779                 cleanup,
1780                 ..
1781             } => {
1782                 if let &Some((_, target)) = destination {
1783                     self.assert_iscleanup(mir, block_data, target, is_cleanup);
1784                 }
1785                 if let Some(cleanup) = cleanup {
1786                     if is_cleanup {
1787                         span_mirbug!(self, block_data, "cleanup on cleanup block")
1788                     }
1789                     self.assert_iscleanup(mir, block_data, cleanup, true);
1790                 }
1791             }
1792             TerminatorKind::FalseEdges {
1793                 real_target,
1794                 ref imaginary_targets,
1795             } => {
1796                 self.assert_iscleanup(mir, block_data, real_target, is_cleanup);
1797                 for target in imaginary_targets {
1798                     self.assert_iscleanup(mir, block_data, *target, is_cleanup);
1799                 }
1800             }
1801             TerminatorKind::FalseUnwind {
1802                 real_target,
1803                 unwind,
1804             } => {
1805                 self.assert_iscleanup(mir, block_data, real_target, is_cleanup);
1806                 if let Some(unwind) = unwind {
1807                     if is_cleanup {
1808                         span_mirbug!(
1809                             self,
1810                             block_data,
1811                             "cleanup in cleanup block via false unwind"
1812                         );
1813                     }
1814                     self.assert_iscleanup(mir, block_data, unwind, true);
1815                 }
1816             }
1817         }
1818     }
1819
1820     fn assert_iscleanup(
1821         &mut self,
1822         mir: &Mir<'tcx>,
1823         ctxt: &dyn fmt::Debug,
1824         bb: BasicBlock,
1825         iscleanuppad: bool,
1826     ) {
1827         if mir[bb].is_cleanup != iscleanuppad {
1828             span_mirbug!(
1829                 self,
1830                 ctxt,
1831                 "cleanuppad mismatch: {:?} should be {:?}",
1832                 bb,
1833                 iscleanuppad
1834             );
1835         }
1836     }
1837
1838     fn check_local(&mut self, mir: &Mir<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>) {
1839         match mir.local_kind(local) {
1840             LocalKind::ReturnPointer | LocalKind::Arg => {
1841                 // return values of normal functions are required to be
1842                 // sized by typeck, but return values of ADT constructors are
1843                 // not because we don't include a `Self: Sized` bounds on them.
1844                 //
1845                 // Unbound parts of arguments were never required to be Sized
1846                 // - maybe we should make that a warning.
1847                 return;
1848             }
1849             LocalKind::Var | LocalKind::Temp => {}
1850         }
1851
1852         // When `#![feature(unsized_locals)]` is enabled, only function calls
1853         // and nullary ops are checked in `check_call_dest`.
1854         if !self.tcx().features().unsized_locals {
1855             let span = local_decl.source_info.span;
1856             let ty = local_decl.ty;
1857             self.ensure_place_sized(ty, span);
1858         }
1859     }
1860
1861     fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
1862         let tcx = self.tcx();
1863
1864         // Erase the regions from `ty` to get a global type.  The
1865         // `Sized` bound in no way depends on precise regions, so this
1866         // shouldn't affect `is_sized`.
1867         let gcx = tcx.global_tcx();
1868         let erased_ty = gcx.lift(&tcx.erase_regions(&ty)).unwrap();
1869         if !erased_ty.is_sized(gcx.at(span), self.param_env) {
1870             // in current MIR construction, all non-control-flow rvalue
1871             // expressions evaluate through `as_temp` or `into` a return
1872             // slot or local, so to find all unsized rvalues it is enough
1873             // to check all temps, return slots and locals.
1874             if let None = self.reported_errors.replace((ty, span)) {
1875                 let mut diag = struct_span_err!(
1876                     self.tcx().sess,
1877                     span,
1878                     E0161,
1879                     "cannot move a value of type {0}: the size of {0} \
1880                      cannot be statically determined",
1881                     ty
1882                 );
1883
1884                 // While this is located in `nll::typeck` this error is not
1885                 // an NLL error, it's a required check to prevent creation
1886                 // of unsized rvalues in certain cases:
1887                 // * operand of a box expression
1888                 // * callee in a call expression
1889                 diag.emit();
1890             }
1891         }
1892     }
1893
1894     fn aggregate_field_ty(
1895         &mut self,
1896         ak: &AggregateKind<'tcx>,
1897         field_index: usize,
1898         location: Location,
1899     ) -> Result<Ty<'tcx>, FieldAccessError> {
1900         let tcx = self.tcx();
1901
1902         match *ak {
1903             AggregateKind::Adt(def, variant_index, substs, _, active_field_index) => {
1904                 let variant = &def.variants[variant_index];
1905                 let adj_field_index = active_field_index.unwrap_or(field_index);
1906                 if let Some(field) = variant.fields.get(adj_field_index) {
1907                     Ok(self.normalize(field.ty(tcx, substs), location))
1908                 } else {
1909                     Err(FieldAccessError::OutOfRange {
1910                         field_count: variant.fields.len(),
1911                     })
1912                 }
1913             }
1914             AggregateKind::Closure(def_id, substs) => {
1915                 match substs.upvar_tys(def_id, tcx).nth(field_index) {
1916                     Some(ty) => Ok(ty),
1917                     None => Err(FieldAccessError::OutOfRange {
1918                         field_count: substs.upvar_tys(def_id, tcx).count(),
1919                     }),
1920                 }
1921             }
1922             AggregateKind::Generator(def_id, substs, _) => {
1923                 // It doesn't make sense to look at a field beyond the prefix;
1924                 // these require a variant index, and are not initialized in
1925                 // aggregate rvalues.
1926                 match substs.prefix_tys(def_id, tcx).nth(field_index) {
1927                     Some(ty) => Ok(ty),
1928                     None => Err(FieldAccessError::OutOfRange {
1929                         field_count: substs.prefix_tys(def_id, tcx).count(),
1930                     }),
1931                 }
1932             }
1933             AggregateKind::Array(ty) => Ok(ty),
1934             AggregateKind::Tuple => {
1935                 unreachable!("This should have been covered in check_rvalues");
1936             }
1937         }
1938     }
1939
1940     fn check_rvalue(&mut self, mir: &Mir<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
1941         let tcx = self.tcx();
1942
1943         match rvalue {
1944             Rvalue::Aggregate(ak, ops) => {
1945                 self.check_aggregate_rvalue(mir, rvalue, ak, ops, location)
1946             }
1947
1948             Rvalue::Repeat(operand, len) => if *len > 1 {
1949                 let operand_ty = operand.ty(mir, tcx);
1950
1951                 let trait_ref = ty::TraitRef {
1952                     def_id: tcx.lang_items().copy_trait().unwrap(),
1953                     substs: tcx.mk_substs_trait(operand_ty, &[]),
1954                 };
1955
1956                 self.prove_trait_ref(
1957                     trait_ref,
1958                     location.to_locations(),
1959                     ConstraintCategory::CopyBound,
1960                 );
1961             },
1962
1963             Rvalue::NullaryOp(_, ty) => {
1964                 // Even with unsized locals cannot box an unsized value.
1965                 if self.tcx().features().unsized_locals {
1966                     let span = mir.source_info(location).span;
1967                     self.ensure_place_sized(ty, span);
1968                 }
1969
1970                 let trait_ref = ty::TraitRef {
1971                     def_id: tcx.lang_items().sized_trait().unwrap(),
1972                     substs: tcx.mk_substs_trait(ty, &[]),
1973                 };
1974
1975                 self.prove_trait_ref(
1976                     trait_ref,
1977                     location.to_locations(),
1978                     ConstraintCategory::SizedBound,
1979                 );
1980             }
1981
1982             Rvalue::Cast(cast_kind, op, ty) => {
1983                 match cast_kind {
1984                     CastKind::Pointer(PointerCast::ReifyFnPointer) => {
1985                         let fn_sig = op.ty(mir, tcx).fn_sig(tcx);
1986
1987                         // The type that we see in the fcx is like
1988                         // `foo::<'a, 'b>`, where `foo` is the path to a
1989                         // function definition. When we extract the
1990                         // signature, it comes from the `fn_sig` query,
1991                         // and hence may contain unnormalized results.
1992                         let fn_sig = self.normalize(fn_sig, location);
1993
1994                         let ty_fn_ptr_from = tcx.mk_fn_ptr(fn_sig);
1995
1996                         if let Err(terr) = self.eq_types(
1997                             ty_fn_ptr_from,
1998                             ty,
1999                             location.to_locations(),
2000                             ConstraintCategory::Cast,
2001                         ) {
2002                             span_mirbug!(
2003                                 self,
2004                                 rvalue,
2005                                 "equating {:?} with {:?} yields {:?}",
2006                                 ty_fn_ptr_from,
2007                                 ty,
2008                                 terr
2009                             );
2010                         }
2011                     }
2012
2013                     CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => {
2014                         let sig = match op.ty(mir, tcx).sty {
2015                             ty::Closure(def_id, substs) => {
2016                                 substs.closure_sig_ty(def_id, tcx).fn_sig(tcx)
2017                             }
2018                             _ => bug!(),
2019                         };
2020                         let ty_fn_ptr_from = tcx.coerce_closure_fn_ty(sig, *unsafety);
2021
2022                         if let Err(terr) = self.eq_types(
2023                             ty_fn_ptr_from,
2024                             ty,
2025                             location.to_locations(),
2026                             ConstraintCategory::Cast,
2027                         ) {
2028                             span_mirbug!(
2029                                 self,
2030                                 rvalue,
2031                                 "equating {:?} with {:?} yields {:?}",
2032                                 ty_fn_ptr_from,
2033                                 ty,
2034                                 terr
2035                             );
2036                         }
2037                     }
2038
2039                     CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
2040                         let fn_sig = op.ty(mir, tcx).fn_sig(tcx);
2041
2042                         // The type that we see in the fcx is like
2043                         // `foo::<'a, 'b>`, where `foo` is the path to a
2044                         // function definition. When we extract the
2045                         // signature, it comes from the `fn_sig` query,
2046                         // and hence may contain unnormalized results.
2047                         let fn_sig = self.normalize(fn_sig, location);
2048
2049                         let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);
2050
2051                         if let Err(terr) = self.eq_types(
2052                             ty_fn_ptr_from,
2053                             ty,
2054                             location.to_locations(),
2055                             ConstraintCategory::Cast,
2056                         ) {
2057                             span_mirbug!(
2058                                 self,
2059                                 rvalue,
2060                                 "equating {:?} with {:?} yields {:?}",
2061                                 ty_fn_ptr_from,
2062                                 ty,
2063                                 terr
2064                             );
2065                         }
2066                     }
2067
2068                     CastKind::Pointer(PointerCast::Unsize) => {
2069                         let &ty = ty;
2070                         let trait_ref = ty::TraitRef {
2071                             def_id: tcx.lang_items().coerce_unsized_trait().unwrap(),
2072                             substs: tcx.mk_substs_trait(op.ty(mir, tcx), &[ty.into()]),
2073                         };
2074
2075                         self.prove_trait_ref(
2076                             trait_ref,
2077                             location.to_locations(),
2078                             ConstraintCategory::Cast,
2079                         );
2080                     }
2081
2082                     CastKind::Pointer(PointerCast::MutToConstPointer) => {
2083                         let ty_from = match op.ty(mir, tcx).sty {
2084                             ty::RawPtr(ty::TypeAndMut {
2085                                 ty: ty_from,
2086                                 mutbl: hir::MutMutable,
2087                             }) => ty_from,
2088                             _ => {
2089                                 span_mirbug!(
2090                                     self,
2091                                     rvalue,
2092                                     "unexpected base type for cast {:?}",
2093                                     ty,
2094                                 );
2095                                 return;
2096                             }
2097                         };
2098                         let ty_to = match ty.sty {
2099                             ty::RawPtr(ty::TypeAndMut {
2100                                 ty: ty_to,
2101                                 mutbl: hir::MutImmutable,
2102                             }) => ty_to,
2103                             _ => {
2104                                 span_mirbug!(
2105                                     self,
2106                                     rvalue,
2107                                     "unexpected target type for cast {:?}",
2108                                     ty,
2109                                 );
2110                                 return;
2111                             }
2112                         };
2113                         if let Err(terr) = self.sub_types(
2114                             ty_from,
2115                             ty_to,
2116                             location.to_locations(),
2117                             ConstraintCategory::Cast,
2118                         ) {
2119                             span_mirbug!(
2120                                 self,
2121                                 rvalue,
2122                                 "relating {:?} with {:?} yields {:?}",
2123                                 ty_from,
2124                                 ty_to,
2125                                 terr
2126                             )
2127                         }
2128                     }
2129
2130                     CastKind::Misc => {
2131                         if let ty::Ref(_, mut ty_from, _) = op.ty(mir, tcx).sty {
2132                             let (mut ty_to, mutability) = if let ty::RawPtr(ty::TypeAndMut {
2133                                 ty: ty_to,
2134                                 mutbl,
2135                             }) = ty.sty {
2136                                 (ty_to, mutbl)
2137                             } else {
2138                                 span_mirbug!(
2139                                     self,
2140                                     rvalue,
2141                                     "invalid cast types {:?} -> {:?}",
2142                                     op.ty(mir, tcx),
2143                                     ty,
2144                                 );
2145                                 return;
2146                             };
2147
2148                             // Handle the direct cast from `&[T; N]` to `*const T` by unwrapping
2149                             // any array we find.
2150                             while let ty::Array(ty_elem_from, _) = ty_from.sty {
2151                                 ty_from = ty_elem_from;
2152                                 if let ty::Array(ty_elem_to, _) = ty_to.sty {
2153                                     ty_to = ty_elem_to;
2154                                 } else {
2155                                     break;
2156                                 }
2157                             }
2158
2159                             if let hir::MutMutable = mutability {
2160                                 if let Err(terr) = self.eq_types(
2161                                     ty_from,
2162                                     ty_to,
2163                                     location.to_locations(),
2164                                     ConstraintCategory::Cast,
2165                                 ) {
2166                                     span_mirbug!(
2167                                         self,
2168                                         rvalue,
2169                                         "equating {:?} with {:?} yields {:?}",
2170                                         ty_from,
2171                                         ty_to,
2172                                         terr
2173                                     )
2174                                 }
2175                             } else {
2176                                 if let Err(terr) = self.sub_types(
2177                                     ty_from,
2178                                     ty_to,
2179                                     location.to_locations(),
2180                                     ConstraintCategory::Cast,
2181                                 ) {
2182                                     span_mirbug!(
2183                                         self,
2184                                         rvalue,
2185                                         "relating {:?} with {:?} yields {:?}",
2186                                         ty_from,
2187                                         ty_to,
2188                                         terr
2189                                     )
2190                                 }
2191                             }
2192                         }
2193                     }
2194                 }
2195             }
2196
2197             Rvalue::Ref(region, _borrow_kind, borrowed_place) => {
2198                 self.add_reborrow_constraint(mir, location, region, borrowed_place);
2199             }
2200
2201             Rvalue::BinaryOp(BinOp::Eq, left, right)
2202             | Rvalue::BinaryOp(BinOp::Ne, left, right)
2203             | Rvalue::BinaryOp(BinOp::Lt, left, right)
2204             | Rvalue::BinaryOp(BinOp::Le, left, right)
2205             | Rvalue::BinaryOp(BinOp::Gt, left, right)
2206             | Rvalue::BinaryOp(BinOp::Ge, left, right) => {
2207                 let ty_left = left.ty(mir, tcx);
2208                 if let ty::RawPtr(_) | ty::FnPtr(_) = ty_left.sty {
2209                     let ty_right = right.ty(mir, tcx);
2210                     let common_ty = self.infcx.next_ty_var(
2211                         TypeVariableOrigin::MiscVariable(mir.source_info(location).span),
2212                     );
2213                     self.sub_types(
2214                         common_ty,
2215                         ty_left,
2216                         location.to_locations(),
2217                         ConstraintCategory::Boring
2218                     ).unwrap_or_else(|err| {
2219                         bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
2220                     });
2221                     if let Err(terr) = self.sub_types(
2222                         common_ty,
2223                         ty_right,
2224                         location.to_locations(),
2225                         ConstraintCategory::Boring
2226                     ) {
2227                         span_mirbug!(
2228                             self,
2229                             rvalue,
2230                             "unexpected comparison types {:?} and {:?} yields {:?}",
2231                             ty_left,
2232                             ty_right,
2233                             terr
2234                         )
2235                     }
2236                 }
2237             }
2238
2239             Rvalue::Use(..)
2240             | Rvalue::Len(..)
2241             | Rvalue::BinaryOp(..)
2242             | Rvalue::CheckedBinaryOp(..)
2243             | Rvalue::UnaryOp(..)
2244             | Rvalue::Discriminant(..) => {}
2245         }
2246     }
2247
2248     /// If this rvalue supports a user-given type annotation, then
2249     /// extract and return it. This represents the final type of the
2250     /// rvalue and will be unified with the inferred type.
2251     fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<UserTypeAnnotationIndex> {
2252         match rvalue {
2253             Rvalue::Use(_)
2254             | Rvalue::Repeat(..)
2255             | Rvalue::Ref(..)
2256             | Rvalue::Len(..)
2257             | Rvalue::Cast(..)
2258             | Rvalue::BinaryOp(..)
2259             | Rvalue::CheckedBinaryOp(..)
2260             | Rvalue::NullaryOp(..)
2261             | Rvalue::UnaryOp(..)
2262             | Rvalue::Discriminant(..) => None,
2263
2264             Rvalue::Aggregate(aggregate, _) => match **aggregate {
2265                 AggregateKind::Adt(_, _, _, user_ty, _) => user_ty,
2266                 AggregateKind::Array(_) => None,
2267                 AggregateKind::Tuple => None,
2268                 AggregateKind::Closure(_, _) => None,
2269                 AggregateKind::Generator(_, _, _) => None,
2270             },
2271         }
2272     }
2273
2274     fn check_aggregate_rvalue(
2275         &mut self,
2276         mir: &Mir<'tcx>,
2277         rvalue: &Rvalue<'tcx>,
2278         aggregate_kind: &AggregateKind<'tcx>,
2279         operands: &[Operand<'tcx>],
2280         location: Location,
2281     ) {
2282         let tcx = self.tcx();
2283
2284         self.prove_aggregate_predicates(aggregate_kind, location);
2285
2286         if *aggregate_kind == AggregateKind::Tuple {
2287             // tuple rvalue field type is always the type of the op. Nothing to check here.
2288             return;
2289         }
2290
2291         for (i, operand) in operands.iter().enumerate() {
2292             let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
2293                 Ok(field_ty) => field_ty,
2294                 Err(FieldAccessError::OutOfRange { field_count }) => {
2295                     span_mirbug!(
2296                         self,
2297                         rvalue,
2298                         "accessed field #{} but variant only has {}",
2299                         i,
2300                         field_count
2301                     );
2302                     continue;
2303                 }
2304             };
2305             let operand_ty = operand.ty(mir, tcx);
2306
2307             if let Err(terr) = self.sub_types(
2308                 operand_ty,
2309                 field_ty,
2310                 location.to_locations(),
2311                 ConstraintCategory::Boring,
2312             ) {
2313                 span_mirbug!(
2314                     self,
2315                     rvalue,
2316                     "{:?} is not a subtype of {:?}: {:?}",
2317                     operand_ty,
2318                     field_ty,
2319                     terr
2320                 );
2321             }
2322         }
2323     }
2324
2325     /// Adds the constraints that arise from a borrow expression `&'a P` at the location `L`.
2326     ///
2327     /// # Parameters
2328     ///
2329     /// - `location`: the location `L` where the borrow expression occurs
2330     /// - `borrow_region`: the region `'a` associated with the borrow
2331     /// - `borrowed_place`: the place `P` being borrowed
2332     fn add_reborrow_constraint(
2333         &mut self,
2334         mir: &Mir<'tcx>,
2335         location: Location,
2336         borrow_region: ty::Region<'tcx>,
2337         borrowed_place: &Place<'tcx>,
2338     ) {
2339         // These constraints are only meaningful during borrowck:
2340         let BorrowCheckContext {
2341             borrow_set,
2342             location_table,
2343             all_facts,
2344             constraints,
2345             ..
2346         } = match self.borrowck_context {
2347             Some(ref mut borrowck_context) => borrowck_context,
2348             None => return,
2349         };
2350
2351         // In Polonius mode, we also push a `borrow_region` fact
2352         // linking the loan to the region (in some cases, though,
2353         // there is no loan associated with this borrow expression --
2354         // that occurs when we are borrowing an unsafe place, for
2355         // example).
2356         if let Some(all_facts) = all_facts {
2357             if let Some(borrow_index) = borrow_set.location_map.get(&location) {
2358                 let region_vid = borrow_region.to_region_vid();
2359                 all_facts.borrow_region.push((
2360                     region_vid,
2361                     *borrow_index,
2362                     location_table.mid_index(location),
2363                 ));
2364             }
2365         }
2366
2367         // If we are reborrowing the referent of another reference, we
2368         // need to add outlives relationships. In a case like `&mut
2369         // *p`, where the `p` has type `&'b mut Foo`, for example, we
2370         // need to ensure that `'b: 'a`.
2371
2372         let mut borrowed_place = borrowed_place;
2373
2374         debug!(
2375             "add_reborrow_constraint({:?}, {:?}, {:?})",
2376             location, borrow_region, borrowed_place
2377         );
2378         while let Place::Projection(box PlaceProjection { base, elem }) = borrowed_place {
2379             debug!("add_reborrow_constraint - iteration {:?}", borrowed_place);
2380
2381             match *elem {
2382                 ProjectionElem::Deref => {
2383                     let tcx = self.infcx.tcx;
2384                     let base_ty = base.ty(mir, tcx).ty;
2385
2386                     debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
2387                     match base_ty.sty {
2388                         ty::Ref(ref_region, _, mutbl) => {
2389                             constraints.outlives_constraints.push(OutlivesConstraint {
2390                                 sup: ref_region.to_region_vid(),
2391                                 sub: borrow_region.to_region_vid(),
2392                                 locations: location.to_locations(),
2393                                 category: ConstraintCategory::Boring,
2394                             });
2395
2396                             match mutbl {
2397                                 hir::Mutability::MutImmutable => {
2398                                     // Immutable reference. We don't need the base
2399                                     // to be valid for the entire lifetime of
2400                                     // the borrow.
2401                                     break;
2402                                 }
2403                                 hir::Mutability::MutMutable => {
2404                                     // Mutable reference. We *do* need the base
2405                                     // to be valid, because after the base becomes
2406                                     // invalid, someone else can use our mutable deref.
2407
2408                                     // This is in order to make the following function
2409                                     // illegal:
2410                                     // ```
2411                                     // fn unsafe_deref<'a, 'b>(x: &'a &'b mut T) -> &'b mut T {
2412                                     //     &mut *x
2413                                     // }
2414                                     // ```
2415                                     //
2416                                     // As otherwise you could clone `&mut T` using the
2417                                     // following function:
2418                                     // ```
2419                                     // fn bad(x: &mut T) -> (&mut T, &mut T) {
2420                                     //     let my_clone = unsafe_deref(&'a x);
2421                                     //     ENDREGION 'a;
2422                                     //     (my_clone, x)
2423                                     // }
2424                                     // ```
2425                                 }
2426                             }
2427                         }
2428                         ty::RawPtr(..) => {
2429                             // deref of raw pointer, guaranteed to be valid
2430                             break;
2431                         }
2432                         ty::Adt(def, _) if def.is_box() => {
2433                             // deref of `Box`, need the base to be valid - propagate
2434                         }
2435                         _ => bug!("unexpected deref ty {:?} in {:?}", base_ty, borrowed_place),
2436                     }
2437                 }
2438                 ProjectionElem::Field(..)
2439                 | ProjectionElem::Downcast(..)
2440                 | ProjectionElem::Index(..)
2441                 | ProjectionElem::ConstantIndex { .. }
2442                 | ProjectionElem::Subslice { .. } => {
2443                     // other field access
2444                 }
2445             }
2446
2447             // The "propagate" case. We need to check that our base is valid
2448             // for the borrow's lifetime.
2449             borrowed_place = base;
2450         }
2451     }
2452
2453     fn prove_aggregate_predicates(
2454         &mut self,
2455         aggregate_kind: &AggregateKind<'tcx>,
2456         location: Location,
2457     ) {
2458         let tcx = self.tcx();
2459
2460         debug!(
2461             "prove_aggregate_predicates(aggregate_kind={:?}, location={:?})",
2462             aggregate_kind, location
2463         );
2464
2465         let instantiated_predicates = match aggregate_kind {
2466             AggregateKind::Adt(def, _, substs, _, _) => {
2467                 tcx.predicates_of(def.did).instantiate(tcx, substs)
2468             }
2469
2470             // For closures, we have some **extra requirements** we
2471             //
2472             // have to check. In particular, in their upvars and
2473             // signatures, closures often reference various regions
2474             // from the surrounding function -- we call those the
2475             // closure's free regions. When we borrow-check (and hence
2476             // region-check) closures, we may find that the closure
2477             // requires certain relationships between those free
2478             // regions. However, because those free regions refer to
2479             // portions of the CFG of their caller, the closure is not
2480             // in a position to verify those relationships. In that
2481             // case, the requirements get "propagated" to us, and so
2482             // we have to solve them here where we instantiate the
2483             // closure.
2484             //
2485             // Despite the opacity of the previous parapgrah, this is
2486             // actually relatively easy to understand in terms of the
2487             // desugaring. A closure gets desugared to a struct, and
2488             // these extra requirements are basically like where
2489             // clauses on the struct.
2490             AggregateKind::Closure(def_id, ty::ClosureSubsts { substs })
2491             | AggregateKind::Generator(def_id, ty::GeneratorSubsts { substs }, _) => {
2492                 self.prove_closure_bounds(tcx, *def_id, substs, location)
2493             }
2494
2495             AggregateKind::Array(_) | AggregateKind::Tuple => ty::InstantiatedPredicates::empty(),
2496         };
2497
2498         self.normalize_and_prove_instantiated_predicates(
2499             instantiated_predicates,
2500             location.to_locations(),
2501         );
2502     }
2503
2504     fn prove_closure_bounds(
2505         &mut self,
2506         tcx: TyCtxt<'a, 'gcx, 'tcx>,
2507         def_id: DefId,
2508         substs: SubstsRef<'tcx>,
2509         location: Location,
2510     ) -> ty::InstantiatedPredicates<'tcx> {
2511         if let Some(closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements {
2512             let closure_constraints =
2513                 closure_region_requirements.apply_requirements(tcx, def_id, substs);
2514
2515             if let Some(ref mut borrowck_context) = self.borrowck_context {
2516                 let bounds_mapping = closure_constraints
2517                     .iter()
2518                     .enumerate()
2519                     .filter_map(|(idx, constraint)| {
2520                         let ty::OutlivesPredicate(k1, r2) =
2521                             constraint.no_bound_vars().unwrap_or_else(|| {
2522                                 bug!("query_constraint {:?} contained bound vars", constraint,);
2523                             });
2524
2525                         match k1.unpack() {
2526                             UnpackedKind::Lifetime(r1) => {
2527                                 // constraint is r1: r2
2528                                 let r1_vid = borrowck_context.universal_regions.to_region_vid(r1);
2529                                 let r2_vid = borrowck_context.universal_regions.to_region_vid(r2);
2530                                 let outlives_requirements =
2531                                     &closure_region_requirements.outlives_requirements[idx];
2532                                 Some((
2533                                     (r1_vid, r2_vid),
2534                                     (
2535                                         outlives_requirements.category,
2536                                         outlives_requirements.blame_span,
2537                                     ),
2538                                 ))
2539                             }
2540                             UnpackedKind::Type(_) | UnpackedKind::Const(_) => None,
2541                         }
2542                     })
2543                     .collect();
2544
2545                 let existing = borrowck_context
2546                     .constraints
2547                     .closure_bounds_mapping
2548                     .insert(location, bounds_mapping);
2549                 assert!(
2550                     existing.is_none(),
2551                     "Multiple closures at the same location."
2552                 );
2553             }
2554
2555             self.push_region_constraints(
2556                 location.to_locations(),
2557                 ConstraintCategory::ClosureBounds,
2558                 &closure_constraints,
2559             );
2560         }
2561
2562         tcx.predicates_of(def_id).instantiate(tcx, substs)
2563     }
2564
2565     fn prove_trait_ref(
2566         &mut self,
2567         trait_ref: ty::TraitRef<'tcx>,
2568         locations: Locations,
2569         category: ConstraintCategory,
2570     ) {
2571         self.prove_predicates(
2572             Some(ty::Predicate::Trait(
2573                 trait_ref.to_poly_trait_ref().to_poly_trait_predicate(),
2574             )),
2575             locations,
2576             category,
2577         );
2578     }
2579
2580     fn normalize_and_prove_instantiated_predicates(
2581         &mut self,
2582         instantiated_predicates: ty::InstantiatedPredicates<'tcx>,
2583         locations: Locations,
2584     ) {
2585         for predicate in instantiated_predicates.predicates {
2586             let predicate = self.normalize(predicate, locations);
2587             self.prove_predicate(predicate, locations, ConstraintCategory::Boring);
2588         }
2589     }
2590
2591     fn prove_predicates(
2592         &mut self,
2593         predicates: impl IntoIterator<Item = ty::Predicate<'tcx>>,
2594         locations: Locations,
2595         category: ConstraintCategory,
2596     ) {
2597         for predicate in predicates {
2598             debug!(
2599                 "prove_predicates(predicate={:?}, locations={:?})",
2600                 predicate, locations,
2601             );
2602
2603             self.prove_predicate(predicate, locations, category);
2604         }
2605     }
2606
2607     fn prove_predicate(
2608         &mut self,
2609         predicate: ty::Predicate<'tcx>,
2610         locations: Locations,
2611         category: ConstraintCategory,
2612     ) {
2613         debug!(
2614             "prove_predicate(predicate={:?}, location={:?})",
2615             predicate, locations,
2616         );
2617
2618         let param_env = self.param_env;
2619         self.fully_perform_op(
2620             locations,
2621             category,
2622             param_env.and(type_op::prove_predicate::ProvePredicate::new(predicate)),
2623         ).unwrap_or_else(|NoSolution| {
2624             span_mirbug!(self, NoSolution, "could not prove {:?}", predicate);
2625         })
2626     }
2627
2628     fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
2629         self.last_span = mir.span;
2630         debug!("run_on_mir: {:?}", mir.span);
2631
2632         for (local, local_decl) in mir.local_decls.iter_enumerated() {
2633             self.check_local(mir, local, local_decl);
2634         }
2635
2636         for (block, block_data) in mir.basic_blocks().iter_enumerated() {
2637             let mut location = Location {
2638                 block,
2639                 statement_index: 0,
2640             };
2641             for stmt in &block_data.statements {
2642                 if !stmt.source_info.span.is_dummy() {
2643                     self.last_span = stmt.source_info.span;
2644                 }
2645                 self.check_stmt(mir, stmt, location);
2646                 location.statement_index += 1;
2647             }
2648
2649             self.check_terminator(mir, block_data.terminator(), location);
2650             self.check_iscleanup(mir, block_data);
2651         }
2652     }
2653
2654     fn normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T
2655     where
2656         T: type_op::normalize::Normalizable<'gcx, 'tcx> + Copy,
2657     {
2658         debug!("normalize(value={:?}, location={:?})", value, location);
2659         let param_env = self.param_env;
2660         self.fully_perform_op(
2661             location.to_locations(),
2662             ConstraintCategory::Boring,
2663             param_env.and(type_op::normalize::Normalize::new(value)),
2664         ).unwrap_or_else(|NoSolution| {
2665             span_mirbug!(self, NoSolution, "failed to normalize `{:?}`", value);
2666             value
2667         })
2668     }
2669 }
2670
2671 pub struct TypeckMir;
2672
2673 impl MirPass for TypeckMir {
2674     fn run_pass<'a, 'tcx>(
2675         &self,
2676         tcx: TyCtxt<'a, 'tcx, 'tcx>,
2677         src: MirSource<'tcx>,
2678         mir: &mut Mir<'tcx>,
2679     ) {
2680         let def_id = src.def_id();
2681         debug!("run_pass: {:?}", def_id);
2682
2683         // FIXME: We don't need this MIR pass anymore.
2684         if true {
2685             return;
2686         }
2687
2688         if tcx.sess.err_count() > 0 {
2689             // compiling a broken program can obviously result in a
2690             // broken MIR, so try not to report duplicate errors.
2691             return;
2692         }
2693
2694         if tcx.is_constructor(def_id) {
2695             // We just assume that the automatically generated struct/variant constructors are
2696             // correct. See the comment in the `mir_borrowck` implementation for an
2697             // explanation why we need this.
2698             return;
2699         }
2700
2701         let param_env = tcx.param_env(def_id);
2702         tcx.infer_ctxt().enter(|infcx| {
2703             type_check_internal(
2704                 &infcx,
2705                 def_id,
2706                 param_env,
2707                 mir,
2708                 &vec![],
2709                 None,
2710                 None,
2711                 None,
2712                 |_| (),
2713             );
2714
2715             // For verification purposes, we just ignore the resulting
2716             // region constraint sets. Not our problem. =)
2717         });
2718     }
2719 }
2720
2721 trait NormalizeLocation: fmt::Debug + Copy {
2722     fn to_locations(self) -> Locations;
2723 }
2724
2725 impl NormalizeLocation for Locations {
2726     fn to_locations(self) -> Locations {
2727         self
2728     }
2729 }
2730
2731 impl NormalizeLocation for Location {
2732     fn to_locations(self) -> Locations {
2733         Locations::Single(self)
2734     }
2735 }
2736
2737 #[derive(Debug, Default)]
2738 struct ObligationAccumulator<'tcx> {
2739     obligations: PredicateObligations<'tcx>,
2740 }
2741
2742 impl<'tcx> ObligationAccumulator<'tcx> {
2743     fn add<T>(&mut self, value: InferOk<'tcx, T>) -> T {
2744         let InferOk { value, obligations } = value;
2745         self.obligations.extend(obligations);
2746         value
2747     }
2748
2749     fn into_vec(self) -> PredicateObligations<'tcx> {
2750         self.obligations
2751     }
2752 }