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