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