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