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