]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_mir/src/borrow_check/type_check/mod.rs
use exhaustive match for checking Rvalue::Repeat
[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,
48     promote_consts::should_suggest_const_in_array_repeat_expressions_attribute,
49 };
50
51 use crate::borrow_check::{
52     borrow_set::BorrowSet,
53     constraints::{OutlivesConstraint, OutlivesConstraintSet},
54     facts::AllFacts,
55     location::LocationTable,
56     member_constraints::MemberConstraintSet,
57     nll::ToRegionVid,
58     path_utils,
59     region_infer::values::{
60         LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements,
61     },
62     region_infer::{ClosureRegionRequirementsExt, TypeTest},
63     renumber,
64     type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
65     universal_regions::{DefiningTy, UniversalRegions},
66     Upvar,
67 };
68
69 macro_rules! span_mirbug {
70     ($context:expr, $elem:expr, $($message:tt)*) => ({
71         $crate::borrow_check::type_check::mirbug(
72             $context.tcx(),
73             $context.last_span,
74             &format!(
75                 "broken MIR in {:?} ({:?}): {}",
76                 $context.body.source.def_id(),
77                 $elem,
78                 format_args!($($message)*),
79             ),
80         )
81     })
82 }
83
84 macro_rules! span_mirbug_and_err {
85     ($context:expr, $elem:expr, $($message:tt)*) => ({
86         {
87             span_mirbug!($context, $elem, $($message)*);
88             $context.error()
89         }
90     })
91 }
92
93 mod constraint_conversion;
94 pub mod free_region_relations;
95 mod input_output;
96 crate mod liveness;
97 mod relate_tys;
98
99 /// Type checks the given `mir` in the context of the inference
100 /// context `infcx`. Returns any region constraints that have yet to
101 /// be proven. This result is includes liveness constraints that
102 /// ensure that regions appearing in the types of all local variables
103 /// are live at all points where that local variable may later be
104 /// used.
105 ///
106 /// This phase of type-check ought to be infallible -- this is because
107 /// the original, HIR-based type-check succeeded. So if any errors
108 /// occur here, we will get a `bug!` reported.
109 ///
110 /// # Parameters
111 ///
112 /// - `infcx` -- inference context to use
113 /// - `param_env` -- parameter environment to use for trait solving
114 /// - `body` -- MIR body to type-check
115 /// - `promoted` -- map of promoted constants within `body`
116 /// - `universal_regions` -- the universal regions from `body`s function signature
117 /// - `location_table` -- MIR location map of `body`
118 /// - `borrow_set` -- information about borrows occurring in `body`
119 /// - `all_facts` -- when using Polonius, this is the generated set of Polonius facts
120 /// - `flow_inits` -- results of a maybe-init dataflow analysis
121 /// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
122 /// - `elements` -- MIR region map
123 pub(crate) fn type_check<'mir, 'tcx>(
124     infcx: &InferCtxt<'_, 'tcx>,
125     param_env: ty::ParamEnv<'tcx>,
126     body: &Body<'tcx>,
127     promoted: &IndexVec<Promoted, Body<'tcx>>,
128     universal_regions: &Rc<UniversalRegions<'tcx>>,
129     location_table: &LocationTable,
130     borrow_set: &BorrowSet<'tcx>,
131     all_facts: &mut Option<AllFacts>,
132     flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
133     move_data: &MoveData<'tcx>,
134     elements: &Rc<RegionValueElements>,
135     upvars: &[Upvar],
136 ) -> MirTypeckResults<'tcx> {
137     let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
138     let mut constraints = MirTypeckRegionConstraints {
139         placeholder_indices: PlaceholderIndices::default(),
140         placeholder_index_to_region: IndexVec::default(),
141         liveness_constraints: LivenessValues::new(elements.clone()),
142         outlives_constraints: OutlivesConstraintSet::default(),
143         member_constraints: MemberConstraintSet::default(),
144         closure_bounds_mapping: Default::default(),
145         type_tests: Vec::default(),
146     };
147
148     let CreateResult {
149         universal_region_relations,
150         region_bound_pairs,
151         normalized_inputs_and_output,
152     } = free_region_relations::create(
153         infcx,
154         param_env,
155         Some(implicit_region_bound),
156         universal_regions,
157         &mut constraints,
158     );
159
160     let mut borrowck_context = BorrowCheckContext {
161         universal_regions,
162         location_table,
163         borrow_set,
164         all_facts,
165         constraints: &mut constraints,
166         upvars,
167     };
168
169     let opaque_type_values = type_check_internal(
170         infcx,
171         param_env,
172         body,
173         promoted,
174         &region_bound_pairs,
175         implicit_region_bound,
176         &mut borrowck_context,
177         &universal_region_relations,
178         |mut cx| {
179             cx.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output);
180             liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);
181
182             translate_outlives_facts(&mut cx);
183             cx.opaque_type_values
184         },
185     );
186
187     MirTypeckResults { constraints, universal_region_relations, opaque_type_values }
188 }
189
190 fn type_check_internal<'a, 'tcx, R>(
191     infcx: &'a InferCtxt<'a, 'tcx>,
192     param_env: ty::ParamEnv<'tcx>,
193     body: &'a Body<'tcx>,
194     promoted: &'a IndexVec<Promoted, Body<'tcx>>,
195     region_bound_pairs: &'a RegionBoundPairs<'tcx>,
196     implicit_region_bound: ty::Region<'tcx>,
197     borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
198     universal_region_relations: &'a UniversalRegionRelations<'tcx>,
199     extra: impl FnOnce(TypeChecker<'a, 'tcx>) -> R,
200 ) -> R {
201     let mut checker = TypeChecker::new(
202         infcx,
203         body,
204         param_env,
205         region_bound_pairs,
206         implicit_region_bound,
207         borrowck_context,
208         universal_region_relations,
209     );
210     let errors_reported = {
211         let mut verifier = TypeVerifier::new(&mut checker, body, promoted);
212         verifier.visit_body(&body);
213         verifier.errors_reported
214     };
215
216     if !errors_reported {
217         // if verifier failed, don't do further checks to avoid ICEs
218         checker.typeck_mir(body);
219     }
220
221     extra(checker)
222 }
223
224 fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) {
225     let cx = &mut typeck.borrowck_context;
226     if let Some(facts) = cx.all_facts {
227         let _prof_timer = typeck.infcx.tcx.prof.generic_activity("polonius_fact_generation");
228         let location_table = cx.location_table;
229         facts.outlives.extend(cx.constraints.outlives_constraints.outlives().iter().flat_map(
230             |constraint: &OutlivesConstraint| {
231                 if let Some(from_location) = constraint.locations.from_location() {
232                     Either::Left(iter::once((
233                         constraint.sup,
234                         constraint.sub,
235                         location_table.mid_index(from_location),
236                     )))
237                 } else {
238                     Either::Right(
239                         location_table
240                             .all_points()
241                             .map(move |location| (constraint.sup, constraint.sub, location)),
242                     )
243                 }
244             },
245         ));
246     }
247 }
248
249 fn mirbug(tcx: TyCtxt<'_>, span: Span, msg: &str) {
250     // We sometimes see MIR failures (notably predicate failures) due to
251     // the fact that we check rvalue sized predicates here. So use `delay_span_bug`
252     // to avoid reporting bugs in those cases.
253     tcx.sess.diagnostic().delay_span_bug(span, msg);
254 }
255
256 enum FieldAccessError {
257     OutOfRange { field_count: usize },
258 }
259
260 /// Verifies that MIR types are sane to not crash further checks.
261 ///
262 /// The sanitize_XYZ methods here take an MIR object and compute its
263 /// type, calling `span_mirbug` and returning an error type if there
264 /// is a problem.
265 struct TypeVerifier<'a, 'b, 'tcx> {
266     cx: &'a mut TypeChecker<'b, 'tcx>,
267     body: &'b Body<'tcx>,
268     promoted: &'b IndexVec<Promoted, Body<'tcx>>,
269     last_span: Span,
270     errors_reported: bool,
271 }
272
273 impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
274     fn visit_span(&mut self, span: &Span) {
275         if !span.is_dummy() {
276             self.last_span = *span;
277         }
278     }
279
280     fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
281         self.sanitize_place(place, location, context);
282     }
283
284     fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
285         self.super_constant(constant, location);
286         let ty = self.sanitize_type(constant, constant.literal.ty);
287
288         self.cx.infcx.tcx.for_each_free_region(&ty, |live_region| {
289             let live_region_vid =
290                 self.cx.borrowck_context.universal_regions.to_region_vid(live_region);
291             self.cx
292                 .borrowck_context
293                 .constraints
294                 .liveness_constraints
295                 .add_element(live_region_vid, location);
296         });
297
298         if let Some(annotation_index) = constant.user_ty {
299             if let Err(terr) = self.cx.relate_type_and_user_type(
300                 constant.literal.ty,
301                 ty::Variance::Invariant,
302                 &UserTypeProjection { base: annotation_index, projs: vec![] },
303                 location.to_locations(),
304                 ConstraintCategory::Boring,
305             ) {
306                 let annotation = &self.cx.user_type_annotations[annotation_index];
307                 span_mirbug!(
308                     self,
309                     constant,
310                     "bad constant user type {:?} vs {:?}: {:?}",
311                     annotation,
312                     constant.literal.ty,
313                     terr,
314                 );
315             }
316         } else {
317             let tcx = self.tcx();
318             if let ty::ConstKind::Unevaluated(def, substs, promoted) = constant.literal.val {
319                 if let Some(promoted) = promoted {
320                     let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
321                                      promoted: &Body<'tcx>,
322                                      ty,
323                                      san_ty| {
324                         if let Err(terr) = verifier.cx.eq_types(
325                             san_ty,
326                             ty,
327                             location.to_locations(),
328                             ConstraintCategory::Boring,
329                         ) {
330                             span_mirbug!(
331                                 verifier,
332                                 promoted,
333                                 "bad promoted type ({:?}: {:?}): {:?}",
334                                 ty,
335                                 san_ty,
336                                 terr
337                             );
338                         };
339                     };
340
341                     if !self.errors_reported {
342                         let promoted_body = &self.promoted[promoted];
343                         self.sanitize_promoted(promoted_body, location);
344
345                         let promoted_ty = promoted_body.return_ty();
346                         check_err(self, promoted_body, ty, promoted_ty);
347                     }
348                 } else {
349                     if let Err(terr) = self.cx.fully_perform_op(
350                         location.to_locations(),
351                         ConstraintCategory::Boring,
352                         self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
353                             constant.literal.ty,
354                             def.did,
355                             UserSubsts { substs, user_self_ty: None },
356                         )),
357                     ) {
358                         span_mirbug!(
359                             self,
360                             constant,
361                             "bad constant type {:?} ({:?})",
362                             constant,
363                             terr
364                         );
365                     }
366                 }
367             } else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
368                 let unnormalized_ty = tcx.type_of(static_def_id);
369                 let locations = location.to_locations();
370                 let normalized_ty = self.cx.normalize(unnormalized_ty, locations);
371                 let literal_ty = constant.literal.ty.builtin_deref(true).unwrap().ty;
372
373                 if let Err(terr) = self.cx.eq_types(
374                     normalized_ty,
375                     literal_ty,
376                     locations,
377                     ConstraintCategory::Boring,
378                 ) {
379                     span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr);
380                 }
381             }
382
383             if let ty::FnDef(def_id, substs) = *constant.literal.ty.kind() {
384                 let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
385                 self.cx.normalize_and_prove_instantiated_predicates(
386                     instantiated_predicates,
387                     location.to_locations(),
388                 );
389             }
390         }
391     }
392
393     fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
394         self.super_rvalue(rvalue, location);
395         let rval_ty = rvalue.ty(self.body, self.tcx());
396         self.sanitize_type(rvalue, rval_ty);
397     }
398
399     fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
400         self.super_local_decl(local, local_decl);
401         self.sanitize_type(local_decl, local_decl.ty);
402
403         if let Some(user_ty) = &local_decl.user_ty {
404             for (user_ty, span) in user_ty.projections_and_spans() {
405                 let ty = if !local_decl.is_nonref_binding() {
406                     // If we have a binding of the form `let ref x: T = ..`
407                     // then remove the outermost reference so we can check the
408                     // type annotation for the remaining type.
409                     if let ty::Ref(_, rty, _) = local_decl.ty.kind() {
410                         rty
411                     } else {
412                         bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty);
413                     }
414                 } else {
415                     local_decl.ty
416                 };
417
418                 if let Err(terr) = self.cx.relate_type_and_user_type(
419                     ty,
420                     ty::Variance::Invariant,
421                     user_ty,
422                     Locations::All(*span),
423                     ConstraintCategory::TypeAnnotation,
424                 ) {
425                     span_mirbug!(
426                         self,
427                         local,
428                         "bad user type on variable {:?}: {:?} != {:?} ({:?})",
429                         local,
430                         local_decl.ty,
431                         local_decl.user_ty,
432                         terr,
433                     );
434                 }
435             }
436         }
437     }
438
439     fn visit_body(&mut self, body: &Body<'tcx>) {
440         self.sanitize_type(&"return type", body.return_ty());
441         for local_decl in &body.local_decls {
442             self.sanitize_type(local_decl, local_decl.ty);
443         }
444         if self.errors_reported {
445             return;
446         }
447         self.super_body(body);
448     }
449 }
450
451 impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
452     fn new(
453         cx: &'a mut TypeChecker<'b, 'tcx>,
454         body: &'b Body<'tcx>,
455         promoted: &'b IndexVec<Promoted, Body<'tcx>>,
456     ) -> Self {
457         TypeVerifier { body, promoted, cx, last_span: body.span, errors_reported: false }
458     }
459
460     fn tcx(&self) -> TyCtxt<'tcx> {
461         self.cx.infcx.tcx
462     }
463
464     fn sanitize_type(&mut self, parent: &dyn fmt::Debug, ty: Ty<'tcx>) -> Ty<'tcx> {
465         if ty.has_escaping_bound_vars() || ty.references_error() {
466             span_mirbug_and_err!(self, parent, "bad type {:?}", ty)
467         } else {
468             ty
469         }
470     }
471
472     /// Checks that the types internal to the `place` match up with
473     /// what would be expected.
474     fn sanitize_place(
475         &mut self,
476         place: &Place<'tcx>,
477         location: Location,
478         context: PlaceContext,
479     ) -> PlaceTy<'tcx> {
480         debug!("sanitize_place: {:?}", place);
481
482         let mut place_ty = PlaceTy::from_ty(self.body.local_decls[place.local].ty);
483
484         for elem in place.projection.iter() {
485             if place_ty.variant_index.is_none() {
486                 if place_ty.ty.references_error() {
487                     assert!(self.errors_reported);
488                     return PlaceTy::from_ty(self.tcx().ty_error());
489                 }
490             }
491             place_ty = self.sanitize_projection(place_ty, elem, place, location)
492         }
493
494         if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
495             let tcx = self.tcx();
496             let trait_ref = ty::TraitRef {
497                 def_id: tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
498                 substs: tcx.mk_substs_trait(place_ty.ty, &[]),
499             };
500
501             // To have a `Copy` operand, the type `T` of the
502             // value must be `Copy`. Note that we prove that `T: Copy`,
503             // rather than using the `is_copy_modulo_regions`
504             // test. This is important because
505             // `is_copy_modulo_regions` ignores the resulting region
506             // obligations and assumes they pass. This can result in
507             // bounds from `Copy` impls being unsoundly ignored (e.g.,
508             // #29149). Note that we decide to use `Copy` before knowing
509             // whether the bounds fully apply: in effect, the rule is
510             // that if a value of some type could implement `Copy`, then
511             // it must.
512             self.cx.prove_trait_ref(
513                 trait_ref,
514                 location.to_locations(),
515                 ConstraintCategory::CopyBound,
516             );
517         }
518
519         place_ty
520     }
521
522     fn sanitize_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Location) {
523         // Determine the constraints from the promoted MIR by running the type
524         // checker on the promoted MIR, then transfer the constraints back to
525         // the main MIR, changing the locations to the provided location.
526
527         let parent_body = mem::replace(&mut self.body, promoted_body);
528
529         // Use new sets of constraints and closure bounds so that we can
530         // modify their locations.
531         let all_facts = &mut None;
532         let mut constraints = Default::default();
533         let mut closure_bounds = Default::default();
534         let mut liveness_constraints =
535             LivenessValues::new(Rc::new(RegionValueElements::new(&promoted_body)));
536         // Don't try to add borrow_region facts for the promoted MIR
537
538         let mut swap_constraints = |this: &mut Self| {
539             mem::swap(this.cx.borrowck_context.all_facts, all_facts);
540             mem::swap(
541                 &mut this.cx.borrowck_context.constraints.outlives_constraints,
542                 &mut constraints,
543             );
544             mem::swap(
545                 &mut this.cx.borrowck_context.constraints.closure_bounds_mapping,
546                 &mut closure_bounds,
547             );
548             mem::swap(
549                 &mut this.cx.borrowck_context.constraints.liveness_constraints,
550                 &mut liveness_constraints,
551             );
552         };
553
554         swap_constraints(self);
555
556         self.visit_body(&promoted_body);
557
558         if !self.errors_reported {
559             // if verifier failed, don't do further checks to avoid ICEs
560             self.cx.typeck_mir(promoted_body);
561         }
562
563         self.body = parent_body;
564         // Merge the outlives constraints back in, at the given location.
565         swap_constraints(self);
566
567         let locations = location.to_locations();
568         for constraint in constraints.outlives().iter() {
569             let mut constraint = *constraint;
570             constraint.locations = locations;
571             if let ConstraintCategory::Return(_)
572             | ConstraintCategory::UseAsConst
573             | ConstraintCategory::UseAsStatic = constraint.category
574             {
575                 // "Returning" from a promoted is an assignment to a
576                 // temporary from the user's point of view.
577                 constraint.category = ConstraintCategory::Boring;
578             }
579             self.cx.borrowck_context.constraints.outlives_constraints.push(constraint)
580         }
581         for live_region in liveness_constraints.rows() {
582             self.cx
583                 .borrowck_context
584                 .constraints
585                 .liveness_constraints
586                 .add_element(live_region, location);
587         }
588
589         if !closure_bounds.is_empty() {
590             let combined_bounds_mapping =
591                 closure_bounds.into_iter().flat_map(|(_, value)| value).collect();
592             let existing = self
593                 .cx
594                 .borrowck_context
595                 .constraints
596                 .closure_bounds_mapping
597                 .insert(location, combined_bounds_mapping);
598             assert!(existing.is_none(), "Multiple promoteds/closures at the same location.");
599         }
600     }
601
602     fn sanitize_projection(
603         &mut self,
604         base: PlaceTy<'tcx>,
605         pi: PlaceElem<'tcx>,
606         place: &Place<'tcx>,
607         location: Location,
608     ) -> PlaceTy<'tcx> {
609         debug!("sanitize_projection: {:?} {:?} {:?}", base, pi, place);
610         let tcx = self.tcx();
611         let base_ty = base.ty;
612         match pi {
613             ProjectionElem::Deref => {
614                 let deref_ty = base_ty.builtin_deref(true);
615                 PlaceTy::from_ty(deref_ty.map(|t| t.ty).unwrap_or_else(|| {
616                     span_mirbug_and_err!(self, place, "deref of non-pointer {:?}", base_ty)
617                 }))
618             }
619             ProjectionElem::Index(i) => {
620                 let index_ty = Place::from(i).ty(self.body, tcx).ty;
621                 if index_ty != tcx.types.usize {
622                     PlaceTy::from_ty(span_mirbug_and_err!(self, i, "index by non-usize {:?}", i))
623                 } else {
624                     PlaceTy::from_ty(base_ty.builtin_index().unwrap_or_else(|| {
625                         span_mirbug_and_err!(self, place, "index of non-array {:?}", base_ty)
626                     }))
627                 }
628             }
629             ProjectionElem::ConstantIndex { .. } => {
630                 // consider verifying in-bounds
631                 PlaceTy::from_ty(base_ty.builtin_index().unwrap_or_else(|| {
632                     span_mirbug_and_err!(self, place, "index of non-array {:?}", base_ty)
633                 }))
634             }
635             ProjectionElem::Subslice { from, to, from_end } => {
636                 PlaceTy::from_ty(match base_ty.kind() {
637                     ty::Array(inner, _) => {
638                         assert!(!from_end, "array subslices should not use from_end");
639                         tcx.mk_array(inner, to - from)
640                     }
641                     ty::Slice(..) => {
642                         assert!(from_end, "slice subslices should use from_end");
643                         base_ty
644                     }
645                     _ => span_mirbug_and_err!(self, place, "slice of non-array {:?}", base_ty),
646                 })
647             }
648             ProjectionElem::Downcast(maybe_name, index) => match base_ty.kind() {
649                 ty::Adt(adt_def, _substs) if adt_def.is_enum() => {
650                     if index.as_usize() >= adt_def.variants.len() {
651                         PlaceTy::from_ty(span_mirbug_and_err!(
652                             self,
653                             place,
654                             "cast to variant #{:?} but enum only has {:?}",
655                             index,
656                             adt_def.variants.len()
657                         ))
658                     } else {
659                         PlaceTy { ty: base_ty, variant_index: Some(index) }
660                     }
661                 }
662                 // We do not need to handle generators here, because this runs
663                 // before the generator transform stage.
664                 _ => {
665                     let ty = if let Some(name) = maybe_name {
666                         span_mirbug_and_err!(
667                             self,
668                             place,
669                             "can't downcast {:?} as {:?}",
670                             base_ty,
671                             name
672                         )
673                     } else {
674                         span_mirbug_and_err!(self, place, "can't downcast {:?}", base_ty)
675                     };
676                     PlaceTy::from_ty(ty)
677                 }
678             },
679             ProjectionElem::Field(field, fty) => {
680                 let fty = self.sanitize_type(place, fty);
681                 match self.field_ty(place, base, field, location) {
682                     Ok(ty) => {
683                         let ty = self.cx.normalize(ty, location);
684                         if let Err(terr) = self.cx.eq_types(
685                             ty,
686                             fty,
687                             location.to_locations(),
688                             ConstraintCategory::Boring,
689                         ) {
690                             span_mirbug!(
691                                 self,
692                                 place,
693                                 "bad field access ({:?}: {:?}): {:?}",
694                                 ty,
695                                 fty,
696                                 terr
697                             );
698                         }
699                     }
700                     Err(FieldAccessError::OutOfRange { field_count }) => span_mirbug!(
701                         self,
702                         place,
703                         "accessed field #{} but variant only has {}",
704                         field.index(),
705                         field_count
706                     ),
707                 }
708                 PlaceTy::from_ty(fty)
709             }
710         }
711     }
712
713     fn error(&mut self) -> Ty<'tcx> {
714         self.errors_reported = true;
715         self.tcx().ty_error()
716     }
717
718     fn field_ty(
719         &mut self,
720         parent: &dyn fmt::Debug,
721         base_ty: PlaceTy<'tcx>,
722         field: Field,
723         location: Location,
724     ) -> Result<Ty<'tcx>, FieldAccessError> {
725         let tcx = self.tcx();
726
727         let (variant, substs) = match base_ty {
728             PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() {
729                 ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
730                 ty::Generator(def_id, substs, _) => {
731                     let mut variants = substs.as_generator().state_tys(def_id, tcx);
732                     let mut variant = match variants.nth(variant_index.into()) {
733                         Some(v) => v,
734                         None => bug!(
735                             "variant_index of generator out of range: {:?}/{:?}",
736                             variant_index,
737                             substs.as_generator().state_tys(def_id, tcx).count()
738                         ),
739                     };
740                     return match variant.nth(field.index()) {
741                         Some(ty) => Ok(ty),
742                         None => Err(FieldAccessError::OutOfRange { field_count: variant.count() }),
743                     };
744                 }
745                 _ => bug!("can't have downcast of non-adt non-generator type"),
746             },
747             PlaceTy { ty, variant_index: None } => match *ty.kind() {
748                 ty::Adt(adt_def, substs) if !adt_def.is_enum() => {
749                     (&adt_def.variants[VariantIdx::new(0)], substs)
750                 }
751                 ty::Closure(_, substs) => {
752                     return match substs
753                         .as_closure()
754                         .tupled_upvars_ty()
755                         .tuple_element_ty(field.index())
756                     {
757                         Some(ty) => Ok(ty),
758                         None => Err(FieldAccessError::OutOfRange {
759                             field_count: substs.as_closure().upvar_tys().count(),
760                         }),
761                     };
762                 }
763                 ty::Generator(_, substs, _) => {
764                     // Only prefix fields (upvars and current state) are
765                     // accessible without a variant index.
766                     return match substs.as_generator().prefix_tys().nth(field.index()) {
767                         Some(ty) => Ok(ty),
768                         None => Err(FieldAccessError::OutOfRange {
769                             field_count: substs.as_generator().prefix_tys().count(),
770                         }),
771                     };
772                 }
773                 ty::Tuple(tys) => {
774                     return match tys.get(field.index()) {
775                         Some(&ty) => Ok(ty.expect_ty()),
776                         None => Err(FieldAccessError::OutOfRange { field_count: tys.len() }),
777                     };
778                 }
779                 _ => {
780                     return Ok(span_mirbug_and_err!(
781                         self,
782                         parent,
783                         "can't project out of {:?}",
784                         base_ty
785                     ));
786                 }
787             },
788         };
789
790         if let Some(field) = variant.fields.get(field.index()) {
791             Ok(self.cx.normalize(field.ty(tcx, substs), location))
792         } else {
793             Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
794         }
795     }
796 }
797
798 /// The MIR type checker. Visits the MIR and enforces all the
799 /// constraints needed for it to be valid and well-typed. Along the
800 /// way, it accrues region constraints -- these can later be used by
801 /// NLL region checking.
802 struct TypeChecker<'a, 'tcx> {
803     infcx: &'a InferCtxt<'a, 'tcx>,
804     param_env: ty::ParamEnv<'tcx>,
805     last_span: Span,
806     body: &'a Body<'tcx>,
807     /// User type annotations are shared between the main MIR and the MIR of
808     /// all of the promoted items.
809     user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
810     region_bound_pairs: &'a RegionBoundPairs<'tcx>,
811     implicit_region_bound: ty::Region<'tcx>,
812     reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
813     borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
814     universal_region_relations: &'a UniversalRegionRelations<'tcx>,
815     opaque_type_values: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
816 }
817
818 struct BorrowCheckContext<'a, 'tcx> {
819     universal_regions: &'a UniversalRegions<'tcx>,
820     location_table: &'a LocationTable,
821     all_facts: &'a mut Option<AllFacts>,
822     borrow_set: &'a BorrowSet<'tcx>,
823     constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
824     upvars: &'a [Upvar],
825 }
826
827 crate struct MirTypeckResults<'tcx> {
828     crate constraints: MirTypeckRegionConstraints<'tcx>,
829     pub(in crate::borrow_check) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
830     crate opaque_type_values: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
831 }
832
833 /// A collection of region constraints that must be satisfied for the
834 /// program to be considered well-typed.
835 crate struct MirTypeckRegionConstraints<'tcx> {
836     /// Maps from a `ty::Placeholder` to the corresponding
837     /// `PlaceholderIndex` bit that we will use for it.
838     ///
839     /// To keep everything in sync, do not insert this set
840     /// directly. Instead, use the `placeholder_region` helper.
841     crate placeholder_indices: PlaceholderIndices,
842
843     /// Each time we add a placeholder to `placeholder_indices`, we
844     /// also create a corresponding "representative" region vid for
845     /// that wraps it. This vector tracks those. This way, when we
846     /// convert the same `ty::RePlaceholder(p)` twice, we can map to
847     /// the same underlying `RegionVid`.
848     crate placeholder_index_to_region: IndexVec<PlaceholderIndex, ty::Region<'tcx>>,
849
850     /// In general, the type-checker is not responsible for enforcing
851     /// liveness constraints; this job falls to the region inferencer,
852     /// which performs a liveness analysis. However, in some limited
853     /// cases, the MIR type-checker creates temporary regions that do
854     /// not otherwise appear in the MIR -- in particular, the
855     /// late-bound regions that it instantiates at call-sites -- and
856     /// hence it must report on their liveness constraints.
857     crate liveness_constraints: LivenessValues<RegionVid>,
858
859     crate outlives_constraints: OutlivesConstraintSet,
860
861     crate member_constraints: MemberConstraintSet<'tcx, RegionVid>,
862
863     crate closure_bounds_mapping:
864         FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
865
866     crate type_tests: Vec<TypeTest<'tcx>>,
867 }
868
869 impl MirTypeckRegionConstraints<'tcx> {
870     fn placeholder_region(
871         &mut self,
872         infcx: &InferCtxt<'_, 'tcx>,
873         placeholder: ty::PlaceholderRegion,
874     ) -> ty::Region<'tcx> {
875         let placeholder_index = self.placeholder_indices.insert(placeholder);
876         match self.placeholder_index_to_region.get(placeholder_index) {
877             Some(&v) => v,
878             None => {
879                 let origin = NLLRegionVariableOrigin::Placeholder(placeholder);
880                 let region = infcx.next_nll_region_var_in_universe(origin, placeholder.universe);
881                 self.placeholder_index_to_region.push(region);
882                 region
883             }
884         }
885     }
886 }
887
888 /// The `Locations` type summarizes *where* region constraints are
889 /// required to hold. Normally, this is at a particular point which
890 /// created the obligation, but for constraints that the user gave, we
891 /// want the constraint to hold at all points.
892 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
893 pub enum Locations {
894     /// Indicates that a type constraint should always be true. This
895     /// is particularly important in the new borrowck analysis for
896     /// things like the type of the return slot. Consider this
897     /// example:
898     ///
899     /// ```
900     /// fn foo<'a>(x: &'a u32) -> &'a u32 {
901     ///     let y = 22;
902     ///     return &y; // error
903     /// }
904     /// ```
905     ///
906     /// Here, we wind up with the signature from the return type being
907     /// something like `&'1 u32` where `'1` is a universal region. But
908     /// the type of the return slot `_0` is something like `&'2 u32`
909     /// where `'2` is an existential region variable. The type checker
910     /// requires that `&'2 u32 = &'1 u32` -- but at what point? In the
911     /// older NLL analysis, we required this only at the entry point
912     /// to the function. By the nature of the constraints, this wound
913     /// up propagating to all points reachable from start (because
914     /// `'1` -- as a universal region -- is live everywhere). In the
915     /// newer analysis, though, this doesn't work: `_0` is considered
916     /// dead at the start (it has no usable value) and hence this type
917     /// equality is basically a no-op. Then, later on, when we do `_0
918     /// = &'3 y`, that region `'3` never winds up related to the
919     /// universal region `'1` and hence no error occurs. Therefore, we
920     /// use Locations::All instead, which ensures that the `'1` and
921     /// `'2` are equal everything. We also use this for other
922     /// user-given type annotations; e.g., if the user wrote `let mut
923     /// x: &'static u32 = ...`, we would ensure that all values
924     /// assigned to `x` are of `'static` lifetime.
925     ///
926     /// The span points to the place the constraint arose. For example,
927     /// it points to the type in a user-given type annotation. If
928     /// there's no sensible span then it's DUMMY_SP.
929     All(Span),
930
931     /// An outlives constraint that only has to hold at a single location,
932     /// usually it represents a point where references flow from one spot to
933     /// another (e.g., `x = y`)
934     Single(Location),
935 }
936
937 impl Locations {
938     pub fn from_location(&self) -> Option<Location> {
939         match self {
940             Locations::All(_) => None,
941             Locations::Single(from_location) => Some(*from_location),
942         }
943     }
944
945     /// Gets a span representing the location.
946     pub fn span(&self, body: &Body<'_>) -> Span {
947         match self {
948             Locations::All(span) => *span,
949             Locations::Single(l) => body.source_info(*l).span,
950         }
951     }
952 }
953
954 impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
955     fn new(
956         infcx: &'a InferCtxt<'a, 'tcx>,
957         body: &'a Body<'tcx>,
958         param_env: ty::ParamEnv<'tcx>,
959         region_bound_pairs: &'a RegionBoundPairs<'tcx>,
960         implicit_region_bound: ty::Region<'tcx>,
961         borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
962         universal_region_relations: &'a UniversalRegionRelations<'tcx>,
963     ) -> Self {
964         let mut checker = Self {
965             infcx,
966             last_span: DUMMY_SP,
967             body,
968             user_type_annotations: &body.user_type_annotations,
969             param_env,
970             region_bound_pairs,
971             implicit_region_bound,
972             borrowck_context,
973             reported_errors: Default::default(),
974             universal_region_relations,
975             opaque_type_values: FxHashMap::default(),
976         };
977         checker.check_user_type_annotations();
978         checker
979     }
980
981     fn unsized_feature_enabled(&self) -> bool {
982         let features = self.tcx().features();
983         features.unsized_locals || features.unsized_fn_params
984     }
985
986     /// Equate the inferred type and the annotated type for user type annotations
987     fn check_user_type_annotations(&mut self) {
988         debug!(
989             "check_user_type_annotations: user_type_annotations={:?}",
990             self.user_type_annotations
991         );
992         for user_annotation in self.user_type_annotations {
993             let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
994             let (annotation, _) =
995                 self.infcx.instantiate_canonical_with_fresh_inference_vars(span, user_ty);
996             match annotation {
997                 UserType::Ty(mut ty) => {
998                     ty = self.normalize(ty, Locations::All(span));
999
1000                     if let Err(terr) = self.eq_types(
1001                         ty,
1002                         inferred_ty,
1003                         Locations::All(span),
1004                         ConstraintCategory::BoringNoLocation,
1005                     ) {
1006                         span_mirbug!(
1007                             self,
1008                             user_annotation,
1009                             "bad user type ({:?} = {:?}): {:?}",
1010                             ty,
1011                             inferred_ty,
1012                             terr
1013                         );
1014                     }
1015
1016                     self.prove_predicate(
1017                         ty::PredicateAtom::WellFormed(inferred_ty.into()).to_predicate(self.tcx()),
1018                         Locations::All(span),
1019                         ConstraintCategory::TypeAnnotation,
1020                     );
1021                 }
1022                 UserType::TypeOf(def_id, user_substs) => {
1023                     if let Err(terr) = self.fully_perform_op(
1024                         Locations::All(span),
1025                         ConstraintCategory::BoringNoLocation,
1026                         self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
1027                             inferred_ty,
1028                             def_id,
1029                             user_substs,
1030                         )),
1031                     ) {
1032                         span_mirbug!(
1033                             self,
1034                             user_annotation,
1035                             "bad user type AscribeUserType({:?}, {:?} {:?}): {:?}",
1036                             inferred_ty,
1037                             def_id,
1038                             user_substs,
1039                             terr
1040                         );
1041                     }
1042                 }
1043             }
1044         }
1045     }
1046
1047     /// Given some operation `op` that manipulates types, proves
1048     /// predicates, or otherwise uses the inference context, executes
1049     /// `op` and then executes all the further obligations that `op`
1050     /// returns. This will yield a set of outlives constraints amongst
1051     /// regions which are extracted and stored as having occurred at
1052     /// `locations`.
1053     ///
1054     /// **Any `rustc_infer::infer` operations that might generate region
1055     /// constraints should occur within this method so that those
1056     /// constraints can be properly localized!**
1057     fn fully_perform_op<R>(
1058         &mut self,
1059         locations: Locations,
1060         category: ConstraintCategory,
1061         op: impl type_op::TypeOp<'tcx, Output = R>,
1062     ) -> Fallible<R> {
1063         let (r, opt_data) = op.fully_perform(self.infcx)?;
1064
1065         if let Some(data) = &opt_data {
1066             self.push_region_constraints(locations, category, data);
1067         }
1068
1069         Ok(r)
1070     }
1071
1072     fn push_region_constraints(
1073         &mut self,
1074         locations: Locations,
1075         category: ConstraintCategory,
1076         data: &QueryRegionConstraints<'tcx>,
1077     ) {
1078         debug!("push_region_constraints: constraints generated at {:?} are {:#?}", locations, data);
1079
1080         constraint_conversion::ConstraintConversion::new(
1081             self.infcx,
1082             self.borrowck_context.universal_regions,
1083             self.region_bound_pairs,
1084             Some(self.implicit_region_bound),
1085             self.param_env,
1086             locations,
1087             category,
1088             &mut self.borrowck_context.constraints,
1089         )
1090         .convert_all(data);
1091     }
1092
1093     /// Convenient wrapper around `relate_tys::relate_types` -- see
1094     /// that fn for docs.
1095     fn relate_types(
1096         &mut self,
1097         a: Ty<'tcx>,
1098         v: ty::Variance,
1099         b: Ty<'tcx>,
1100         locations: Locations,
1101         category: ConstraintCategory,
1102     ) -> Fallible<()> {
1103         relate_tys::relate_types(
1104             self.infcx,
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::PredicateAtom::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::PredicateAtom::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 { ref 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(_) => {
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                                 // To determine if `const_in_array_repeat_expressions` feature gate should
2002                                 // be mentioned, need to check if the rvalue is promotable.
2003                                 let should_suggest =
2004                                     should_suggest_const_in_array_repeat_expressions_attribute(
2005                                         &ccx, operand,
2006                                     );
2007                                 debug!("check_rvalue: should_suggest={:?}", should_suggest);
2008
2009                                 let def_id = body.source.def_id().expect_local();
2010                                 self.infcx.report_selection_error(
2011                                     &traits::Obligation::new(
2012                                         ObligationCause::new(
2013                                             span,
2014                                             self.tcx().hir().local_def_id_to_hir_id(def_id),
2015                                             traits::ObligationCauseCode::RepeatVec(should_suggest),
2016                                         ),
2017                                         self.param_env,
2018                                         ty::Binder::bind(ty::TraitRef::new(
2019                                             self.tcx().require_lang_item(
2020                                                 LangItem::Copy,
2021                                                 Some(self.last_span),
2022                                             ),
2023                                             tcx.mk_substs_trait(ty, &[]),
2024                                         ))
2025                                         .without_const()
2026                                         .to_predicate(self.tcx()),
2027                                     ),
2028                                     &traits::SelectionError::Unimplemented,
2029                                     false,
2030                                     false,
2031                                 );
2032                             }
2033                         }
2034                     }
2035                 }
2036             }
2037
2038             Rvalue::NullaryOp(_, ty) => {
2039                 // Even with unsized locals cannot box an unsized value.
2040                 if self.unsized_feature_enabled() {
2041                     let span = body.source_info(location).span;
2042                     self.ensure_place_sized(ty, span);
2043                 }
2044
2045                 let trait_ref = ty::TraitRef {
2046                     def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
2047                     substs: tcx.mk_substs_trait(ty, &[]),
2048                 };
2049
2050                 self.prove_trait_ref(
2051                     trait_ref,
2052                     location.to_locations(),
2053                     ConstraintCategory::SizedBound,
2054                 );
2055             }
2056
2057             Rvalue::Cast(cast_kind, op, ty) => {
2058                 match cast_kind {
2059                     CastKind::Pointer(PointerCast::ReifyFnPointer) => {
2060                         let fn_sig = op.ty(body, tcx).fn_sig(tcx);
2061
2062                         // The type that we see in the fcx is like
2063                         // `foo::<'a, 'b>`, where `foo` is the path to a
2064                         // function definition. When we extract the
2065                         // signature, it comes from the `fn_sig` query,
2066                         // and hence may contain unnormalized results.
2067                         let fn_sig = self.normalize(fn_sig, location);
2068
2069                         let ty_fn_ptr_from = tcx.mk_fn_ptr(fn_sig);
2070
2071                         if let Err(terr) = self.eq_types(
2072                             ty_fn_ptr_from,
2073                             ty,
2074                             location.to_locations(),
2075                             ConstraintCategory::Cast,
2076                         ) {
2077                             span_mirbug!(
2078                                 self,
2079                                 rvalue,
2080                                 "equating {:?} with {:?} yields {:?}",
2081                                 ty_fn_ptr_from,
2082                                 ty,
2083                                 terr
2084                             );
2085                         }
2086                     }
2087
2088                     CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => {
2089                         let sig = match op.ty(body, tcx).kind() {
2090                             ty::Closure(_, substs) => substs.as_closure().sig(),
2091                             _ => bug!(),
2092                         };
2093                         let ty_fn_ptr_from = tcx.mk_fn_ptr(tcx.signature_unclosure(sig, *unsafety));
2094
2095                         if let Err(terr) = self.eq_types(
2096                             ty_fn_ptr_from,
2097                             ty,
2098                             location.to_locations(),
2099                             ConstraintCategory::Cast,
2100                         ) {
2101                             span_mirbug!(
2102                                 self,
2103                                 rvalue,
2104                                 "equating {:?} with {:?} yields {:?}",
2105                                 ty_fn_ptr_from,
2106                                 ty,
2107                                 terr
2108                             );
2109                         }
2110                     }
2111
2112                     CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
2113                         let fn_sig = op.ty(body, tcx).fn_sig(tcx);
2114
2115                         // The type that we see in the fcx is like
2116                         // `foo::<'a, 'b>`, where `foo` is the path to a
2117                         // function definition. When we extract the
2118                         // signature, it comes from the `fn_sig` query,
2119                         // and hence may contain unnormalized results.
2120                         let fn_sig = self.normalize(fn_sig, location);
2121
2122                         let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);
2123
2124                         if let Err(terr) = self.eq_types(
2125                             ty_fn_ptr_from,
2126                             ty,
2127                             location.to_locations(),
2128                             ConstraintCategory::Cast,
2129                         ) {
2130                             span_mirbug!(
2131                                 self,
2132                                 rvalue,
2133                                 "equating {:?} with {:?} yields {:?}",
2134                                 ty_fn_ptr_from,
2135                                 ty,
2136                                 terr
2137                             );
2138                         }
2139                     }
2140
2141                     CastKind::Pointer(PointerCast::Unsize) => {
2142                         let &ty = ty;
2143                         let trait_ref = ty::TraitRef {
2144                             def_id: tcx
2145                                 .require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)),
2146                             substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]),
2147                         };
2148
2149                         self.prove_trait_ref(
2150                             trait_ref,
2151                             location.to_locations(),
2152                             ConstraintCategory::Cast,
2153                         );
2154                     }
2155
2156                     CastKind::Pointer(PointerCast::MutToConstPointer) => {
2157                         let ty_from = match op.ty(body, tcx).kind() {
2158                             ty::RawPtr(ty::TypeAndMut {
2159                                 ty: ty_from,
2160                                 mutbl: hir::Mutability::Mut,
2161                             }) => ty_from,
2162                             _ => {
2163                                 span_mirbug!(
2164                                     self,
2165                                     rvalue,
2166                                     "unexpected base type for cast {:?}",
2167                                     ty,
2168                                 );
2169                                 return;
2170                             }
2171                         };
2172                         let ty_to = match ty.kind() {
2173                             ty::RawPtr(ty::TypeAndMut {
2174                                 ty: ty_to,
2175                                 mutbl: hir::Mutability::Not,
2176                             }) => ty_to,
2177                             _ => {
2178                                 span_mirbug!(
2179                                     self,
2180                                     rvalue,
2181                                     "unexpected target type for cast {:?}",
2182                                     ty,
2183                                 );
2184                                 return;
2185                             }
2186                         };
2187                         if let Err(terr) = self.sub_types(
2188                             ty_from,
2189                             ty_to,
2190                             location.to_locations(),
2191                             ConstraintCategory::Cast,
2192                         ) {
2193                             span_mirbug!(
2194                                 self,
2195                                 rvalue,
2196                                 "relating {:?} with {:?} yields {:?}",
2197                                 ty_from,
2198                                 ty_to,
2199                                 terr
2200                             );
2201                         }
2202                     }
2203
2204                     CastKind::Pointer(PointerCast::ArrayToPointer) => {
2205                         let ty_from = op.ty(body, tcx);
2206
2207                         let opt_ty_elem = match ty_from.kind() {
2208                             ty::RawPtr(ty::TypeAndMut {
2209                                 mutbl: hir::Mutability::Not,
2210                                 ty: array_ty,
2211                             }) => match array_ty.kind() {
2212                                 ty::Array(ty_elem, _) => Some(ty_elem),
2213                                 _ => None,
2214                             },
2215                             _ => None,
2216                         };
2217
2218                         let ty_elem = match opt_ty_elem {
2219                             Some(ty_elem) => ty_elem,
2220                             None => {
2221                                 span_mirbug!(
2222                                     self,
2223                                     rvalue,
2224                                     "ArrayToPointer cast from unexpected type {:?}",
2225                                     ty_from,
2226                                 );
2227                                 return;
2228                             }
2229                         };
2230
2231                         let ty_to = match ty.kind() {
2232                             ty::RawPtr(ty::TypeAndMut {
2233                                 mutbl: hir::Mutability::Not,
2234                                 ty: ty_to,
2235                             }) => ty_to,
2236                             _ => {
2237                                 span_mirbug!(
2238                                     self,
2239                                     rvalue,
2240                                     "ArrayToPointer cast to unexpected type {:?}",
2241                                     ty,
2242                                 );
2243                                 return;
2244                             }
2245                         };
2246
2247                         if let Err(terr) = self.sub_types(
2248                             ty_elem,
2249                             ty_to,
2250                             location.to_locations(),
2251                             ConstraintCategory::Cast,
2252                         ) {
2253                             span_mirbug!(
2254                                 self,
2255                                 rvalue,
2256                                 "relating {:?} with {:?} yields {:?}",
2257                                 ty_elem,
2258                                 ty_to,
2259                                 terr
2260                             )
2261                         }
2262                     }
2263
2264                     CastKind::Misc => {
2265                         let ty_from = op.ty(body, tcx);
2266                         let cast_ty_from = CastTy::from_ty(ty_from);
2267                         let cast_ty_to = CastTy::from_ty(ty);
2268                         match (cast_ty_from, cast_ty_to) {
2269                             (None, _)
2270                             | (_, None | Some(CastTy::FnPtr))
2271                             | (Some(CastTy::Float), Some(CastTy::Ptr(_)))
2272                             | (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Float)) => {
2273                                 span_mirbug!(self, rvalue, "Invalid cast {:?} -> {:?}", ty_from, ty,)
2274                             }
2275                             (
2276                                 Some(CastTy::Int(_)),
2277                                 Some(CastTy::Int(_) | CastTy::Float | CastTy::Ptr(_)),
2278                             )
2279                             | (Some(CastTy::Float), Some(CastTy::Int(_) | CastTy::Float))
2280                             | (Some(CastTy::Ptr(_)), Some(CastTy::Int(_) | CastTy::Ptr(_)))
2281                             | (Some(CastTy::FnPtr), Some(CastTy::Int(_) | CastTy::Ptr(_))) => (),
2282                         }
2283                     }
2284                 }
2285             }
2286
2287             Rvalue::Ref(region, _borrow_kind, borrowed_place) => {
2288                 self.add_reborrow_constraint(&body, location, region, borrowed_place);
2289             }
2290
2291             Rvalue::BinaryOp(
2292                 BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge,
2293                 left,
2294                 right,
2295             ) => {
2296                 let ty_left = left.ty(body, tcx);
2297                 match ty_left.kind() {
2298                     // Types with regions are comparable if they have a common super-type.
2299                     ty::RawPtr(_) | ty::FnPtr(_) => {
2300                         let ty_right = right.ty(body, tcx);
2301                         let common_ty = self.infcx.next_ty_var(TypeVariableOrigin {
2302                             kind: TypeVariableOriginKind::MiscVariable,
2303                             span: body.source_info(location).span,
2304                         });
2305                         self.relate_types(
2306                             common_ty,
2307                             ty::Variance::Contravariant,
2308                             ty_left,
2309                             location.to_locations(),
2310                             ConstraintCategory::Boring,
2311                         )
2312                         .unwrap_or_else(|err| {
2313                             bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
2314                         });
2315                         if let Err(terr) = self.relate_types(
2316                             common_ty,
2317                             ty::Variance::Contravariant,
2318                             ty_right,
2319                             location.to_locations(),
2320                             ConstraintCategory::Boring,
2321                         ) {
2322                             span_mirbug!(
2323                                 self,
2324                                 rvalue,
2325                                 "unexpected comparison types {:?} and {:?} yields {:?}",
2326                                 ty_left,
2327                                 ty_right,
2328                                 terr
2329                             )
2330                         }
2331                     }
2332                     // For types with no regions we can just check that the
2333                     // both operands have the same type.
2334                     ty::Int(_) | ty::Uint(_) | ty::Bool | ty::Char | ty::Float(_)
2335                         if ty_left == right.ty(body, tcx) => {}
2336                     // Other types are compared by trait methods, not by
2337                     // `Rvalue::BinaryOp`.
2338                     _ => span_mirbug!(
2339                         self,
2340                         rvalue,
2341                         "unexpected comparison types {:?} and {:?}",
2342                         ty_left,
2343                         right.ty(body, tcx)
2344                     ),
2345                 }
2346             }
2347
2348             Rvalue::AddressOf(..)
2349             | Rvalue::ThreadLocalRef(..)
2350             | Rvalue::Use(..)
2351             | Rvalue::Len(..)
2352             | Rvalue::BinaryOp(..)
2353             | Rvalue::CheckedBinaryOp(..)
2354             | Rvalue::UnaryOp(..)
2355             | Rvalue::Discriminant(..) => {}
2356         }
2357     }
2358
2359     /// If this rvalue supports a user-given type annotation, then
2360     /// extract and return it. This represents the final type of the
2361     /// rvalue and will be unified with the inferred type.
2362     fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<UserTypeAnnotationIndex> {
2363         match rvalue {
2364             Rvalue::Use(_)
2365             | Rvalue::ThreadLocalRef(_)
2366             | Rvalue::Repeat(..)
2367             | Rvalue::Ref(..)
2368             | Rvalue::AddressOf(..)
2369             | Rvalue::Len(..)
2370             | Rvalue::Cast(..)
2371             | Rvalue::BinaryOp(..)
2372             | Rvalue::CheckedBinaryOp(..)
2373             | Rvalue::NullaryOp(..)
2374             | Rvalue::UnaryOp(..)
2375             | Rvalue::Discriminant(..) => None,
2376
2377             Rvalue::Aggregate(aggregate, _) => match **aggregate {
2378                 AggregateKind::Adt(_, _, _, user_ty, _) => user_ty,
2379                 AggregateKind::Array(_) => None,
2380                 AggregateKind::Tuple => None,
2381                 AggregateKind::Closure(_, _) => None,
2382                 AggregateKind::Generator(_, _, _) => None,
2383             },
2384         }
2385     }
2386
2387     fn check_aggregate_rvalue(
2388         &mut self,
2389         body: &Body<'tcx>,
2390         rvalue: &Rvalue<'tcx>,
2391         aggregate_kind: &AggregateKind<'tcx>,
2392         operands: &[Operand<'tcx>],
2393         location: Location,
2394     ) {
2395         let tcx = self.tcx();
2396
2397         self.prove_aggregate_predicates(aggregate_kind, location);
2398
2399         if *aggregate_kind == AggregateKind::Tuple {
2400             // tuple rvalue field type is always the type of the op. Nothing to check here.
2401             return;
2402         }
2403
2404         for (i, operand) in operands.iter().enumerate() {
2405             let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
2406                 Ok(field_ty) => field_ty,
2407                 Err(FieldAccessError::OutOfRange { field_count }) => {
2408                     span_mirbug!(
2409                         self,
2410                         rvalue,
2411                         "accessed field #{} but variant only has {}",
2412                         i,
2413                         field_count
2414                     );
2415                     continue;
2416                 }
2417             };
2418             let operand_ty = operand.ty(body, tcx);
2419             let operand_ty = self.normalize(operand_ty, location);
2420
2421             if let Err(terr) = self.sub_types(
2422                 operand_ty,
2423                 field_ty,
2424                 location.to_locations(),
2425                 ConstraintCategory::Boring,
2426             ) {
2427                 span_mirbug!(
2428                     self,
2429                     rvalue,
2430                     "{:?} is not a subtype of {:?}: {:?}",
2431                     operand_ty,
2432                     field_ty,
2433                     terr
2434                 );
2435             }
2436         }
2437     }
2438
2439     /// Adds the constraints that arise from a borrow expression `&'a P` at the location `L`.
2440     ///
2441     /// # Parameters
2442     ///
2443     /// - `location`: the location `L` where the borrow expression occurs
2444     /// - `borrow_region`: the region `'a` associated with the borrow
2445     /// - `borrowed_place`: the place `P` being borrowed
2446     fn add_reborrow_constraint(
2447         &mut self,
2448         body: &Body<'tcx>,
2449         location: Location,
2450         borrow_region: ty::Region<'tcx>,
2451         borrowed_place: &Place<'tcx>,
2452     ) {
2453         // These constraints are only meaningful during borrowck:
2454         let BorrowCheckContext { borrow_set, location_table, all_facts, constraints, .. } =
2455             self.borrowck_context;
2456
2457         // In Polonius mode, we also push a `borrow_region` fact
2458         // linking the loan to the region (in some cases, though,
2459         // there is no loan associated with this borrow expression --
2460         // that occurs when we are borrowing an unsafe place, for
2461         // example).
2462         if let Some(all_facts) = all_facts {
2463             let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
2464             if let Some(borrow_index) = borrow_set.get_index_of(&location) {
2465                 let region_vid = borrow_region.to_region_vid();
2466                 all_facts.borrow_region.push((
2467                     region_vid,
2468                     borrow_index,
2469                     location_table.mid_index(location),
2470                 ));
2471             }
2472         }
2473
2474         // If we are reborrowing the referent of another reference, we
2475         // need to add outlives relationships. In a case like `&mut
2476         // *p`, where the `p` has type `&'b mut Foo`, for example, we
2477         // need to ensure that `'b: 'a`.
2478
2479         debug!(
2480             "add_reborrow_constraint({:?}, {:?}, {:?})",
2481             location, borrow_region, borrowed_place
2482         );
2483
2484         let mut cursor = borrowed_place.projection.as_ref();
2485         let tcx = self.infcx.tcx;
2486         let field = path_utils::is_upvar_field_projection(
2487             tcx,
2488             &self.borrowck_context.upvars,
2489             borrowed_place.as_ref(),
2490             body,
2491         );
2492         let category = if let Some(field) = field {
2493             ConstraintCategory::ClosureUpvar(self.borrowck_context.upvars[field.index()].var_hir_id)
2494         } else {
2495             ConstraintCategory::Boring
2496         };
2497
2498         while let [proj_base @ .., elem] = cursor {
2499             cursor = proj_base;
2500
2501             debug!("add_reborrow_constraint - iteration {:?}", elem);
2502
2503             match elem {
2504                 ProjectionElem::Deref => {
2505                     let base_ty = Place::ty_from(borrowed_place.local, proj_base, body, tcx).ty;
2506
2507                     debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
2508                     match base_ty.kind() {
2509                         ty::Ref(ref_region, _, mutbl) => {
2510                             constraints.outlives_constraints.push(OutlivesConstraint {
2511                                 sup: ref_region.to_region_vid(),
2512                                 sub: borrow_region.to_region_vid(),
2513                                 locations: location.to_locations(),
2514                                 category,
2515                             });
2516
2517                             match mutbl {
2518                                 hir::Mutability::Not => {
2519                                     // Immutable reference. We don't need the base
2520                                     // to be valid for the entire lifetime of
2521                                     // the borrow.
2522                                     break;
2523                                 }
2524                                 hir::Mutability::Mut => {
2525                                     // Mutable reference. We *do* need the base
2526                                     // to be valid, because after the base becomes
2527                                     // invalid, someone else can use our mutable deref.
2528
2529                                     // This is in order to make the following function
2530                                     // illegal:
2531                                     // ```
2532                                     // fn unsafe_deref<'a, 'b>(x: &'a &'b mut T) -> &'b mut T {
2533                                     //     &mut *x
2534                                     // }
2535                                     // ```
2536                                     //
2537                                     // As otherwise you could clone `&mut T` using the
2538                                     // following function:
2539                                     // ```
2540                                     // fn bad(x: &mut T) -> (&mut T, &mut T) {
2541                                     //     let my_clone = unsafe_deref(&'a x);
2542                                     //     ENDREGION 'a;
2543                                     //     (my_clone, x)
2544                                     // }
2545                                     // ```
2546                                 }
2547                             }
2548                         }
2549                         ty::RawPtr(..) => {
2550                             // deref of raw pointer, guaranteed to be valid
2551                             break;
2552                         }
2553                         ty::Adt(def, _) if def.is_box() => {
2554                             // deref of `Box`, need the base to be valid - propagate
2555                         }
2556                         _ => bug!("unexpected deref ty {:?} in {:?}", base_ty, borrowed_place),
2557                     }
2558                 }
2559                 ProjectionElem::Field(..)
2560                 | ProjectionElem::Downcast(..)
2561                 | ProjectionElem::Index(..)
2562                 | ProjectionElem::ConstantIndex { .. }
2563                 | ProjectionElem::Subslice { .. } => {
2564                     // other field access
2565                 }
2566             }
2567         }
2568     }
2569
2570     fn prove_aggregate_predicates(
2571         &mut self,
2572         aggregate_kind: &AggregateKind<'tcx>,
2573         location: Location,
2574     ) {
2575         let tcx = self.tcx();
2576
2577         debug!(
2578             "prove_aggregate_predicates(aggregate_kind={:?}, location={:?})",
2579             aggregate_kind, location
2580         );
2581
2582         let instantiated_predicates = match aggregate_kind {
2583             AggregateKind::Adt(def, _, substs, _, _) => {
2584                 tcx.predicates_of(def.did).instantiate(tcx, substs)
2585             }
2586
2587             // For closures, we have some **extra requirements** we
2588             //
2589             // have to check. In particular, in their upvars and
2590             // signatures, closures often reference various regions
2591             // from the surrounding function -- we call those the
2592             // closure's free regions. When we borrow-check (and hence
2593             // region-check) closures, we may find that the closure
2594             // requires certain relationships between those free
2595             // regions. However, because those free regions refer to
2596             // portions of the CFG of their caller, the closure is not
2597             // in a position to verify those relationships. In that
2598             // case, the requirements get "propagated" to us, and so
2599             // we have to solve them here where we instantiate the
2600             // closure.
2601             //
2602             // Despite the opacity of the previous parapgrah, this is
2603             // actually relatively easy to understand in terms of the
2604             // desugaring. A closure gets desugared to a struct, and
2605             // these extra requirements are basically like where
2606             // clauses on the struct.
2607             AggregateKind::Closure(def_id, substs)
2608             | AggregateKind::Generator(def_id, substs, _) => {
2609                 self.prove_closure_bounds(tcx, def_id.expect_local(), substs, location)
2610             }
2611
2612             AggregateKind::Array(_) | AggregateKind::Tuple => ty::InstantiatedPredicates::empty(),
2613         };
2614
2615         self.normalize_and_prove_instantiated_predicates(
2616             instantiated_predicates,
2617             location.to_locations(),
2618         );
2619     }
2620
2621     fn prove_closure_bounds(
2622         &mut self,
2623         tcx: TyCtxt<'tcx>,
2624         def_id: LocalDefId,
2625         substs: SubstsRef<'tcx>,
2626         location: Location,
2627     ) -> ty::InstantiatedPredicates<'tcx> {
2628         if let Some(ref closure_region_requirements) = tcx.mir_borrowck(def_id).closure_requirements
2629         {
2630             let closure_constraints = QueryRegionConstraints {
2631                 outlives: closure_region_requirements.apply_requirements(
2632                     tcx,
2633                     def_id.to_def_id(),
2634                     substs,
2635                 ),
2636
2637                 // Presently, closures never propagate member
2638                 // constraints to their parents -- they are enforced
2639                 // locally.  This is largely a non-issue as member
2640                 // constraints only come from `-> impl Trait` and
2641                 // friends which don't appear (thus far...) in
2642                 // closures.
2643                 member_constraints: vec![],
2644             };
2645
2646             let bounds_mapping = closure_constraints
2647                 .outlives
2648                 .iter()
2649                 .enumerate()
2650                 .filter_map(|(idx, constraint)| {
2651                     let ty::OutlivesPredicate(k1, r2) =
2652                         constraint.no_bound_vars().unwrap_or_else(|| {
2653                             bug!("query_constraint {:?} contained bound vars", constraint,);
2654                         });
2655
2656                     match k1.unpack() {
2657                         GenericArgKind::Lifetime(r1) => {
2658                             // constraint is r1: r2
2659                             let r1_vid = self.borrowck_context.universal_regions.to_region_vid(r1);
2660                             let r2_vid = self.borrowck_context.universal_regions.to_region_vid(r2);
2661                             let outlives_requirements =
2662                                 &closure_region_requirements.outlives_requirements[idx];
2663                             Some((
2664                                 (r1_vid, r2_vid),
2665                                 (outlives_requirements.category, outlives_requirements.blame_span),
2666                             ))
2667                         }
2668                         GenericArgKind::Type(_) | GenericArgKind::Const(_) => None,
2669                     }
2670                 })
2671                 .collect();
2672
2673             let existing = self
2674                 .borrowck_context
2675                 .constraints
2676                 .closure_bounds_mapping
2677                 .insert(location, bounds_mapping);
2678             assert!(existing.is_none(), "Multiple closures at the same location.");
2679
2680             self.push_region_constraints(
2681                 location.to_locations(),
2682                 ConstraintCategory::ClosureBounds,
2683                 &closure_constraints,
2684             );
2685         }
2686
2687         tcx.predicates_of(def_id).instantiate(tcx, substs)
2688     }
2689
2690     fn prove_trait_ref(
2691         &mut self,
2692         trait_ref: ty::TraitRef<'tcx>,
2693         locations: Locations,
2694         category: ConstraintCategory,
2695     ) {
2696         self.prove_predicates(
2697             Some(ty::PredicateAtom::Trait(
2698                 ty::TraitPredicate { trait_ref },
2699                 hir::Constness::NotConst,
2700             )),
2701             locations,
2702             category,
2703         );
2704     }
2705
2706     fn normalize_and_prove_instantiated_predicates(
2707         &mut self,
2708         instantiated_predicates: ty::InstantiatedPredicates<'tcx>,
2709         locations: Locations,
2710     ) {
2711         for predicate in instantiated_predicates.predicates {
2712             let predicate = self.normalize(predicate, locations);
2713             self.prove_predicate(predicate, locations, ConstraintCategory::Boring);
2714         }
2715     }
2716
2717     fn prove_predicates(
2718         &mut self,
2719         predicates: impl IntoIterator<Item = impl ToPredicate<'tcx>>,
2720         locations: Locations,
2721         category: ConstraintCategory,
2722     ) {
2723         for predicate in predicates {
2724             let predicate = predicate.to_predicate(self.tcx());
2725             debug!("prove_predicates(predicate={:?}, locations={:?})", predicate, locations,);
2726
2727             self.prove_predicate(predicate, locations, category);
2728         }
2729     }
2730
2731     fn prove_predicate(
2732         &mut self,
2733         predicate: ty::Predicate<'tcx>,
2734         locations: Locations,
2735         category: ConstraintCategory,
2736     ) {
2737         debug!("prove_predicate(predicate={:?}, location={:?})", predicate, locations,);
2738
2739         let param_env = self.param_env;
2740         self.fully_perform_op(
2741             locations,
2742             category,
2743             param_env.and(type_op::prove_predicate::ProvePredicate::new(predicate)),
2744         )
2745         .unwrap_or_else(|NoSolution| {
2746             span_mirbug!(self, NoSolution, "could not prove {:?}", predicate);
2747         })
2748     }
2749
2750     fn typeck_mir(&mut self, body: &Body<'tcx>) {
2751         self.last_span = body.span;
2752         debug!("run_on_mir: {:?}", body.span);
2753
2754         for (local, local_decl) in body.local_decls.iter_enumerated() {
2755             self.check_local(&body, local, local_decl);
2756         }
2757
2758         for (block, block_data) in body.basic_blocks().iter_enumerated() {
2759             let mut location = Location { block, statement_index: 0 };
2760             for stmt in &block_data.statements {
2761                 if !stmt.source_info.span.is_dummy() {
2762                     self.last_span = stmt.source_info.span;
2763                 }
2764                 self.check_stmt(body, stmt, location);
2765                 location.statement_index += 1;
2766             }
2767
2768             self.check_terminator(&body, block_data.terminator(), location);
2769             self.check_iscleanup(&body, block_data);
2770         }
2771     }
2772
2773     fn normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T
2774     where
2775         T: type_op::normalize::Normalizable<'tcx> + Copy + 'tcx,
2776     {
2777         debug!("normalize(value={:?}, location={:?})", value, location);
2778         let param_env = self.param_env;
2779         self.fully_perform_op(
2780             location.to_locations(),
2781             ConstraintCategory::Boring,
2782             param_env.and(type_op::normalize::Normalize::new(value)),
2783         )
2784         .unwrap_or_else(|NoSolution| {
2785             span_mirbug!(self, NoSolution, "failed to normalize `{:?}`", value);
2786             value
2787         })
2788     }
2789 }
2790
2791 trait NormalizeLocation: fmt::Debug + Copy {
2792     fn to_locations(self) -> Locations;
2793 }
2794
2795 impl NormalizeLocation for Locations {
2796     fn to_locations(self) -> Locations {
2797         self
2798     }
2799 }
2800
2801 impl NormalizeLocation for Location {
2802     fn to_locations(self) -> Locations {
2803         Locations::Single(self)
2804     }
2805 }
2806
2807 #[derive(Debug, Default)]
2808 struct ObligationAccumulator<'tcx> {
2809     obligations: PredicateObligations<'tcx>,
2810 }
2811
2812 impl<'tcx> ObligationAccumulator<'tcx> {
2813     fn add<T>(&mut self, value: InferOk<'tcx, T>) -> T {
2814         let InferOk { value, obligations } = value;
2815         self.obligations.extend(obligations);
2816         value
2817     }
2818
2819     fn into_vec(self) -> PredicateObligations<'tcx> {
2820         self.obligations
2821     }
2822 }