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