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