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