]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/mir/mod.rs
abca2ecdb060bc5e83d8ef61e6bf24095365be8b
[rust.git] / compiler / rustc_middle / src / mir / mod.rs
1 //! MIR datatypes and passes. See the [rustc dev guide] for more info.
2 //!
3 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
4
5 use crate::mir::coverage::{CodeRegion, CoverageKind};
6 use crate::mir::interpret::{Allocation, GlobalAlloc, Scalar};
7 use crate::mir::visit::MirVisitable;
8 use crate::ty::adjustment::PointerCast;
9 use crate::ty::codec::{TyDecoder, TyEncoder};
10 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
11 use crate::ty::print::{FmtPrinter, Printer};
12 use crate::ty::subst::{Subst, SubstsRef};
13 use crate::ty::{self, List, Ty, TyCtxt};
14 use crate::ty::{AdtDef, InstanceDef, Region, ScalarInt, UserTypeAnnotationIndex};
15 use rustc_hir as hir;
16 use rustc_hir::def::{CtorKind, Namespace};
17 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
18 use rustc_hir::{self, GeneratorKind};
19 use rustc_target::abi::{Size, VariantIdx};
20
21 use polonius_engine::Atom;
22 pub use rustc_ast::Mutability;
23 use rustc_data_structures::fx::FxHashSet;
24 use rustc_data_structures::graph::dominators::{dominators, Dominators};
25 use rustc_data_structures::graph::{self, GraphSuccessors};
26 use rustc_index::bit_set::BitMatrix;
27 use rustc_index::vec::{Idx, IndexVec};
28 use rustc_serialize::{Decodable, Encodable};
29 use rustc_span::symbol::Symbol;
30 use rustc_span::{Span, DUMMY_SP};
31 use rustc_target::asm::InlineAsmRegOrRegClass;
32 use std::borrow::Cow;
33 use std::convert::TryInto;
34 use std::fmt::{self, Debug, Display, Formatter, Write};
35 use std::ops::{ControlFlow, Index, IndexMut};
36 use std::slice;
37 use std::{iter, mem, option};
38
39 use self::graph_cyclic_cache::GraphIsCyclicCache;
40 use self::predecessors::{PredecessorCache, Predecessors};
41 pub use self::query::*;
42
43 pub mod abstract_const;
44 pub mod coverage;
45 mod graph_cyclic_cache;
46 pub mod interpret;
47 pub mod mono;
48 mod predecessors;
49 mod query;
50 pub mod tcx;
51 pub mod terminator;
52 pub use terminator::*;
53 pub mod traversal;
54 mod type_foldable;
55 pub mod visit;
56
57 /// Types for locals
58 pub type LocalDecls<'tcx> = IndexVec<Local, LocalDecl<'tcx>>;
59
60 pub trait HasLocalDecls<'tcx> {
61     fn local_decls(&self) -> &LocalDecls<'tcx>;
62 }
63
64 impl<'tcx> HasLocalDecls<'tcx> for LocalDecls<'tcx> {
65     #[inline]
66     fn local_decls(&self) -> &LocalDecls<'tcx> {
67         self
68     }
69 }
70
71 impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
72     #[inline]
73     fn local_decls(&self) -> &LocalDecls<'tcx> {
74         &self.local_decls
75     }
76 }
77
78 /// The various "big phases" that MIR goes through.
79 ///
80 /// These phases all describe dialects of MIR. Since all MIR uses the same datastructures, the
81 /// dialects forbid certain variants or values in certain phases.
82 ///
83 /// Note: Each phase's validation checks all invariants of the *previous* phases' dialects. A phase
84 /// that changes the dialect documents what invariants must be upheld *after* that phase finishes.
85 ///
86 /// Warning: ordering of variants is significant.
87 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
88 #[derive(HashStable)]
89 pub enum MirPhase {
90     Build = 0,
91     // FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query).
92     // We used to have this for pre-miri MIR based const eval.
93     Const = 1,
94     /// This phase checks the MIR for promotable elements and takes them out of the main MIR body
95     /// by creating a new MIR body per promoted element. After this phase (and thus the termination
96     /// of the `mir_promoted` query), these promoted elements are available in the `promoted_mir`
97     /// query.
98     ConstPromotion = 2,
99     /// After this phase
100     /// * the only `AggregateKind`s allowed are `Array` and `Generator`,
101     /// * `DropAndReplace` is gone for good
102     /// * `Drop` now uses explicit drop flags visible in the MIR and reaching a `Drop` terminator
103     ///   means that the auto-generated drop glue will be invoked.
104     DropLowering = 3,
105     /// After this phase, generators are explicit state machines (no more `Yield`).
106     /// `AggregateKind::Generator` is gone for good.
107     GeneratorLowering = 4,
108     Optimization = 5,
109 }
110
111 impl MirPhase {
112     /// Gets the index of the current MirPhase within the set of all `MirPhase`s.
113     pub fn phase_index(&self) -> usize {
114         *self as usize
115     }
116 }
117
118 /// Where a specific `mir::Body` comes from.
119 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
120 #[derive(HashStable, TyEncodable, TyDecodable, TypeFoldable)]
121 pub struct MirSource<'tcx> {
122     pub instance: InstanceDef<'tcx>,
123
124     /// If `Some`, this is a promoted rvalue within the parent function.
125     pub promoted: Option<Promoted>,
126 }
127
128 impl<'tcx> MirSource<'tcx> {
129     pub fn item(def_id: DefId) -> Self {
130         MirSource {
131             instance: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
132             promoted: None,
133         }
134     }
135
136     pub fn from_instance(instance: InstanceDef<'tcx>) -> Self {
137         MirSource { instance, promoted: None }
138     }
139
140     pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> {
141         self.instance.with_opt_param()
142     }
143
144     #[inline]
145     pub fn def_id(&self) -> DefId {
146         self.instance.def_id()
147     }
148 }
149
150 #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)]
151 pub struct GeneratorInfo<'tcx> {
152     /// The yield type of the function, if it is a generator.
153     pub yield_ty: Option<Ty<'tcx>>,
154
155     /// Generator drop glue.
156     pub generator_drop: Option<Body<'tcx>>,
157
158     /// The layout of a generator. Produced by the state transformation.
159     pub generator_layout: Option<GeneratorLayout<'tcx>>,
160
161     /// If this is a generator then record the type of source expression that caused this generator
162     /// to be created.
163     pub generator_kind: GeneratorKind,
164 }
165
166 /// The lowered representation of a single function.
167 #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)]
168 pub struct Body<'tcx> {
169     /// A list of basic blocks. References to basic block use a newtyped index type [`BasicBlock`]
170     /// that indexes into this vector.
171     basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
172
173     /// Records how far through the "desugaring and optimization" process this particular
174     /// MIR has traversed. This is particularly useful when inlining, since in that context
175     /// we instantiate the promoted constants and add them to our promoted vector -- but those
176     /// promoted items have already been optimized, whereas ours have not. This field allows
177     /// us to see the difference and forego optimization on the inlined promoted items.
178     pub phase: MirPhase,
179
180     pub source: MirSource<'tcx>,
181
182     /// A list of source scopes; these are referenced by statements
183     /// and used for debuginfo. Indexed by a `SourceScope`.
184     pub source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
185
186     pub generator: Option<Box<GeneratorInfo<'tcx>>>,
187
188     /// Declarations of locals.
189     ///
190     /// The first local is the return value pointer, followed by `arg_count`
191     /// locals for the function arguments, followed by any user-declared
192     /// variables and temporaries.
193     pub local_decls: LocalDecls<'tcx>,
194
195     /// User type annotations.
196     pub user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
197
198     /// The number of arguments this function takes.
199     ///
200     /// Starting at local 1, `arg_count` locals will be provided by the caller
201     /// and can be assumed to be initialized.
202     ///
203     /// If this MIR was built for a constant, this will be 0.
204     pub arg_count: usize,
205
206     /// Mark an argument local (which must be a tuple) as getting passed as
207     /// its individual components at the LLVM level.
208     ///
209     /// This is used for the "rust-call" ABI.
210     pub spread_arg: Option<Local>,
211
212     /// Debug information pertaining to user variables, including captures.
213     pub var_debug_info: Vec<VarDebugInfo<'tcx>>,
214
215     /// A span representing this MIR, for error reporting.
216     pub span: Span,
217
218     /// Constants that are required to evaluate successfully for this MIR to be well-formed.
219     /// We hold in this field all the constants we are not able to evaluate yet.
220     pub required_consts: Vec<Constant<'tcx>>,
221
222     /// Does this body use generic parameters. This is used for the `ConstEvaluatable` check.
223     ///
224     /// Note that this does not actually mean that this body is not computable right now.
225     /// The repeat count in the following example is polymorphic, but can still be evaluated
226     /// without knowing anything about the type parameter `T`.
227     ///
228     /// ```rust
229     /// fn test<T>() {
230     ///     let _ = [0; std::mem::size_of::<*mut T>()];
231     /// }
232     /// ```
233     ///
234     /// **WARNING**: Do not change this flags after the MIR was originally created, even if an optimization
235     /// removed the last mention of all generic params. We do not want to rely on optimizations and
236     /// potentially allow things like `[u8; std::mem::size_of::<T>() * 0]` due to this.
237     pub is_polymorphic: bool,
238
239     predecessor_cache: PredecessorCache,
240     is_cyclic: GraphIsCyclicCache,
241 }
242
243 impl<'tcx> Body<'tcx> {
244     pub fn new(
245         source: MirSource<'tcx>,
246         basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
247         source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
248         local_decls: LocalDecls<'tcx>,
249         user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
250         arg_count: usize,
251         var_debug_info: Vec<VarDebugInfo<'tcx>>,
252         span: Span,
253         generator_kind: Option<GeneratorKind>,
254     ) -> Self {
255         // We need `arg_count` locals, and one for the return place.
256         assert!(
257             local_decls.len() > arg_count,
258             "expected at least {} locals, got {}",
259             arg_count + 1,
260             local_decls.len()
261         );
262
263         let mut body = Body {
264             phase: MirPhase::Build,
265             source,
266             basic_blocks,
267             source_scopes,
268             generator: generator_kind.map(|generator_kind| {
269                 Box::new(GeneratorInfo {
270                     yield_ty: None,
271                     generator_drop: None,
272                     generator_layout: None,
273                     generator_kind,
274                 })
275             }),
276             local_decls,
277             user_type_annotations,
278             arg_count,
279             spread_arg: None,
280             var_debug_info,
281             span,
282             required_consts: Vec::new(),
283             is_polymorphic: false,
284             predecessor_cache: PredecessorCache::new(),
285             is_cyclic: GraphIsCyclicCache::new(),
286         };
287         body.is_polymorphic = body.has_param_types_or_consts();
288         body
289     }
290
291     /// Returns a partially initialized MIR body containing only a list of basic blocks.
292     ///
293     /// The returned MIR contains no `LocalDecl`s (even for the return place) or source scopes. It
294     /// is only useful for testing but cannot be `#[cfg(test)]` because it is used in a different
295     /// crate.
296     pub fn new_cfg_only(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self {
297         let mut body = Body {
298             phase: MirPhase::Build,
299             source: MirSource::item(DefId::local(CRATE_DEF_INDEX)),
300             basic_blocks,
301             source_scopes: IndexVec::new(),
302             generator: None,
303             local_decls: IndexVec::new(),
304             user_type_annotations: IndexVec::new(),
305             arg_count: 0,
306             spread_arg: None,
307             span: DUMMY_SP,
308             required_consts: Vec::new(),
309             var_debug_info: Vec::new(),
310             is_polymorphic: false,
311             predecessor_cache: PredecessorCache::new(),
312             is_cyclic: GraphIsCyclicCache::new(),
313         };
314         body.is_polymorphic = body.has_param_types_or_consts();
315         body
316     }
317
318     #[inline]
319     pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
320         &self.basic_blocks
321     }
322
323     #[inline]
324     pub fn basic_blocks_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
325         // Because the user could mutate basic block terminators via this reference, we need to
326         // invalidate the caches.
327         //
328         // FIXME: Use a finer-grained API for this, so only transformations that alter terminators
329         // invalidate the caches.
330         self.predecessor_cache.invalidate();
331         self.is_cyclic.invalidate();
332         &mut self.basic_blocks
333     }
334
335     #[inline]
336     pub fn basic_blocks_and_local_decls_mut(
337         &mut self,
338     ) -> (&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, &mut LocalDecls<'tcx>) {
339         self.predecessor_cache.invalidate();
340         self.is_cyclic.invalidate();
341         (&mut self.basic_blocks, &mut self.local_decls)
342     }
343
344     #[inline]
345     pub fn basic_blocks_local_decls_mut_and_var_debug_info(
346         &mut self,
347     ) -> (
348         &mut IndexVec<BasicBlock, BasicBlockData<'tcx>>,
349         &mut LocalDecls<'tcx>,
350         &mut Vec<VarDebugInfo<'tcx>>,
351     ) {
352         self.predecessor_cache.invalidate();
353         self.is_cyclic.invalidate();
354         (&mut self.basic_blocks, &mut self.local_decls, &mut self.var_debug_info)
355     }
356
357     /// Returns `true` if a cycle exists in the control-flow graph that is reachable from the
358     /// `START_BLOCK`.
359     pub fn is_cfg_cyclic(&self) -> bool {
360         self.is_cyclic.is_cyclic(self)
361     }
362
363     #[inline]
364     pub fn local_kind(&self, local: Local) -> LocalKind {
365         let index = local.as_usize();
366         if index == 0 {
367             debug_assert!(
368                 self.local_decls[local].mutability == Mutability::Mut,
369                 "return place should be mutable"
370             );
371
372             LocalKind::ReturnPointer
373         } else if index < self.arg_count + 1 {
374             LocalKind::Arg
375         } else if self.local_decls[local].is_user_variable() {
376             LocalKind::Var
377         } else {
378             LocalKind::Temp
379         }
380     }
381
382     /// Returns an iterator over all user-declared mutable locals.
383     #[inline]
384     pub fn mut_vars_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
385         (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
386             let local = Local::new(index);
387             let decl = &self.local_decls[local];
388             if decl.is_user_variable() && decl.mutability == Mutability::Mut {
389                 Some(local)
390             } else {
391                 None
392             }
393         })
394     }
395
396     /// Returns an iterator over all user-declared mutable arguments and locals.
397     #[inline]
398     pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
399         (1..self.local_decls.len()).filter_map(move |index| {
400             let local = Local::new(index);
401             let decl = &self.local_decls[local];
402             if (decl.is_user_variable() || index < self.arg_count + 1)
403                 && decl.mutability == Mutability::Mut
404             {
405                 Some(local)
406             } else {
407                 None
408             }
409         })
410     }
411
412     /// Returns an iterator over all function arguments.
413     #[inline]
414     pub fn args_iter(&self) -> impl Iterator<Item = Local> + ExactSizeIterator {
415         let arg_count = self.arg_count;
416         (1..arg_count + 1).map(Local::new)
417     }
418
419     /// Returns an iterator over all user-defined variables and compiler-generated temporaries (all
420     /// locals that are neither arguments nor the return place).
421     #[inline]
422     pub fn vars_and_temps_iter(
423         &self,
424     ) -> impl DoubleEndedIterator<Item = Local> + ExactSizeIterator {
425         let arg_count = self.arg_count;
426         let local_count = self.local_decls.len();
427         (arg_count + 1..local_count).map(Local::new)
428     }
429
430     /// Changes a statement to a nop. This is both faster than deleting instructions and avoids
431     /// invalidating statement indices in `Location`s.
432     pub fn make_statement_nop(&mut self, location: Location) {
433         let block = &mut self.basic_blocks[location.block];
434         debug_assert!(location.statement_index < block.statements.len());
435         block.statements[location.statement_index].make_nop()
436     }
437
438     /// Returns the source info associated with `location`.
439     pub fn source_info(&self, location: Location) -> &SourceInfo {
440         let block = &self[location.block];
441         let stmts = &block.statements;
442         let idx = location.statement_index;
443         if idx < stmts.len() {
444             &stmts[idx].source_info
445         } else {
446             assert_eq!(idx, stmts.len());
447             &block.terminator().source_info
448         }
449     }
450
451     /// Returns the return type; it always return first element from `local_decls` array.
452     #[inline]
453     pub fn return_ty(&self) -> Ty<'tcx> {
454         self.local_decls[RETURN_PLACE].ty
455     }
456
457     /// Gets the location of the terminator for the given block.
458     #[inline]
459     pub fn terminator_loc(&self, bb: BasicBlock) -> Location {
460         Location { block: bb, statement_index: self[bb].statements.len() }
461     }
462
463     #[inline]
464     pub fn predecessors(&self) -> impl std::ops::Deref<Target = Predecessors> + '_ {
465         self.predecessor_cache.compute(&self.basic_blocks)
466     }
467
468     #[inline]
469     pub fn dominators(&self) -> Dominators<BasicBlock> {
470         dominators(self)
471     }
472
473     #[inline]
474     pub fn yield_ty(&self) -> Option<Ty<'tcx>> {
475         self.generator.as_ref().and_then(|generator| generator.yield_ty)
476     }
477
478     #[inline]
479     pub fn generator_layout(&self) -> Option<&GeneratorLayout<'tcx>> {
480         self.generator.as_ref().and_then(|generator| generator.generator_layout.as_ref())
481     }
482
483     #[inline]
484     pub fn generator_drop(&self) -> Option<&Body<'tcx>> {
485         self.generator.as_ref().and_then(|generator| generator.generator_drop.as_ref())
486     }
487
488     #[inline]
489     pub fn generator_kind(&self) -> Option<GeneratorKind> {
490         self.generator.as_ref().map(|generator| generator.generator_kind)
491     }
492 }
493
494 #[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
495 pub enum Safety {
496     Safe,
497     /// Unsafe because of a PushUnsafeBlock
498     BuiltinUnsafe,
499     /// Unsafe because of an unsafe fn
500     FnUnsafe,
501     /// Unsafe because of an `unsafe` block
502     ExplicitUnsafe(hir::HirId),
503 }
504
505 impl<'tcx> Index<BasicBlock> for Body<'tcx> {
506     type Output = BasicBlockData<'tcx>;
507
508     #[inline]
509     fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> {
510         &self.basic_blocks()[index]
511     }
512 }
513
514 impl<'tcx> IndexMut<BasicBlock> for Body<'tcx> {
515     #[inline]
516     fn index_mut(&mut self, index: BasicBlock) -> &mut BasicBlockData<'tcx> {
517         &mut self.basic_blocks_mut()[index]
518     }
519 }
520
521 #[derive(Copy, Clone, Debug, HashStable, TypeFoldable)]
522 pub enum ClearCrossCrate<T> {
523     Clear,
524     Set(T),
525 }
526
527 impl<T> ClearCrossCrate<T> {
528     pub fn as_ref(&self) -> ClearCrossCrate<&T> {
529         match self {
530             ClearCrossCrate::Clear => ClearCrossCrate::Clear,
531             ClearCrossCrate::Set(v) => ClearCrossCrate::Set(v),
532         }
533     }
534
535     pub fn assert_crate_local(self) -> T {
536         match self {
537             ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"),
538             ClearCrossCrate::Set(v) => v,
539         }
540     }
541 }
542
543 const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
544 const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
545
546 impl<'tcx, E: TyEncoder<'tcx>, T: Encodable<E>> Encodable<E> for ClearCrossCrate<T> {
547     #[inline]
548     fn encode(&self, e: &mut E) -> Result<(), E::Error> {
549         if E::CLEAR_CROSS_CRATE {
550             return Ok(());
551         }
552
553         match *self {
554             ClearCrossCrate::Clear => TAG_CLEAR_CROSS_CRATE_CLEAR.encode(e),
555             ClearCrossCrate::Set(ref val) => {
556                 TAG_CLEAR_CROSS_CRATE_SET.encode(e)?;
557                 val.encode(e)
558             }
559         }
560     }
561 }
562 impl<'tcx, D: TyDecoder<'tcx>, T: Decodable<D>> Decodable<D> for ClearCrossCrate<T> {
563     #[inline]
564     fn decode(d: &mut D) -> Result<ClearCrossCrate<T>, D::Error> {
565         if D::CLEAR_CROSS_CRATE {
566             return Ok(ClearCrossCrate::Clear);
567         }
568
569         let discr = u8::decode(d)?;
570
571         match discr {
572             TAG_CLEAR_CROSS_CRATE_CLEAR => Ok(ClearCrossCrate::Clear),
573             TAG_CLEAR_CROSS_CRATE_SET => {
574                 let val = T::decode(d)?;
575                 Ok(ClearCrossCrate::Set(val))
576             }
577             tag => Err(d.error(&format!("Invalid tag for ClearCrossCrate: {:?}", tag))),
578         }
579     }
580 }
581
582 /// Grouped information about the source code origin of a MIR entity.
583 /// Intended to be inspected by diagnostics and debuginfo.
584 /// Most passes can work with it as a whole, within a single function.
585 // The unofficial Cranelift backend, at least as of #65828, needs `SourceInfo` to implement `Eq` and
586 // `Hash`. Please ping @bjorn3 if removing them.
587 #[derive(Copy, Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
588 pub struct SourceInfo {
589     /// The source span for the AST pertaining to this MIR entity.
590     pub span: Span,
591
592     /// The source scope, keeping track of which bindings can be
593     /// seen by debuginfo, active lint levels, `unsafe {...}`, etc.
594     pub scope: SourceScope,
595 }
596
597 impl SourceInfo {
598     #[inline]
599     pub fn outermost(span: Span) -> Self {
600         SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }
601     }
602 }
603
604 ///////////////////////////////////////////////////////////////////////////
605 // Borrow kinds
606
607 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)]
608 #[derive(Hash, HashStable)]
609 pub enum BorrowKind {
610     /// Data must be immutable and is aliasable.
611     Shared,
612
613     /// The immediately borrowed place must be immutable, but projections from
614     /// it don't need to be. For example, a shallow borrow of `a.b` doesn't
615     /// conflict with a mutable borrow of `a.b.c`.
616     ///
617     /// This is used when lowering matches: when matching on a place we want to
618     /// ensure that place have the same value from the start of the match until
619     /// an arm is selected. This prevents this code from compiling:
620     ///
621     ///     let mut x = &Some(0);
622     ///     match *x {
623     ///         None => (),
624     ///         Some(_) if { x = &None; false } => (),
625     ///         Some(_) => (),
626     ///     }
627     ///
628     /// This can't be a shared borrow because mutably borrowing (*x as Some).0
629     /// should not prevent `if let None = x { ... }`, for example, because the
630     /// mutating `(*x as Some).0` can't affect the discriminant of `x`.
631     /// We can also report errors with this kind of borrow differently.
632     Shallow,
633
634     /// Data must be immutable but not aliasable. This kind of borrow
635     /// cannot currently be expressed by the user and is used only in
636     /// implicit closure bindings. It is needed when the closure is
637     /// borrowing or mutating a mutable referent, e.g.:
638     ///
639     ///     let x: &mut isize = ...;
640     ///     let y = || *x += 5;
641     ///
642     /// If we were to try to translate this closure into a more explicit
643     /// form, we'd encounter an error with the code as written:
644     ///
645     ///     struct Env { x: & &mut isize }
646     ///     let x: &mut isize = ...;
647     ///     let y = (&mut Env { &x }, fn_ptr);  // Closure is pair of env and fn
648     ///     fn fn_ptr(env: &mut Env) { **env.x += 5; }
649     ///
650     /// This is then illegal because you cannot mutate an `&mut` found
651     /// in an aliasable location. To solve, you'd have to translate with
652     /// an `&mut` borrow:
653     ///
654     ///     struct Env { x: & &mut isize }
655     ///     let x: &mut isize = ...;
656     ///     let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
657     ///     fn fn_ptr(env: &mut Env) { **env.x += 5; }
658     ///
659     /// Now the assignment to `**env.x` is legal, but creating a
660     /// mutable pointer to `x` is not because `x` is not mutable. We
661     /// could fix this by declaring `x` as `let mut x`. This is ok in
662     /// user code, if awkward, but extra weird for closures, since the
663     /// borrow is hidden.
664     ///
665     /// So we introduce a "unique imm" borrow -- the referent is
666     /// immutable, but not aliasable. This solves the problem. For
667     /// simplicity, we don't give users the way to express this
668     /// borrow, it's just used when translating closures.
669     Unique,
670
671     /// Data is mutable and not aliasable.
672     Mut {
673         /// `true` if this borrow arose from method-call auto-ref
674         /// (i.e., `adjustment::Adjust::Borrow`).
675         allow_two_phase_borrow: bool,
676     },
677 }
678
679 impl BorrowKind {
680     pub fn allows_two_phase_borrow(&self) -> bool {
681         match *self {
682             BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => false,
683             BorrowKind::Mut { allow_two_phase_borrow } => allow_two_phase_borrow,
684         }
685     }
686 }
687
688 ///////////////////////////////////////////////////////////////////////////
689 // Variables and temps
690
691 rustc_index::newtype_index! {
692     pub struct Local {
693         derive [HashStable]
694         DEBUG_FORMAT = "_{}",
695         const RETURN_PLACE = 0,
696     }
697 }
698
699 impl Atom for Local {
700     fn index(self) -> usize {
701         Idx::index(self)
702     }
703 }
704
705 /// Classifies locals into categories. See `Body::local_kind`.
706 #[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
707 pub enum LocalKind {
708     /// User-declared variable binding.
709     Var,
710     /// Compiler-introduced temporary.
711     Temp,
712     /// Function argument.
713     Arg,
714     /// Location of function's return value.
715     ReturnPointer,
716 }
717
718 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
719 pub struct VarBindingForm<'tcx> {
720     /// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`?
721     pub binding_mode: ty::BindingMode,
722     /// If an explicit type was provided for this variable binding,
723     /// this holds the source Span of that type.
724     ///
725     /// NOTE: if you want to change this to a `HirId`, be wary that
726     /// doing so breaks incremental compilation (as of this writing),
727     /// while a `Span` does not cause our tests to fail.
728     pub opt_ty_info: Option<Span>,
729     /// Place of the RHS of the =, or the subject of the `match` where this
730     /// variable is initialized. None in the case of `let PATTERN;`.
731     /// Some((None, ..)) in the case of and `let [mut] x = ...` because
732     /// (a) the right-hand side isn't evaluated as a place expression.
733     /// (b) it gives a way to separate this case from the remaining cases
734     ///     for diagnostics.
735     pub opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
736     /// The span of the pattern in which this variable was bound.
737     pub pat_span: Span,
738 }
739
740 #[derive(Clone, Debug, TyEncodable, TyDecodable)]
741 pub enum BindingForm<'tcx> {
742     /// This is a binding for a non-`self` binding, or a `self` that has an explicit type.
743     Var(VarBindingForm<'tcx>),
744     /// Binding for a `self`/`&self`/`&mut self` binding where the type is implicit.
745     ImplicitSelf(ImplicitSelfKind),
746     /// Reference used in a guard expression to ensure immutability.
747     RefForGuard,
748 }
749
750 /// Represents what type of implicit self a function has, if any.
751 #[derive(Clone, Copy, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
752 pub enum ImplicitSelfKind {
753     /// Represents a `fn x(self);`.
754     Imm,
755     /// Represents a `fn x(mut self);`.
756     Mut,
757     /// Represents a `fn x(&self);`.
758     ImmRef,
759     /// Represents a `fn x(&mut self);`.
760     MutRef,
761     /// Represents when a function does not have a self argument or
762     /// when a function has a `self: X` argument.
763     None,
764 }
765
766 TrivialTypeFoldableAndLiftImpls! { BindingForm<'tcx>, }
767
768 mod binding_form_impl {
769     use crate::ich::StableHashingContext;
770     use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
771
772     impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for super::BindingForm<'tcx> {
773         fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
774             use super::BindingForm::*;
775             std::mem::discriminant(self).hash_stable(hcx, hasher);
776
777             match self {
778                 Var(binding) => binding.hash_stable(hcx, hasher),
779                 ImplicitSelf(kind) => kind.hash_stable(hcx, hasher),
780                 RefForGuard => (),
781             }
782         }
783     }
784 }
785
786 /// `BlockTailInfo` is attached to the `LocalDecl` for temporaries
787 /// created during evaluation of expressions in a block tail
788 /// expression; that is, a block like `{ STMT_1; STMT_2; EXPR }`.
789 ///
790 /// It is used to improve diagnostics when such temporaries are
791 /// involved in borrow_check errors, e.g., explanations of where the
792 /// temporaries come from, when their destructors are run, and/or how
793 /// one might revise the code to satisfy the borrow checker's rules.
794 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
795 pub struct BlockTailInfo {
796     /// If `true`, then the value resulting from evaluating this tail
797     /// expression is ignored by the block's expression context.
798     ///
799     /// Examples include `{ ...; tail };` and `let _ = { ...; tail };`
800     /// but not e.g., `let _x = { ...; tail };`
801     pub tail_result_is_ignored: bool,
802
803     /// `Span` of the tail expression.
804     pub span: Span,
805 }
806
807 /// A MIR local.
808 ///
809 /// This can be a binding declared by the user, a temporary inserted by the compiler, a function
810 /// argument, or the return place.
811 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
812 pub struct LocalDecl<'tcx> {
813     /// Whether this is a mutable binding (i.e., `let x` or `let mut x`).
814     ///
815     /// Temporaries and the return place are always mutable.
816     pub mutability: Mutability,
817
818     // FIXME(matthewjasper) Don't store in this in `Body`
819     pub local_info: Option<Box<LocalInfo<'tcx>>>,
820
821     /// `true` if this is an internal local.
822     ///
823     /// These locals are not based on types in the source code and are only used
824     /// for a few desugarings at the moment.
825     ///
826     /// The generator transformation will sanity check the locals which are live
827     /// across a suspension point against the type components of the generator
828     /// which type checking knows are live across a suspension point. We need to
829     /// flag drop flags to avoid triggering this check as they are introduced
830     /// after typeck.
831     ///
832     /// This should be sound because the drop flags are fully algebraic, and
833     /// therefore don't affect the auto-trait or outlives properties of the
834     /// generator.
835     pub internal: bool,
836
837     /// If this local is a temporary and `is_block_tail` is `Some`,
838     /// then it is a temporary created for evaluation of some
839     /// subexpression of some block's tail expression (with no
840     /// intervening statement context).
841     // FIXME(matthewjasper) Don't store in this in `Body`
842     pub is_block_tail: Option<BlockTailInfo>,
843
844     /// The type of this local.
845     pub ty: Ty<'tcx>,
846
847     /// If the user manually ascribed a type to this variable,
848     /// e.g., via `let x: T`, then we carry that type here. The MIR
849     /// borrow checker needs this information since it can affect
850     /// region inference.
851     // FIXME(matthewjasper) Don't store in this in `Body`
852     pub user_ty: Option<Box<UserTypeProjections>>,
853
854     /// The *syntactic* (i.e., not visibility) source scope the local is defined
855     /// in. If the local was defined in a let-statement, this
856     /// is *within* the let-statement, rather than outside
857     /// of it.
858     ///
859     /// This is needed because the visibility source scope of locals within
860     /// a let-statement is weird.
861     ///
862     /// The reason is that we want the local to be *within* the let-statement
863     /// for lint purposes, but we want the local to be *after* the let-statement
864     /// for names-in-scope purposes.
865     ///
866     /// That's it, if we have a let-statement like the one in this
867     /// function:
868     ///
869     /// ```
870     /// fn foo(x: &str) {
871     ///     #[allow(unused_mut)]
872     ///     let mut x: u32 = { // <- one unused mut
873     ///         let mut y: u32 = x.parse().unwrap();
874     ///         y + 2
875     ///     };
876     ///     drop(x);
877     /// }
878     /// ```
879     ///
880     /// Then, from a lint point of view, the declaration of `x: u32`
881     /// (and `y: u32`) are within the `#[allow(unused_mut)]` scope - the
882     /// lint scopes are the same as the AST/HIR nesting.
883     ///
884     /// However, from a name lookup point of view, the scopes look more like
885     /// as if the let-statements were `match` expressions:
886     ///
887     /// ```
888     /// fn foo(x: &str) {
889     ///     match {
890     ///         match x.parse().unwrap() {
891     ///             y => y + 2
892     ///         }
893     ///     } {
894     ///         x => drop(x)
895     ///     };
896     /// }
897     /// ```
898     ///
899     /// We care about the name-lookup scopes for debuginfo - if the
900     /// debuginfo instruction pointer is at the call to `x.parse()`, we
901     /// want `x` to refer to `x: &str`, but if it is at the call to
902     /// `drop(x)`, we want it to refer to `x: u32`.
903     ///
904     /// To allow both uses to work, we need to have more than a single scope
905     /// for a local. We have the `source_info.scope` represent the "syntactic"
906     /// lint scope (with a variable being under its let block) while the
907     /// `var_debug_info.source_info.scope` represents the "local variable"
908     /// scope (where the "rest" of a block is under all prior let-statements).
909     ///
910     /// The end result looks like this:
911     ///
912     /// ```text
913     /// ROOT SCOPE
914     ///  │{ argument x: &str }
915     ///  │
916     ///  │ │{ #[allow(unused_mut)] } // This is actually split into 2 scopes
917     ///  │ │                         // in practice because I'm lazy.
918     ///  │ │
919     ///  │ │← x.source_info.scope
920     ///  │ │← `x.parse().unwrap()`
921     ///  │ │
922     ///  │ │ │← y.source_info.scope
923     ///  │ │
924     ///  │ │ │{ let y: u32 }
925     ///  │ │ │
926     ///  │ │ │← y.var_debug_info.source_info.scope
927     ///  │ │ │← `y + 2`
928     ///  │
929     ///  │ │{ let x: u32 }
930     ///  │ │← x.var_debug_info.source_info.scope
931     ///  │ │← `drop(x)` // This accesses `x: u32`.
932     /// ```
933     pub source_info: SourceInfo,
934 }
935
936 // `LocalDecl` is used a lot. Make sure it doesn't unintentionally get bigger.
937 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
938 static_assert_size!(LocalDecl<'_>, 56);
939
940 /// Extra information about a some locals that's used for diagnostics and for
941 /// classifying variables into local variables, statics, etc, which is needed e.g.
942 /// for unsafety checking.
943 ///
944 /// Not used for non-StaticRef temporaries, the return place, or anonymous
945 /// function parameters.
946 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
947 pub enum LocalInfo<'tcx> {
948     /// A user-defined local variable or function parameter
949     ///
950     /// The `BindingForm` is solely used for local diagnostics when generating
951     /// warnings/errors when compiling the current crate, and therefore it need
952     /// not be visible across crates.
953     User(ClearCrossCrate<BindingForm<'tcx>>),
954     /// A temporary created that references the static with the given `DefId`.
955     StaticRef { def_id: DefId, is_thread_local: bool },
956     /// A temporary created that references the const with the given `DefId`
957     ConstRef { def_id: DefId },
958 }
959
960 impl<'tcx> LocalDecl<'tcx> {
961     /// Returns `true` only if local is a binding that can itself be
962     /// made mutable via the addition of the `mut` keyword, namely
963     /// something like the occurrences of `x` in:
964     /// - `fn foo(x: Type) { ... }`,
965     /// - `let x = ...`,
966     /// - or `match ... { C(x) => ... }`
967     pub fn can_be_made_mutable(&self) -> bool {
968         matches!(
969             self.local_info,
970             Some(box LocalInfo::User(ClearCrossCrate::Set(
971                 BindingForm::Var(VarBindingForm {
972                     binding_mode: ty::BindingMode::BindByValue(_),
973                     opt_ty_info: _,
974                     opt_match_place: _,
975                     pat_span: _,
976                 }) | BindingForm::ImplicitSelf(ImplicitSelfKind::Imm),
977             )))
978         )
979     }
980
981     /// Returns `true` if local is definitely not a `ref ident` or
982     /// `ref mut ident` binding. (Such bindings cannot be made into
983     /// mutable bindings, but the inverse does not necessarily hold).
984     pub fn is_nonref_binding(&self) -> bool {
985         matches!(
986             self.local_info,
987             Some(box LocalInfo::User(ClearCrossCrate::Set(
988                 BindingForm::Var(VarBindingForm {
989                     binding_mode: ty::BindingMode::BindByValue(_),
990                     opt_ty_info: _,
991                     opt_match_place: _,
992                     pat_span: _,
993                 }) | BindingForm::ImplicitSelf(_),
994             )))
995         )
996     }
997
998     /// Returns `true` if this variable is a named variable or function
999     /// parameter declared by the user.
1000     #[inline]
1001     pub fn is_user_variable(&self) -> bool {
1002         matches!(self.local_info, Some(box LocalInfo::User(_)))
1003     }
1004
1005     /// Returns `true` if this is a reference to a variable bound in a `match`
1006     /// expression that is used to access said variable for the guard of the
1007     /// match arm.
1008     pub fn is_ref_for_guard(&self) -> bool {
1009         matches!(
1010             self.local_info,
1011             Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard)))
1012         )
1013     }
1014
1015     /// Returns `Some` if this is a reference to a static item that is used to
1016     /// access that static.
1017     pub fn is_ref_to_static(&self) -> bool {
1018         matches!(self.local_info, Some(box LocalInfo::StaticRef { .. }))
1019     }
1020
1021     /// Returns `Some` if this is a reference to a thread-local static item that is used to
1022     /// access that static.
1023     pub fn is_ref_to_thread_local(&self) -> bool {
1024         match self.local_info {
1025             Some(box LocalInfo::StaticRef { is_thread_local, .. }) => is_thread_local,
1026             _ => false,
1027         }
1028     }
1029
1030     /// Returns `true` is the local is from a compiler desugaring, e.g.,
1031     /// `__next` from a `for` loop.
1032     #[inline]
1033     pub fn from_compiler_desugaring(&self) -> bool {
1034         self.source_info.span.desugaring_kind().is_some()
1035     }
1036
1037     /// Creates a new `LocalDecl` for a temporary: mutable, non-internal.
1038     #[inline]
1039     pub fn new(ty: Ty<'tcx>, span: Span) -> Self {
1040         Self::with_source_info(ty, SourceInfo::outermost(span))
1041     }
1042
1043     /// Like `LocalDecl::new`, but takes a `SourceInfo` instead of a `Span`.
1044     #[inline]
1045     pub fn with_source_info(ty: Ty<'tcx>, source_info: SourceInfo) -> Self {
1046         LocalDecl {
1047             mutability: Mutability::Mut,
1048             local_info: None,
1049             internal: false,
1050             is_block_tail: None,
1051             ty,
1052             user_ty: None,
1053             source_info,
1054         }
1055     }
1056
1057     /// Converts `self` into same `LocalDecl` except tagged as internal.
1058     #[inline]
1059     pub fn internal(mut self) -> Self {
1060         self.internal = true;
1061         self
1062     }
1063
1064     /// Converts `self` into same `LocalDecl` except tagged as immutable.
1065     #[inline]
1066     pub fn immutable(mut self) -> Self {
1067         self.mutability = Mutability::Not;
1068         self
1069     }
1070
1071     /// Converts `self` into same `LocalDecl` except tagged as internal temporary.
1072     #[inline]
1073     pub fn block_tail(mut self, info: BlockTailInfo) -> Self {
1074         assert!(self.is_block_tail.is_none());
1075         self.is_block_tail = Some(info);
1076         self
1077     }
1078 }
1079
1080 #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
1081 pub enum VarDebugInfoContents<'tcx> {
1082     /// NOTE(eddyb) There's an unenforced invariant that this `Place` is
1083     /// based on a `Local`, not a `Static`, and contains no indexing.
1084     Place(Place<'tcx>),
1085     Const(Constant<'tcx>),
1086 }
1087
1088 impl<'tcx> Debug for VarDebugInfoContents<'tcx> {
1089     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
1090         match self {
1091             VarDebugInfoContents::Const(c) => write!(fmt, "{}", c),
1092             VarDebugInfoContents::Place(p) => write!(fmt, "{:?}", p),
1093         }
1094     }
1095 }
1096
1097 /// Debug information pertaining to a user variable.
1098 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
1099 pub struct VarDebugInfo<'tcx> {
1100     pub name: Symbol,
1101
1102     /// Source info of the user variable, including the scope
1103     /// within which the variable is visible (to debuginfo)
1104     /// (see `LocalDecl`'s `source_info` field for more details).
1105     pub source_info: SourceInfo,
1106
1107     /// Where the data for this user variable is to be found.
1108     pub value: VarDebugInfoContents<'tcx>,
1109 }
1110
1111 ///////////////////////////////////////////////////////////////////////////
1112 // BasicBlock
1113
1114 rustc_index::newtype_index! {
1115     /// A node in the MIR [control-flow graph][CFG].
1116     ///
1117     /// There are no branches (e.g., `if`s, function calls, etc.) within a basic block, which makes
1118     /// it easier to do [data-flow analyses] and optimizations. Instead, branches are represented
1119     /// as an edge in a graph between basic blocks.
1120     ///
1121     /// Basic blocks consist of a series of [statements][Statement], ending with a
1122     /// [terminator][Terminator]. Basic blocks can have multiple predecessors and successors,
1123     /// however there is a MIR pass ([`CriticalCallEdges`]) that removes *critical edges*, which
1124     /// are edges that go from a multi-successor node to a multi-predecessor node. This pass is
1125     /// needed because some analyses require that there are no critical edges in the CFG.
1126     ///
1127     /// Note that this type is just an index into [`Body.basic_blocks`](Body::basic_blocks);
1128     /// the actual data that a basic block holds is in [`BasicBlockData`].
1129     ///
1130     /// Read more about basic blocks in the [rustc-dev-guide][guide-mir].
1131     ///
1132     /// [CFG]: https://rustc-dev-guide.rust-lang.org/appendix/background.html#cfg
1133     /// [data-flow analyses]:
1134     ///     https://rustc-dev-guide.rust-lang.org/appendix/background.html#what-is-a-dataflow-analysis
1135     /// [`CriticalCallEdges`]: ../../rustc_mir/transform/add_call_guards/enum.AddCallGuards.html#variant.CriticalCallEdges
1136     /// [guide-mir]: https://rustc-dev-guide.rust-lang.org/mir/
1137     pub struct BasicBlock {
1138         derive [HashStable]
1139         DEBUG_FORMAT = "bb{}",
1140         const START_BLOCK = 0,
1141     }
1142 }
1143
1144 impl BasicBlock {
1145     pub fn start_location(self) -> Location {
1146         Location { block: self, statement_index: 0 }
1147     }
1148 }
1149
1150 ///////////////////////////////////////////////////////////////////////////
1151 // BasicBlockData and Terminator
1152
1153 /// See [`BasicBlock`] for documentation on what basic blocks are at a high level.
1154 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
1155 pub struct BasicBlockData<'tcx> {
1156     /// List of statements in this block.
1157     pub statements: Vec<Statement<'tcx>>,
1158
1159     /// Terminator for this block.
1160     ///
1161     /// N.B., this should generally ONLY be `None` during construction.
1162     /// Therefore, you should generally access it via the
1163     /// `terminator()` or `terminator_mut()` methods. The only
1164     /// exception is that certain passes, such as `simplify_cfg`, swap
1165     /// out the terminator temporarily with `None` while they continue
1166     /// to recurse over the set of basic blocks.
1167     pub terminator: Option<Terminator<'tcx>>,
1168
1169     /// If true, this block lies on an unwind path. This is used
1170     /// during codegen where distinct kinds of basic blocks may be
1171     /// generated (particularly for MSVC cleanup). Unwind blocks must
1172     /// only branch to other unwind blocks.
1173     pub is_cleanup: bool,
1174 }
1175
1176 /// Information about an assertion failure.
1177 #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, PartialOrd)]
1178 pub enum AssertKind<O> {
1179     BoundsCheck { len: O, index: O },
1180     Overflow(BinOp, O, O),
1181     OverflowNeg(O),
1182     DivisionByZero(O),
1183     RemainderByZero(O),
1184     ResumedAfterReturn(GeneratorKind),
1185     ResumedAfterPanic(GeneratorKind),
1186 }
1187
1188 #[derive(
1189     Clone,
1190     Debug,
1191     PartialEq,
1192     PartialOrd,
1193     TyEncodable,
1194     TyDecodable,
1195     Hash,
1196     HashStable,
1197     TypeFoldable
1198 )]
1199 pub enum InlineAsmOperand<'tcx> {
1200     In {
1201         reg: InlineAsmRegOrRegClass,
1202         value: Operand<'tcx>,
1203     },
1204     Out {
1205         reg: InlineAsmRegOrRegClass,
1206         late: bool,
1207         place: Option<Place<'tcx>>,
1208     },
1209     InOut {
1210         reg: InlineAsmRegOrRegClass,
1211         late: bool,
1212         in_value: Operand<'tcx>,
1213         out_place: Option<Place<'tcx>>,
1214     },
1215     Const {
1216         value: Operand<'tcx>,
1217     },
1218     SymFn {
1219         value: Box<Constant<'tcx>>,
1220     },
1221     SymStatic {
1222         def_id: DefId,
1223     },
1224 }
1225
1226 /// Type for MIR `Assert` terminator error messages.
1227 pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
1228
1229 pub type Successors<'a> =
1230     iter::Chain<option::IntoIter<&'a BasicBlock>, slice::Iter<'a, BasicBlock>>;
1231 pub type SuccessorsMut<'a> =
1232     iter::Chain<option::IntoIter<&'a mut BasicBlock>, slice::IterMut<'a, BasicBlock>>;
1233
1234 impl<'tcx> BasicBlockData<'tcx> {
1235     pub fn new(terminator: Option<Terminator<'tcx>>) -> BasicBlockData<'tcx> {
1236         BasicBlockData { statements: vec![], terminator, is_cleanup: false }
1237     }
1238
1239     /// Accessor for terminator.
1240     ///
1241     /// Terminator may not be None after construction of the basic block is complete. This accessor
1242     /// provides a convenience way to reach the terminator.
1243     pub fn terminator(&self) -> &Terminator<'tcx> {
1244         self.terminator.as_ref().expect("invalid terminator state")
1245     }
1246
1247     pub fn terminator_mut(&mut self) -> &mut Terminator<'tcx> {
1248         self.terminator.as_mut().expect("invalid terminator state")
1249     }
1250
1251     pub fn retain_statements<F>(&mut self, mut f: F)
1252     where
1253         F: FnMut(&mut Statement<'_>) -> bool,
1254     {
1255         for s in &mut self.statements {
1256             if !f(s) {
1257                 s.make_nop();
1258             }
1259         }
1260     }
1261
1262     pub fn expand_statements<F, I>(&mut self, mut f: F)
1263     where
1264         F: FnMut(&mut Statement<'tcx>) -> Option<I>,
1265         I: iter::TrustedLen<Item = Statement<'tcx>>,
1266     {
1267         // Gather all the iterators we'll need to splice in, and their positions.
1268         let mut splices: Vec<(usize, I)> = vec![];
1269         let mut extra_stmts = 0;
1270         for (i, s) in self.statements.iter_mut().enumerate() {
1271             if let Some(mut new_stmts) = f(s) {
1272                 if let Some(first) = new_stmts.next() {
1273                     // We can already store the first new statement.
1274                     *s = first;
1275
1276                     // Save the other statements for optimized splicing.
1277                     let remaining = new_stmts.size_hint().0;
1278                     if remaining > 0 {
1279                         splices.push((i + 1 + extra_stmts, new_stmts));
1280                         extra_stmts += remaining;
1281                     }
1282                 } else {
1283                     s.make_nop();
1284                 }
1285             }
1286         }
1287
1288         // Splice in the new statements, from the end of the block.
1289         // FIXME(eddyb) This could be more efficient with a "gap buffer"
1290         // where a range of elements ("gap") is left uninitialized, with
1291         // splicing adding new elements to the end of that gap and moving
1292         // existing elements from before the gap to the end of the gap.
1293         // For now, this is safe code, emulating a gap but initializing it.
1294         let mut gap = self.statements.len()..self.statements.len() + extra_stmts;
1295         self.statements.resize(
1296             gap.end,
1297             Statement { source_info: SourceInfo::outermost(DUMMY_SP), kind: StatementKind::Nop },
1298         );
1299         for (splice_start, new_stmts) in splices.into_iter().rev() {
1300             let splice_end = splice_start + new_stmts.size_hint().0;
1301             while gap.end > splice_end {
1302                 gap.start -= 1;
1303                 gap.end -= 1;
1304                 self.statements.swap(gap.start, gap.end);
1305             }
1306             self.statements.splice(splice_start..splice_end, new_stmts);
1307             gap.end = splice_start;
1308         }
1309     }
1310
1311     pub fn visitable(&self, index: usize) -> &dyn MirVisitable<'tcx> {
1312         if index < self.statements.len() { &self.statements[index] } else { &self.terminator }
1313     }
1314 }
1315
1316 impl<O> AssertKind<O> {
1317     /// Getting a description does not require `O` to be printable, and does not
1318     /// require allocation.
1319     /// The caller is expected to handle `BoundsCheck` separately.
1320     pub fn description(&self) -> &'static str {
1321         use AssertKind::*;
1322         match self {
1323             Overflow(BinOp::Add, _, _) => "attempt to add with overflow",
1324             Overflow(BinOp::Sub, _, _) => "attempt to subtract with overflow",
1325             Overflow(BinOp::Mul, _, _) => "attempt to multiply with overflow",
1326             Overflow(BinOp::Div, _, _) => "attempt to divide with overflow",
1327             Overflow(BinOp::Rem, _, _) => "attempt to calculate the remainder with overflow",
1328             OverflowNeg(_) => "attempt to negate with overflow",
1329             Overflow(BinOp::Shr, _, _) => "attempt to shift right with overflow",
1330             Overflow(BinOp::Shl, _, _) => "attempt to shift left with overflow",
1331             Overflow(op, _, _) => bug!("{:?} cannot overflow", op),
1332             DivisionByZero(_) => "attempt to divide by zero",
1333             RemainderByZero(_) => "attempt to calculate the remainder with a divisor of zero",
1334             ResumedAfterReturn(GeneratorKind::Gen) => "generator resumed after completion",
1335             ResumedAfterReturn(GeneratorKind::Async(_)) => "`async fn` resumed after completion",
1336             ResumedAfterPanic(GeneratorKind::Gen) => "generator resumed after panicking",
1337             ResumedAfterPanic(GeneratorKind::Async(_)) => "`async fn` resumed after panicking",
1338             BoundsCheck { .. } => bug!("Unexpected AssertKind"),
1339         }
1340     }
1341
1342     /// Format the message arguments for the `assert(cond, msg..)` terminator in MIR printing.
1343     fn fmt_assert_args<W: Write>(&self, f: &mut W) -> fmt::Result
1344     where
1345         O: Debug,
1346     {
1347         use AssertKind::*;
1348         match self {
1349             BoundsCheck { ref len, ref index } => write!(
1350                 f,
1351                 "\"index out of bounds: the length is {{}} but the index is {{}}\", {:?}, {:?}",
1352                 len, index
1353             ),
1354
1355             OverflowNeg(op) => {
1356                 write!(f, "\"attempt to negate `{{}}`, which would overflow\", {:?}", op)
1357             }
1358             DivisionByZero(op) => write!(f, "\"attempt to divide `{{}}` by zero\", {:?}", op),
1359             RemainderByZero(op) => write!(
1360                 f,
1361                 "\"attempt to calculate the remainder of `{{}}` with a divisor of zero\", {:?}",
1362                 op
1363             ),
1364             Overflow(BinOp::Add, l, r) => write!(
1365                 f,
1366                 "\"attempt to compute `{{}} + {{}}`, which would overflow\", {:?}, {:?}",
1367                 l, r
1368             ),
1369             Overflow(BinOp::Sub, l, r) => write!(
1370                 f,
1371                 "\"attempt to compute `{{}} - {{}}`, which would overflow\", {:?}, {:?}",
1372                 l, r
1373             ),
1374             Overflow(BinOp::Mul, l, r) => write!(
1375                 f,
1376                 "\"attempt to compute `{{}} * {{}}`, which would overflow\", {:?}, {:?}",
1377                 l, r
1378             ),
1379             Overflow(BinOp::Div, l, r) => write!(
1380                 f,
1381                 "\"attempt to compute `{{}} / {{}}`, which would overflow\", {:?}, {:?}",
1382                 l, r
1383             ),
1384             Overflow(BinOp::Rem, l, r) => write!(
1385                 f,
1386                 "\"attempt to compute the remainder of `{{}} % {{}}`, which would overflow\", {:?}, {:?}",
1387                 l, r
1388             ),
1389             Overflow(BinOp::Shr, _, r) => {
1390                 write!(f, "\"attempt to shift right by `{{}}`, which would overflow\", {:?}", r)
1391             }
1392             Overflow(BinOp::Shl, _, r) => {
1393                 write!(f, "\"attempt to shift left by `{{}}`, which would overflow\", {:?}", r)
1394             }
1395             _ => write!(f, "\"{}\"", self.description()),
1396         }
1397     }
1398 }
1399
1400 impl<O: fmt::Debug> fmt::Debug for AssertKind<O> {
1401     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1402         use AssertKind::*;
1403         match self {
1404             BoundsCheck { ref len, ref index } => write!(
1405                 f,
1406                 "index out of bounds: the length is {:?} but the index is {:?}",
1407                 len, index
1408             ),
1409             OverflowNeg(op) => write!(f, "attempt to negate `{:#?}`, which would overflow", op),
1410             DivisionByZero(op) => write!(f, "attempt to divide `{:#?}` by zero", op),
1411             RemainderByZero(op) => write!(
1412                 f,
1413                 "attempt to calculate the remainder of `{:#?}` with a divisor of zero",
1414                 op
1415             ),
1416             Overflow(BinOp::Add, l, r) => {
1417                 write!(f, "attempt to compute `{:#?} + {:#?}`, which would overflow", l, r)
1418             }
1419             Overflow(BinOp::Sub, l, r) => {
1420                 write!(f, "attempt to compute `{:#?} - {:#?}`, which would overflow", l, r)
1421             }
1422             Overflow(BinOp::Mul, l, r) => {
1423                 write!(f, "attempt to compute `{:#?} * {:#?}`, which would overflow", l, r)
1424             }
1425             Overflow(BinOp::Div, l, r) => {
1426                 write!(f, "attempt to compute `{:#?} / {:#?}`, which would overflow", l, r)
1427             }
1428             Overflow(BinOp::Rem, l, r) => write!(
1429                 f,
1430                 "attempt to compute the remainder of `{:#?} % {:#?}`, which would overflow",
1431                 l, r
1432             ),
1433             Overflow(BinOp::Shr, _, r) => {
1434                 write!(f, "attempt to shift right by `{:#?}`, which would overflow", r)
1435             }
1436             Overflow(BinOp::Shl, _, r) => {
1437                 write!(f, "attempt to shift left by `{:#?}`, which would overflow", r)
1438             }
1439             _ => write!(f, "{}", self.description()),
1440         }
1441     }
1442 }
1443
1444 ///////////////////////////////////////////////////////////////////////////
1445 // Statements
1446
1447 #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
1448 pub struct Statement<'tcx> {
1449     pub source_info: SourceInfo,
1450     pub kind: StatementKind<'tcx>,
1451 }
1452
1453 // `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
1454 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
1455 static_assert_size!(Statement<'_>, 32);
1456
1457 impl Statement<'_> {
1458     /// Changes a statement to a nop. This is both faster than deleting instructions and avoids
1459     /// invalidating statement indices in `Location`s.
1460     pub fn make_nop(&mut self) {
1461         self.kind = StatementKind::Nop
1462     }
1463
1464     /// Changes a statement to a nop and returns the original statement.
1465     pub fn replace_nop(&mut self) -> Self {
1466         Statement {
1467             source_info: self.source_info,
1468             kind: mem::replace(&mut self.kind, StatementKind::Nop),
1469         }
1470     }
1471 }
1472
1473 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
1474 pub enum StatementKind<'tcx> {
1475     /// Write the RHS Rvalue to the LHS Place.
1476     Assign(Box<(Place<'tcx>, Rvalue<'tcx>)>),
1477
1478     /// This represents all the reading that a pattern match may do
1479     /// (e.g., inspecting constants and discriminant values), and the
1480     /// kind of pattern it comes from. This is in order to adapt potential
1481     /// error messages to these specific patterns.
1482     ///
1483     /// Note that this also is emitted for regular `let` bindings to ensure that locals that are
1484     /// never accessed still get some sanity checks for, e.g., `let x: ! = ..;`
1485     FakeRead(FakeReadCause, Box<Place<'tcx>>),
1486
1487     /// Write the discriminant for a variant to the enum Place.
1488     SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
1489
1490     /// Start a live range for the storage of the local.
1491     StorageLive(Local),
1492
1493     /// End the current live range for the storage of the local.
1494     StorageDead(Local),
1495
1496     /// Executes a piece of inline Assembly. Stored in a Box to keep the size
1497     /// of `StatementKind` low.
1498     LlvmInlineAsm(Box<LlvmInlineAsm<'tcx>>),
1499
1500     /// Retag references in the given place, ensuring they got fresh tags. This is
1501     /// part of the Stacked Borrows model. These statements are currently only interpreted
1502     /// by miri and only generated when "-Z mir-emit-retag" is passed.
1503     /// See <https://internals.rust-lang.org/t/stacked-borrows-an-aliasing-model-for-rust/8153/>
1504     /// for more details.
1505     Retag(RetagKind, Box<Place<'tcx>>),
1506
1507     /// Encodes a user's type ascription. These need to be preserved
1508     /// intact so that NLL can respect them. For example:
1509     ///
1510     ///     let a: T = y;
1511     ///
1512     /// The effect of this annotation is to relate the type `T_y` of the place `y`
1513     /// to the user-given type `T`. The effect depends on the specified variance:
1514     ///
1515     /// - `Covariant` -- requires that `T_y <: T`
1516     /// - `Contravariant` -- requires that `T_y :> T`
1517     /// - `Invariant` -- requires that `T_y == T`
1518     /// - `Bivariant` -- no effect
1519     AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>, ty::Variance),
1520
1521     /// Marks the start of a "coverage region", injected with '-Zinstrument-coverage'. A
1522     /// `Coverage` statement carries metadata about the coverage region, used to inject a coverage
1523     /// map into the binary. If `Coverage::kind` is a `Counter`, the statement also generates
1524     /// executable code, to increment a counter varible at runtime, each time the code region is
1525     /// executed.
1526     Coverage(Box<Coverage>),
1527
1528     /// Denotes a call to the intrinsic function copy_overlapping, where `src_dst` denotes the
1529     /// memory being read from and written to(one field to save memory), and size
1530     /// indicates how many bytes are being copied over.
1531     CopyNonOverlapping(Box<CopyNonOverlapping<'tcx>>),
1532
1533     /// No-op. Useful for deleting instructions without affecting statement indices.
1534     Nop,
1535 }
1536
1537 impl<'tcx> StatementKind<'tcx> {
1538     pub fn as_assign_mut(&mut self) -> Option<&mut (Place<'tcx>, Rvalue<'tcx>)> {
1539         match self {
1540             StatementKind::Assign(x) => Some(x),
1541             _ => None,
1542         }
1543     }
1544
1545     pub fn as_assign(&self) -> Option<&(Place<'tcx>, Rvalue<'tcx>)> {
1546         match self {
1547             StatementKind::Assign(x) => Some(x),
1548             _ => None,
1549         }
1550     }
1551 }
1552
1553 /// Describes what kind of retag is to be performed.
1554 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, Hash, HashStable)]
1555 pub enum RetagKind {
1556     /// The initial retag when entering a function.
1557     FnEntry,
1558     /// Retag preparing for a two-phase borrow.
1559     TwoPhase,
1560     /// Retagging raw pointers.
1561     Raw,
1562     /// A "normal" retag.
1563     Default,
1564 }
1565
1566 /// The `FakeReadCause` describes the type of pattern why a FakeRead statement exists.
1567 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, Hash, HashStable, PartialEq)]
1568 pub enum FakeReadCause {
1569     /// Inject a fake read of the borrowed input at the end of each guards
1570     /// code.
1571     ///
1572     /// This should ensure that you cannot change the variant for an enum while
1573     /// you are in the midst of matching on it.
1574     ForMatchGuard,
1575
1576     /// `let x: !; match x {}` doesn't generate any read of x so we need to
1577     /// generate a read of x to check that it is initialized and safe.
1578     ForMatchedPlace,
1579
1580     /// A fake read of the RefWithinGuard version of a bind-by-value variable
1581     /// in a match guard to ensure that it's value hasn't change by the time
1582     /// we create the OutsideGuard version.
1583     ForGuardBinding,
1584
1585     /// Officially, the semantics of
1586     ///
1587     /// `let pattern = <expr>;`
1588     ///
1589     /// is that `<expr>` is evaluated into a temporary and then this temporary is
1590     /// into the pattern.
1591     ///
1592     /// However, if we see the simple pattern `let var = <expr>`, we optimize this to
1593     /// evaluate `<expr>` directly into the variable `var`. This is mostly unobservable,
1594     /// but in some cases it can affect the borrow checker, as in #53695.
1595     /// Therefore, we insert a "fake read" here to ensure that we get
1596     /// appropriate errors.
1597     ForLet,
1598
1599     /// If we have an index expression like
1600     ///
1601     /// (*x)[1][{ x = y; 4}]
1602     ///
1603     /// then the first bounds check is invalidated when we evaluate the second
1604     /// index expression. Thus we create a fake borrow of `x` across the second
1605     /// indexer, which will cause a borrow check error.
1606     ForIndex,
1607 }
1608
1609 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
1610 pub struct LlvmInlineAsm<'tcx> {
1611     pub asm: hir::LlvmInlineAsmInner,
1612     pub outputs: Box<[Place<'tcx>]>,
1613     pub inputs: Box<[(Span, Operand<'tcx>)]>,
1614 }
1615
1616 impl Debug for Statement<'_> {
1617     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
1618         use self::StatementKind::*;
1619         match self.kind {
1620             Assign(box (ref place, ref rv)) => write!(fmt, "{:?} = {:?}", place, rv),
1621             FakeRead(ref cause, ref place) => write!(fmt, "FakeRead({:?}, {:?})", cause, place),
1622             Retag(ref kind, ref place) => write!(
1623                 fmt,
1624                 "Retag({}{:?})",
1625                 match kind {
1626                     RetagKind::FnEntry => "[fn entry] ",
1627                     RetagKind::TwoPhase => "[2phase] ",
1628                     RetagKind::Raw => "[raw] ",
1629                     RetagKind::Default => "",
1630                 },
1631                 place,
1632             ),
1633             StorageLive(ref place) => write!(fmt, "StorageLive({:?})", place),
1634             StorageDead(ref place) => write!(fmt, "StorageDead({:?})", place),
1635             SetDiscriminant { ref place, variant_index } => {
1636                 write!(fmt, "discriminant({:?}) = {:?}", place, variant_index)
1637             }
1638             LlvmInlineAsm(ref asm) => {
1639                 write!(fmt, "llvm_asm!({:?} : {:?} : {:?})", asm.asm, asm.outputs, asm.inputs)
1640             }
1641             AscribeUserType(box (ref place, ref c_ty), ref variance) => {
1642                 write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
1643             }
1644             Coverage(box ref coverage) => {
1645                 if let Some(rgn) = &coverage.code_region {
1646                     write!(fmt, "Coverage::{:?} for {:?}", coverage.kind, rgn)
1647                 } else {
1648                     write!(fmt, "Coverage::{:?}", coverage.kind)
1649                 }
1650             }
1651             CopyNonOverlapping(box crate::mir::CopyNonOverlapping {
1652                 ref src,
1653                 ref dst,
1654                 ref count,
1655             }) => {
1656                 write!(fmt, "copy_nonoverlapping(src={:?}, dst={:?}, count={:?})", src, dst, count)
1657             }
1658             Nop => write!(fmt, "nop"),
1659         }
1660     }
1661 }
1662
1663 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
1664 pub struct Coverage {
1665     pub kind: CoverageKind,
1666     pub code_region: Option<CodeRegion>,
1667 }
1668
1669 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
1670 pub struct CopyNonOverlapping<'tcx> {
1671     pub src: Operand<'tcx>,
1672     pub dst: Operand<'tcx>,
1673     /// Number of elements to copy from src to dest, not bytes.
1674     pub count: Operand<'tcx>,
1675 }
1676
1677 ///////////////////////////////////////////////////////////////////////////
1678 // Places
1679
1680 /// A path to a value; something that can be evaluated without
1681 /// changing or disturbing program state.
1682 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, HashStable)]
1683 pub struct Place<'tcx> {
1684     pub local: Local,
1685
1686     /// projection out of a place (access a field, deref a pointer, etc)
1687     pub projection: &'tcx List<PlaceElem<'tcx>>,
1688 }
1689
1690 #[cfg(target_arch = "x86_64")]
1691 static_assert_size!(Place<'_>, 16);
1692
1693 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1694 #[derive(TyEncodable, TyDecodable, HashStable)]
1695 pub enum ProjectionElem<V, T> {
1696     Deref,
1697     Field(Field, T),
1698     Index(V),
1699
1700     /// These indices are generated by slice patterns. Easiest to explain
1701     /// by example:
1702     ///
1703     /// ```
1704     /// [X, _, .._, _, _] => { offset: 0, min_length: 4, from_end: false },
1705     /// [_, X, .._, _, _] => { offset: 1, min_length: 4, from_end: false },
1706     /// [_, _, .._, X, _] => { offset: 2, min_length: 4, from_end: true },
1707     /// [_, _, .._, _, X] => { offset: 1, min_length: 4, from_end: true },
1708     /// ```
1709     ConstantIndex {
1710         /// index or -index (in Python terms), depending on from_end
1711         offset: u64,
1712         /// The thing being indexed must be at least this long. For arrays this
1713         /// is always the exact length.
1714         min_length: u64,
1715         /// Counting backwards from end? This is always false when indexing an
1716         /// array.
1717         from_end: bool,
1718     },
1719
1720     /// These indices are generated by slice patterns.
1721     ///
1722     /// If `from_end` is true `slice[from..slice.len() - to]`.
1723     /// Otherwise `array[from..to]`.
1724     Subslice {
1725         from: u64,
1726         to: u64,
1727         /// Whether `to` counts from the start or end of the array/slice.
1728         /// For `PlaceElem`s this is `true` if and only if the base is a slice.
1729         /// For `ProjectionKind`, this can also be `true` for arrays.
1730         from_end: bool,
1731     },
1732
1733     /// "Downcast" to a variant of an ADT. Currently, we only introduce
1734     /// this for ADTs with more than one variant. It may be better to
1735     /// just introduce it always, or always for enums.
1736     ///
1737     /// The included Symbol is the name of the variant, used for printing MIR.
1738     Downcast(Option<Symbol>, VariantIdx),
1739 }
1740
1741 impl<V, T> ProjectionElem<V, T> {
1742     /// Returns `true` if the target of this projection may refer to a different region of memory
1743     /// than the base.
1744     fn is_indirect(&self) -> bool {
1745         match self {
1746             Self::Deref => true,
1747
1748             Self::Field(_, _)
1749             | Self::Index(_)
1750             | Self::ConstantIndex { .. }
1751             | Self::Subslice { .. }
1752             | Self::Downcast(_, _) => false,
1753         }
1754     }
1755 }
1756
1757 /// Alias for projections as they appear in places, where the base is a place
1758 /// and the index is a local.
1759 pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
1760
1761 // At least on 64 bit systems, `PlaceElem` should not be larger than two pointers.
1762 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
1763 static_assert_size!(PlaceElem<'_>, 24);
1764
1765 /// Alias for projections as they appear in `UserTypeProjection`, where we
1766 /// need neither the `V` parameter for `Index` nor the `T` for `Field`.
1767 pub type ProjectionKind = ProjectionElem<(), ()>;
1768
1769 rustc_index::newtype_index! {
1770     pub struct Field {
1771         derive [HashStable]
1772         DEBUG_FORMAT = "field[{}]"
1773     }
1774 }
1775
1776 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1777 pub struct PlaceRef<'tcx> {
1778     pub local: Local,
1779     pub projection: &'tcx [PlaceElem<'tcx>],
1780 }
1781
1782 impl<'tcx> Place<'tcx> {
1783     // FIXME change this to a const fn by also making List::empty a const fn.
1784     pub fn return_place() -> Place<'tcx> {
1785         Place { local: RETURN_PLACE, projection: List::empty() }
1786     }
1787
1788     /// Returns `true` if this `Place` contains a `Deref` projection.
1789     ///
1790     /// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
1791     /// same region of memory as its base.
1792     pub fn is_indirect(&self) -> bool {
1793         self.projection.iter().any(|elem| elem.is_indirect())
1794     }
1795
1796     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
1797     /// a single deref of a local.
1798     #[inline(always)]
1799     pub fn local_or_deref_local(&self) -> Option<Local> {
1800         self.as_ref().local_or_deref_local()
1801     }
1802
1803     /// If this place represents a local variable like `_X` with no
1804     /// projections, return `Some(_X)`.
1805     #[inline(always)]
1806     pub fn as_local(&self) -> Option<Local> {
1807         self.as_ref().as_local()
1808     }
1809
1810     #[inline]
1811     pub fn as_ref(&self) -> PlaceRef<'tcx> {
1812         PlaceRef { local: self.local, projection: &self.projection }
1813     }
1814
1815     /// Iterate over the projections in evaluation order, i.e., the first element is the base with
1816     /// its projection and then subsequently more projections are added.
1817     /// As a concrete example, given the place a.b.c, this would yield:
1818     /// - (a, .b)
1819     /// - (a.b, .c)
1820     ///
1821     /// Given a place without projections, the iterator is empty.
1822     #[inline]
1823     pub fn iter_projections(
1824         self,
1825     ) -> impl Iterator<Item = (PlaceRef<'tcx>, PlaceElem<'tcx>)> + DoubleEndedIterator {
1826         self.projection.iter().enumerate().map(move |(i, proj)| {
1827             let base = PlaceRef { local: self.local, projection: &self.projection[..i] };
1828             (base, proj)
1829         })
1830     }
1831 }
1832
1833 impl From<Local> for Place<'_> {
1834     fn from(local: Local) -> Self {
1835         Place { local, projection: List::empty() }
1836     }
1837 }
1838
1839 impl<'tcx> PlaceRef<'tcx> {
1840     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
1841     /// a single deref of a local.
1842     pub fn local_or_deref_local(&self) -> Option<Local> {
1843         match *self {
1844             PlaceRef { local, projection: [] }
1845             | PlaceRef { local, projection: [ProjectionElem::Deref] } => Some(local),
1846             _ => None,
1847         }
1848     }
1849
1850     /// If this place represents a local variable like `_X` with no
1851     /// projections, return `Some(_X)`.
1852     pub fn as_local(&self) -> Option<Local> {
1853         match *self {
1854             PlaceRef { local, projection: [] } => Some(local),
1855             _ => None,
1856         }
1857     }
1858
1859     pub fn last_projection(&self) -> Option<(PlaceRef<'tcx>, PlaceElem<'tcx>)> {
1860         if let &[ref proj_base @ .., elem] = self.projection {
1861             Some((PlaceRef { local: self.local, projection: proj_base }, elem))
1862         } else {
1863             None
1864         }
1865     }
1866 }
1867
1868 impl Debug for Place<'_> {
1869     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
1870         for elem in self.projection.iter().rev() {
1871             match elem {
1872                 ProjectionElem::Downcast(_, _) | ProjectionElem::Field(_, _) => {
1873                     write!(fmt, "(").unwrap();
1874                 }
1875                 ProjectionElem::Deref => {
1876                     write!(fmt, "(*").unwrap();
1877                 }
1878                 ProjectionElem::Index(_)
1879                 | ProjectionElem::ConstantIndex { .. }
1880                 | ProjectionElem::Subslice { .. } => {}
1881             }
1882         }
1883
1884         write!(fmt, "{:?}", self.local)?;
1885
1886         for elem in self.projection.iter() {
1887             match elem {
1888                 ProjectionElem::Downcast(Some(name), _index) => {
1889                     write!(fmt, " as {})", name)?;
1890                 }
1891                 ProjectionElem::Downcast(None, index) => {
1892                     write!(fmt, " as variant#{:?})", index)?;
1893                 }
1894                 ProjectionElem::Deref => {
1895                     write!(fmt, ")")?;
1896                 }
1897                 ProjectionElem::Field(field, ty) => {
1898                     write!(fmt, ".{:?}: {:?})", field.index(), ty)?;
1899                 }
1900                 ProjectionElem::Index(ref index) => {
1901                     write!(fmt, "[{:?}]", index)?;
1902                 }
1903                 ProjectionElem::ConstantIndex { offset, min_length, from_end: false } => {
1904                     write!(fmt, "[{:?} of {:?}]", offset, min_length)?;
1905                 }
1906                 ProjectionElem::ConstantIndex { offset, min_length, from_end: true } => {
1907                     write!(fmt, "[-{:?} of {:?}]", offset, min_length)?;
1908                 }
1909                 ProjectionElem::Subslice { from, to, from_end: true } if to == 0 => {
1910                     write!(fmt, "[{:?}:]", from)?;
1911                 }
1912                 ProjectionElem::Subslice { from, to, from_end: true } if from == 0 => {
1913                     write!(fmt, "[:-{:?}]", to)?;
1914                 }
1915                 ProjectionElem::Subslice { from, to, from_end: true } => {
1916                     write!(fmt, "[{:?}:-{:?}]", from, to)?;
1917                 }
1918                 ProjectionElem::Subslice { from, to, from_end: false } => {
1919                     write!(fmt, "[{:?}..{:?}]", from, to)?;
1920                 }
1921             }
1922         }
1923
1924         Ok(())
1925     }
1926 }
1927
1928 ///////////////////////////////////////////////////////////////////////////
1929 // Scopes
1930
1931 rustc_index::newtype_index! {
1932     pub struct SourceScope {
1933         derive [HashStable]
1934         DEBUG_FORMAT = "scope[{}]",
1935         const OUTERMOST_SOURCE_SCOPE = 0,
1936     }
1937 }
1938
1939 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
1940 pub struct SourceScopeData<'tcx> {
1941     pub span: Span,
1942     pub parent_scope: Option<SourceScope>,
1943
1944     /// Whether this scope is the root of a scope tree of another body,
1945     /// inlined into this body by the MIR inliner.
1946     /// `ty::Instance` is the callee, and the `Span` is the call site.
1947     pub inlined: Option<(ty::Instance<'tcx>, Span)>,
1948
1949     /// Nearest (transitive) parent scope (if any) which is inlined.
1950     /// This is an optimization over walking up `parent_scope`
1951     /// until a scope with `inlined: Some(...)` is found.
1952     pub inlined_parent_scope: Option<SourceScope>,
1953
1954     /// Crate-local information for this source scope, that can't (and
1955     /// needn't) be tracked across crates.
1956     pub local_data: ClearCrossCrate<SourceScopeLocalData>,
1957 }
1958
1959 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
1960 pub struct SourceScopeLocalData {
1961     /// An `HirId` with lint levels equivalent to this scope's lint levels.
1962     pub lint_root: hir::HirId,
1963     /// The unsafe block that contains this node.
1964     pub safety: Safety,
1965 }
1966
1967 ///////////////////////////////////////////////////////////////////////////
1968 // Operands
1969
1970 /// These are values that can appear inside an rvalue. They are intentionally
1971 /// limited to prevent rvalues from being nested in one another.
1972 #[derive(Clone, PartialEq, PartialOrd, TyEncodable, TyDecodable, Hash, HashStable)]
1973 pub enum Operand<'tcx> {
1974     /// Copy: The value must be available for use afterwards.
1975     ///
1976     /// This implies that the type of the place must be `Copy`; this is true
1977     /// by construction during build, but also checked by the MIR type checker.
1978     Copy(Place<'tcx>),
1979
1980     /// Move: The value (including old borrows of it) will not be used again.
1981     ///
1982     /// Safe for values of all types (modulo future developments towards `?Move`).
1983     /// Correct usage patterns are enforced by the borrow checker for safe code.
1984     /// `Copy` may be converted to `Move` to enable "last-use" optimizations.
1985     Move(Place<'tcx>),
1986
1987     /// Synthesizes a constant value.
1988     Constant(Box<Constant<'tcx>>),
1989 }
1990
1991 #[cfg(target_arch = "x86_64")]
1992 static_assert_size!(Operand<'_>, 24);
1993
1994 impl<'tcx> Debug for Operand<'tcx> {
1995     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
1996         use self::Operand::*;
1997         match *self {
1998             Constant(ref a) => write!(fmt, "{:?}", a),
1999             Copy(ref place) => write!(fmt, "{:?}", place),
2000             Move(ref place) => write!(fmt, "move {:?}", place),
2001         }
2002     }
2003 }
2004
2005 impl<'tcx> Operand<'tcx> {
2006     /// Convenience helper to make a constant that refers to the fn
2007     /// with given `DefId` and substs. Since this is used to synthesize
2008     /// MIR, assumes `user_ty` is None.
2009     pub fn function_handle(
2010         tcx: TyCtxt<'tcx>,
2011         def_id: DefId,
2012         substs: SubstsRef<'tcx>,
2013         span: Span,
2014     ) -> Self {
2015         let ty = tcx.type_of(def_id).subst(tcx, substs);
2016         Operand::Constant(box Constant {
2017             span,
2018             user_ty: None,
2019             literal: ConstantKind::Ty(ty::Const::zero_sized(tcx, ty)),
2020         })
2021     }
2022
2023     pub fn is_move(&self) -> bool {
2024         matches!(self, Operand::Move(..))
2025     }
2026
2027     /// Convenience helper to make a literal-like constant from a given scalar value.
2028     /// Since this is used to synthesize MIR, assumes `user_ty` is None.
2029     pub fn const_from_scalar(
2030         tcx: TyCtxt<'tcx>,
2031         ty: Ty<'tcx>,
2032         val: Scalar,
2033         span: Span,
2034     ) -> Operand<'tcx> {
2035         debug_assert!({
2036             let param_env_and_ty = ty::ParamEnv::empty().and(ty);
2037             let type_size = tcx
2038                 .layout_of(param_env_and_ty)
2039                 .unwrap_or_else(|e| panic!("could not compute layout for {:?}: {:?}", ty, e))
2040                 .size;
2041             let scalar_size = match val {
2042                 Scalar::Int(int) => int.size(),
2043                 _ => panic!("Invalid scalar type {:?}", val),
2044             };
2045             scalar_size == type_size
2046         });
2047         Operand::Constant(box Constant {
2048             span,
2049             user_ty: None,
2050             literal: ConstantKind::Val(val.into(), ty),
2051         })
2052     }
2053
2054     pub fn to_copy(&self) -> Self {
2055         match *self {
2056             Operand::Copy(_) | Operand::Constant(_) => self.clone(),
2057             Operand::Move(place) => Operand::Copy(place),
2058         }
2059     }
2060
2061     /// Returns the `Place` that is the target of this `Operand`, or `None` if this `Operand` is a
2062     /// constant.
2063     pub fn place(&self) -> Option<Place<'tcx>> {
2064         match self {
2065             Operand::Copy(place) | Operand::Move(place) => Some(*place),
2066             Operand::Constant(_) => None,
2067         }
2068     }
2069
2070     /// Returns the `Constant` that is the target of this `Operand`, or `None` if this `Operand` is a
2071     /// place.
2072     pub fn constant(&self) -> Option<&Constant<'tcx>> {
2073         match self {
2074             Operand::Constant(x) => Some(&**x),
2075             Operand::Copy(_) | Operand::Move(_) => None,
2076         }
2077     }
2078 }
2079
2080 ///////////////////////////////////////////////////////////////////////////
2081 /// Rvalues
2082
2083 #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
2084 pub enum Rvalue<'tcx> {
2085     /// x (either a move or copy, depending on type of x)
2086     Use(Operand<'tcx>),
2087
2088     /// [x; 32]
2089     Repeat(Operand<'tcx>, &'tcx ty::Const<'tcx>),
2090
2091     /// &x or &mut x
2092     Ref(Region<'tcx>, BorrowKind, Place<'tcx>),
2093
2094     /// Accessing a thread local static. This is inherently a runtime operation, even if llvm
2095     /// treats it as an access to a static. This `Rvalue` yields a reference to the thread local
2096     /// static.
2097     ThreadLocalRef(DefId),
2098
2099     /// Create a raw pointer to the given place
2100     /// Can be generated by raw address of expressions (`&raw const x`),
2101     /// or when casting a reference to a raw pointer.
2102     AddressOf(Mutability, Place<'tcx>),
2103
2104     /// length of a `[X]` or `[X;n]` value
2105     Len(Place<'tcx>),
2106
2107     Cast(CastKind, Operand<'tcx>, Ty<'tcx>),
2108
2109     BinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
2110     CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
2111
2112     NullaryOp(NullOp, Ty<'tcx>),
2113     UnaryOp(UnOp, Operand<'tcx>),
2114
2115     /// Read the discriminant of an ADT.
2116     ///
2117     /// Undefined (i.e., no effort is made to make it defined, but there’s no reason why it cannot
2118     /// be defined to return, say, a 0) if ADT is not an enum.
2119     Discriminant(Place<'tcx>),
2120
2121     /// Creates an aggregate value, like a tuple or struct. This is
2122     /// only needed because we want to distinguish `dest = Foo { x:
2123     /// ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case
2124     /// that `Foo` has a destructor. These rvalues can be optimized
2125     /// away after type-checking and before lowering.
2126     Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
2127 }
2128
2129 #[cfg(target_arch = "x86_64")]
2130 static_assert_size!(Rvalue<'_>, 40);
2131
2132 #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
2133 pub enum CastKind {
2134     Misc,
2135     Pointer(PointerCast),
2136 }
2137
2138 #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
2139 pub enum AggregateKind<'tcx> {
2140     /// The type is of the element
2141     Array(Ty<'tcx>),
2142     Tuple,
2143
2144     /// The second field is the variant index. It's equal to 0 for struct
2145     /// and union expressions. The fourth field is
2146     /// active field number and is present only for union expressions
2147     /// -- e.g., for a union expression `SomeUnion { c: .. }`, the
2148     /// active field index would identity the field `c`
2149     Adt(&'tcx AdtDef, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<usize>),
2150
2151     Closure(DefId, SubstsRef<'tcx>),
2152     Generator(DefId, SubstsRef<'tcx>, hir::Movability),
2153 }
2154
2155 #[cfg(target_arch = "x86_64")]
2156 static_assert_size!(AggregateKind<'_>, 48);
2157
2158 #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
2159 pub enum BinOp {
2160     /// The `+` operator (addition)
2161     Add,
2162     /// The `-` operator (subtraction)
2163     Sub,
2164     /// The `*` operator (multiplication)
2165     Mul,
2166     /// The `/` operator (division)
2167     Div,
2168     /// The `%` operator (modulus)
2169     Rem,
2170     /// The `^` operator (bitwise xor)
2171     BitXor,
2172     /// The `&` operator (bitwise and)
2173     BitAnd,
2174     /// The `|` operator (bitwise or)
2175     BitOr,
2176     /// The `<<` operator (shift left)
2177     Shl,
2178     /// The `>>` operator (shift right)
2179     Shr,
2180     /// The `==` operator (equality)
2181     Eq,
2182     /// The `<` operator (less than)
2183     Lt,
2184     /// The `<=` operator (less than or equal to)
2185     Le,
2186     /// The `!=` operator (not equal to)
2187     Ne,
2188     /// The `>=` operator (greater than or equal to)
2189     Ge,
2190     /// The `>` operator (greater than)
2191     Gt,
2192     /// The `ptr.offset` operator
2193     Offset,
2194 }
2195
2196 impl BinOp {
2197     pub fn is_checkable(self) -> bool {
2198         use self::BinOp::*;
2199         matches!(self, Add | Sub | Mul | Shl | Shr)
2200     }
2201 }
2202
2203 #[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
2204 pub enum NullOp {
2205     /// Returns the size of a value of that type
2206     SizeOf,
2207     /// Creates a new uninitialized box for a value of that type
2208     Box,
2209 }
2210
2211 #[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
2212 pub enum UnOp {
2213     /// The `!` operator for logical inversion
2214     Not,
2215     /// The `-` operator for negation
2216     Neg,
2217 }
2218
2219 impl<'tcx> Debug for Rvalue<'tcx> {
2220     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
2221         use self::Rvalue::*;
2222
2223         match *self {
2224             Use(ref place) => write!(fmt, "{:?}", place),
2225             Repeat(ref a, ref b) => {
2226                 write!(fmt, "[{:?}; ", a)?;
2227                 pretty_print_const(b, fmt, false)?;
2228                 write!(fmt, "]")
2229             }
2230             Len(ref a) => write!(fmt, "Len({:?})", a),
2231             Cast(ref kind, ref place, ref ty) => {
2232                 write!(fmt, "{:?} as {:?} ({:?})", place, ty, kind)
2233             }
2234             BinaryOp(ref op, box (ref a, ref b)) => write!(fmt, "{:?}({:?}, {:?})", op, a, b),
2235             CheckedBinaryOp(ref op, box (ref a, ref b)) => {
2236                 write!(fmt, "Checked{:?}({:?}, {:?})", op, a, b)
2237             }
2238             UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
2239             Discriminant(ref place) => write!(fmt, "discriminant({:?})", place),
2240             NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t),
2241             ThreadLocalRef(did) => ty::tls::with(|tcx| {
2242                 let muta = tcx.static_mutability(did).unwrap().prefix_str();
2243                 write!(fmt, "&/*tls*/ {}{}", muta, tcx.def_path_str(did))
2244             }),
2245             Ref(region, borrow_kind, ref place) => {
2246                 let kind_str = match borrow_kind {
2247                     BorrowKind::Shared => "",
2248                     BorrowKind::Shallow => "shallow ",
2249                     BorrowKind::Mut { .. } | BorrowKind::Unique => "mut ",
2250                 };
2251
2252                 // When printing regions, add trailing space if necessary.
2253                 let print_region = ty::tls::with(|tcx| {
2254                     tcx.sess.verbose() || tcx.sess.opts.debugging_opts.identify_regions
2255                 });
2256                 let region = if print_region {
2257                     let mut region = region.to_string();
2258                     if !region.is_empty() {
2259                         region.push(' ');
2260                     }
2261                     region
2262                 } else {
2263                     // Do not even print 'static
2264                     String::new()
2265                 };
2266                 write!(fmt, "&{}{}{:?}", region, kind_str, place)
2267             }
2268
2269             AddressOf(mutability, ref place) => {
2270                 let kind_str = match mutability {
2271                     Mutability::Mut => "mut",
2272                     Mutability::Not => "const",
2273                 };
2274
2275                 write!(fmt, "&raw {} {:?}", kind_str, place)
2276             }
2277
2278             Aggregate(ref kind, ref places) => {
2279                 let fmt_tuple = |fmt: &mut Formatter<'_>, name: &str| {
2280                     let mut tuple_fmt = fmt.debug_tuple(name);
2281                     for place in places {
2282                         tuple_fmt.field(place);
2283                     }
2284                     tuple_fmt.finish()
2285                 };
2286
2287                 match **kind {
2288                     AggregateKind::Array(_) => write!(fmt, "{:?}", places),
2289
2290                     AggregateKind::Tuple => {
2291                         if places.is_empty() {
2292                             write!(fmt, "()")
2293                         } else {
2294                             fmt_tuple(fmt, "")
2295                         }
2296                     }
2297
2298                     AggregateKind::Adt(adt_def, variant, substs, _user_ty, _) => {
2299                         let variant_def = &adt_def.variants[variant];
2300
2301                         let name = ty::tls::with(|tcx| {
2302                             let mut name = String::new();
2303                             let substs = tcx.lift(substs).expect("could not lift for printing");
2304                             FmtPrinter::new(tcx, &mut name, Namespace::ValueNS)
2305                                 .print_def_path(variant_def.def_id, substs)?;
2306                             Ok(name)
2307                         })?;
2308
2309                         match variant_def.ctor_kind {
2310                             CtorKind::Const => fmt.write_str(&name),
2311                             CtorKind::Fn => fmt_tuple(fmt, &name),
2312                             CtorKind::Fictive => {
2313                                 let mut struct_fmt = fmt.debug_struct(&name);
2314                                 for (field, place) in iter::zip(&variant_def.fields, places) {
2315                                     struct_fmt.field(&field.ident.as_str(), place);
2316                                 }
2317                                 struct_fmt.finish()
2318                             }
2319                         }
2320                     }
2321
2322                     AggregateKind::Closure(def_id, substs) => ty::tls::with(|tcx| {
2323                         if let Some(def_id) = def_id.as_local() {
2324                             let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
2325                             let name = if tcx.sess.opts.debugging_opts.span_free_formats {
2326                                 let substs = tcx.lift(substs).unwrap();
2327                                 format!(
2328                                     "[closure@{}]",
2329                                     tcx.def_path_str_with_substs(def_id.to_def_id(), substs),
2330                                 )
2331                             } else {
2332                                 let span = tcx.hir().span(hir_id);
2333                                 format!("[closure@{}]", tcx.sess.source_map().span_to_string(span))
2334                             };
2335                             let mut struct_fmt = fmt.debug_struct(&name);
2336
2337                             if let Some(upvars) = tcx.upvars_mentioned(def_id) {
2338                                 for (&var_id, place) in iter::zip(upvars.keys(), places) {
2339                                     let var_name = tcx.hir().name(var_id);
2340                                     struct_fmt.field(&var_name.as_str(), place);
2341                                 }
2342                             }
2343
2344                             struct_fmt.finish()
2345                         } else {
2346                             write!(fmt, "[closure]")
2347                         }
2348                     }),
2349
2350                     AggregateKind::Generator(def_id, _, _) => ty::tls::with(|tcx| {
2351                         if let Some(def_id) = def_id.as_local() {
2352                             let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
2353                             let name = format!("[generator@{:?}]", tcx.hir().span(hir_id));
2354                             let mut struct_fmt = fmt.debug_struct(&name);
2355
2356                             if let Some(upvars) = tcx.upvars_mentioned(def_id) {
2357                                 for (&var_id, place) in iter::zip(upvars.keys(), places) {
2358                                     let var_name = tcx.hir().name(var_id);
2359                                     struct_fmt.field(&var_name.as_str(), place);
2360                                 }
2361                             }
2362
2363                             struct_fmt.finish()
2364                         } else {
2365                             write!(fmt, "[generator]")
2366                         }
2367                     }),
2368                 }
2369             }
2370         }
2371     }
2372 }
2373
2374 ///////////////////////////////////////////////////////////////////////////
2375 /// Constants
2376 ///
2377 /// Two constants are equal if they are the same constant. Note that
2378 /// this does not necessarily mean that they are `==` in Rust. In
2379 /// particular, one must be wary of `NaN`!
2380
2381 #[derive(Clone, Copy, PartialEq, PartialOrd, TyEncodable, TyDecodable, Hash, HashStable)]
2382 pub struct Constant<'tcx> {
2383     pub span: Span,
2384
2385     /// Optional user-given type: for something like
2386     /// `collect::<Vec<_>>`, this would be present and would
2387     /// indicate that `Vec<_>` was explicitly specified.
2388     ///
2389     /// Needed for NLL to impose user-given type constraints.
2390     pub user_ty: Option<UserTypeAnnotationIndex>,
2391
2392     pub literal: ConstantKind<'tcx>,
2393 }
2394
2395 #[derive(Clone, Copy, PartialEq, PartialOrd, TyEncodable, TyDecodable, Hash, HashStable, Debug)]
2396 pub enum ConstantKind<'tcx> {
2397     /// This constant came from the type system
2398     Ty(&'tcx ty::Const<'tcx>),
2399     /// This constant cannot go back into the type system, as it represents
2400     /// something the type system cannot handle (e.g. pointers).
2401     Val(interpret::ConstValue<'tcx>, Ty<'tcx>),
2402 }
2403
2404 impl Constant<'tcx> {
2405     pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
2406         match self.literal.const_for_ty()?.val.try_to_scalar() {
2407             Some(Scalar::Ptr(ptr)) => match tcx.global_alloc(ptr.alloc_id) {
2408                 GlobalAlloc::Static(def_id) => {
2409                     assert!(!tcx.is_thread_local_static(def_id));
2410                     Some(def_id)
2411                 }
2412                 _ => None,
2413             },
2414             _ => None,
2415         }
2416     }
2417     pub fn ty(&self) -> Ty<'tcx> {
2418         self.literal.ty()
2419     }
2420 }
2421
2422 impl From<&'tcx ty::Const<'tcx>> for ConstantKind<'tcx> {
2423     fn from(ct: &'tcx ty::Const<'tcx>) -> Self {
2424         Self::Ty(ct)
2425     }
2426 }
2427
2428 impl ConstantKind<'tcx> {
2429     /// Returns `None` if the constant is not trivially safe for use in the type system.
2430     pub fn const_for_ty(&self) -> Option<&'tcx ty::Const<'tcx>> {
2431         match self {
2432             ConstantKind::Ty(c) => Some(c),
2433             ConstantKind::Val(..) => None,
2434         }
2435     }
2436
2437     pub fn ty(&self) -> Ty<'tcx> {
2438         match self {
2439             ConstantKind::Ty(c) => c.ty,
2440             ConstantKind::Val(_, ty) => ty,
2441         }
2442     }
2443
2444     #[inline]
2445     pub fn try_to_value(self) -> Option<interpret::ConstValue<'tcx>> {
2446         match self {
2447             ConstantKind::Ty(c) => c.val.try_to_value(),
2448             ConstantKind::Val(val, _) => Some(val),
2449         }
2450     }
2451
2452     #[inline]
2453     pub fn try_to_scalar(self) -> Option<Scalar> {
2454         self.try_to_value()?.try_to_scalar()
2455     }
2456
2457     #[inline]
2458     pub fn try_to_scalar_int(self) -> Option<ScalarInt> {
2459         Some(self.try_to_value()?.try_to_scalar()?.assert_int())
2460     }
2461
2462     #[inline]
2463     pub fn try_to_bits(self, size: Size) -> Option<u128> {
2464         self.try_to_scalar_int()?.to_bits(size).ok()
2465     }
2466
2467     #[inline]
2468     pub fn try_to_bool(self) -> Option<bool> {
2469         self.try_to_scalar_int()?.try_into().ok()
2470     }
2471
2472     #[inline]
2473     pub fn try_eval_bits(
2474         &self,
2475         tcx: TyCtxt<'tcx>,
2476         param_env: ty::ParamEnv<'tcx>,
2477         ty: Ty<'tcx>,
2478     ) -> Option<u128> {
2479         match self {
2480             Self::Ty(ct) => ct.try_eval_bits(tcx, param_env, ty),
2481             Self::Val(val, t) => {
2482                 assert_eq!(*t, ty);
2483                 let size =
2484                     tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
2485                 val.try_to_bits(size)
2486             }
2487         }
2488     }
2489
2490     #[inline]
2491     pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option<bool> {
2492         match self {
2493             Self::Ty(ct) => ct.try_eval_bool(tcx, param_env),
2494             Self::Val(val, _) => val.try_to_bool(),
2495         }
2496     }
2497
2498     #[inline]
2499     pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option<u64> {
2500         match self {
2501             Self::Ty(ct) => ct.try_eval_usize(tcx, param_env),
2502             Self::Val(val, _) => val.try_to_machine_usize(tcx),
2503         }
2504     }
2505 }
2506
2507 /// A collection of projections into user types.
2508 ///
2509 /// They are projections because a binding can occur a part of a
2510 /// parent pattern that has been ascribed a type.
2511 ///
2512 /// Its a collection because there can be multiple type ascriptions on
2513 /// the path from the root of the pattern down to the binding itself.
2514 ///
2515 /// An example:
2516 ///
2517 /// ```rust
2518 /// struct S<'a>((i32, &'a str), String);
2519 /// let S((_, w): (i32, &'static str), _): S = ...;
2520 /// //    ------  ^^^^^^^^^^^^^^^^^^^ (1)
2521 /// //  ---------------------------------  ^ (2)
2522 /// ```
2523 ///
2524 /// The highlights labelled `(1)` show the subpattern `(_, w)` being
2525 /// ascribed the type `(i32, &'static str)`.
2526 ///
2527 /// The highlights labelled `(2)` show the whole pattern being
2528 /// ascribed the type `S`.
2529 ///
2530 /// In this example, when we descend to `w`, we will have built up the
2531 /// following two projected types:
2532 ///
2533 ///   * base: `S`,                   projection: `(base.0).1`
2534 ///   * base: `(i32, &'static str)`, projection: `base.1`
2535 ///
2536 /// The first will lead to the constraint `w: &'1 str` (for some
2537 /// inferred region `'1`). The second will lead to the constraint `w:
2538 /// &'static str`.
2539 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
2540 pub struct UserTypeProjections {
2541     pub contents: Vec<(UserTypeProjection, Span)>,
2542 }
2543
2544 impl<'tcx> UserTypeProjections {
2545     pub fn none() -> Self {
2546         UserTypeProjections { contents: vec![] }
2547     }
2548
2549     pub fn is_empty(&self) -> bool {
2550         self.contents.is_empty()
2551     }
2552
2553     pub fn projections_and_spans(
2554         &self,
2555     ) -> impl Iterator<Item = &(UserTypeProjection, Span)> + ExactSizeIterator {
2556         self.contents.iter()
2557     }
2558
2559     pub fn projections(&self) -> impl Iterator<Item = &UserTypeProjection> + ExactSizeIterator {
2560         self.contents.iter().map(|&(ref user_type, _span)| user_type)
2561     }
2562
2563     pub fn push_projection(mut self, user_ty: &UserTypeProjection, span: Span) -> Self {
2564         self.contents.push((user_ty.clone(), span));
2565         self
2566     }
2567
2568     fn map_projections(
2569         mut self,
2570         mut f: impl FnMut(UserTypeProjection) -> UserTypeProjection,
2571     ) -> Self {
2572         self.contents = self.contents.drain(..).map(|(proj, span)| (f(proj), span)).collect();
2573         self
2574     }
2575
2576     pub fn index(self) -> Self {
2577         self.map_projections(|pat_ty_proj| pat_ty_proj.index())
2578     }
2579
2580     pub fn subslice(self, from: u64, to: u64) -> Self {
2581         self.map_projections(|pat_ty_proj| pat_ty_proj.subslice(from, to))
2582     }
2583
2584     pub fn deref(self) -> Self {
2585         self.map_projections(|pat_ty_proj| pat_ty_proj.deref())
2586     }
2587
2588     pub fn leaf(self, field: Field) -> Self {
2589         self.map_projections(|pat_ty_proj| pat_ty_proj.leaf(field))
2590     }
2591
2592     pub fn variant(self, adt_def: &'tcx AdtDef, variant_index: VariantIdx, field: Field) -> Self {
2593         self.map_projections(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field))
2594     }
2595 }
2596
2597 /// Encodes the effect of a user-supplied type annotation on the
2598 /// subcomponents of a pattern. The effect is determined by applying the
2599 /// given list of proejctions to some underlying base type. Often,
2600 /// the projection element list `projs` is empty, in which case this
2601 /// directly encodes a type in `base`. But in the case of complex patterns with
2602 /// subpatterns and bindings, we want to apply only a *part* of the type to a variable,
2603 /// in which case the `projs` vector is used.
2604 ///
2605 /// Examples:
2606 ///
2607 /// * `let x: T = ...` -- here, the `projs` vector is empty.
2608 ///
2609 /// * `let (x, _): T = ...` -- here, the `projs` vector would contain
2610 ///   `field[0]` (aka `.0`), indicating that the type of `s` is
2611 ///   determined by finding the type of the `.0` field from `T`.
2612 #[derive(Clone, Debug, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
2613 pub struct UserTypeProjection {
2614     pub base: UserTypeAnnotationIndex,
2615     pub projs: Vec<ProjectionKind>,
2616 }
2617
2618 impl Copy for ProjectionKind {}
2619
2620 impl UserTypeProjection {
2621     pub(crate) fn index(mut self) -> Self {
2622         self.projs.push(ProjectionElem::Index(()));
2623         self
2624     }
2625
2626     pub(crate) fn subslice(mut self, from: u64, to: u64) -> Self {
2627         self.projs.push(ProjectionElem::Subslice { from, to, from_end: true });
2628         self
2629     }
2630
2631     pub(crate) fn deref(mut self) -> Self {
2632         self.projs.push(ProjectionElem::Deref);
2633         self
2634     }
2635
2636     pub(crate) fn leaf(mut self, field: Field) -> Self {
2637         self.projs.push(ProjectionElem::Field(field, ()));
2638         self
2639     }
2640
2641     pub(crate) fn variant(
2642         mut self,
2643         adt_def: &AdtDef,
2644         variant_index: VariantIdx,
2645         field: Field,
2646     ) -> Self {
2647         self.projs.push(ProjectionElem::Downcast(
2648             Some(adt_def.variants[variant_index].ident.name),
2649             variant_index,
2650         ));
2651         self.projs.push(ProjectionElem::Field(field, ()));
2652         self
2653     }
2654 }
2655
2656 TrivialTypeFoldableAndLiftImpls! { ProjectionKind, }
2657
2658 impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
2659     fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
2660         UserTypeProjection {
2661             base: self.base.fold_with(folder),
2662             projs: self.projs.fold_with(folder),
2663         }
2664     }
2665
2666     fn super_visit_with<Vs: TypeVisitor<'tcx>>(
2667         &self,
2668         visitor: &mut Vs,
2669     ) -> ControlFlow<Vs::BreakTy> {
2670         self.base.visit_with(visitor)
2671         // Note: there's nothing in `self.proj` to visit.
2672     }
2673 }
2674
2675 rustc_index::newtype_index! {
2676     pub struct Promoted {
2677         derive [HashStable]
2678         DEBUG_FORMAT = "promoted[{}]"
2679     }
2680 }
2681
2682 impl<'tcx> Debug for Constant<'tcx> {
2683     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
2684         write!(fmt, "{}", self)
2685     }
2686 }
2687
2688 impl<'tcx> Display for Constant<'tcx> {
2689     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
2690         match self.ty().kind() {
2691             ty::FnDef(..) => {}
2692             _ => write!(fmt, "const ")?,
2693         }
2694         match self.literal {
2695             ConstantKind::Ty(c) => pretty_print_const(c, fmt, true),
2696             ConstantKind::Val(val, ty) => pretty_print_const_value(val, ty, fmt, true),
2697         }
2698     }
2699 }
2700
2701 fn pretty_print_const(
2702     c: &ty::Const<'tcx>,
2703     fmt: &mut Formatter<'_>,
2704     print_types: bool,
2705 ) -> fmt::Result {
2706     use crate::ty::print::PrettyPrinter;
2707     ty::tls::with(|tcx| {
2708         let literal = tcx.lift(c).unwrap();
2709         let mut cx = FmtPrinter::new(tcx, fmt, Namespace::ValueNS);
2710         cx.print_alloc_ids = true;
2711         cx.pretty_print_const(literal, print_types)?;
2712         Ok(())
2713     })
2714 }
2715
2716 fn pretty_print_const_value(
2717     val: interpret::ConstValue<'tcx>,
2718     ty: Ty<'tcx>,
2719     fmt: &mut Formatter<'_>,
2720     print_types: bool,
2721 ) -> fmt::Result {
2722     use crate::ty::print::PrettyPrinter;
2723     ty::tls::with(|tcx| {
2724         let val = tcx.lift(val).unwrap();
2725         let ty = tcx.lift(ty).unwrap();
2726         let mut cx = FmtPrinter::new(tcx, fmt, Namespace::ValueNS);
2727         cx.print_alloc_ids = true;
2728         cx.pretty_print_const_value(val, ty, print_types)?;
2729         Ok(())
2730     })
2731 }
2732
2733 impl<'tcx> graph::DirectedGraph for Body<'tcx> {
2734     type Node = BasicBlock;
2735 }
2736
2737 impl<'tcx> graph::WithNumNodes for Body<'tcx> {
2738     #[inline]
2739     fn num_nodes(&self) -> usize {
2740         self.basic_blocks.len()
2741     }
2742 }
2743
2744 impl<'tcx> graph::WithStartNode for Body<'tcx> {
2745     #[inline]
2746     fn start_node(&self) -> Self::Node {
2747         START_BLOCK
2748     }
2749 }
2750
2751 impl<'tcx> graph::WithSuccessors for Body<'tcx> {
2752     #[inline]
2753     fn successors(&self, node: Self::Node) -> <Self as GraphSuccessors<'_>>::Iter {
2754         self.basic_blocks[node].terminator().successors().cloned()
2755     }
2756 }
2757
2758 impl<'a, 'b> graph::GraphSuccessors<'b> for Body<'a> {
2759     type Item = BasicBlock;
2760     type Iter = iter::Cloned<Successors<'b>>;
2761 }
2762
2763 impl graph::GraphPredecessors<'graph> for Body<'tcx> {
2764     type Item = BasicBlock;
2765     type Iter = smallvec::IntoIter<[BasicBlock; 4]>;
2766 }
2767
2768 impl graph::WithPredecessors for Body<'tcx> {
2769     #[inline]
2770     fn predecessors(&self, node: Self::Node) -> <Self as graph::GraphPredecessors<'_>>::Iter {
2771         self.predecessors()[node].clone().into_iter()
2772     }
2773 }
2774
2775 /// `Location` represents the position of the start of the statement; or, if
2776 /// `statement_index` equals the number of statements, then the start of the
2777 /// terminator.
2778 #[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable)]
2779 pub struct Location {
2780     /// The block that the location is within.
2781     pub block: BasicBlock,
2782
2783     pub statement_index: usize,
2784 }
2785
2786 impl fmt::Debug for Location {
2787     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2788         write!(fmt, "{:?}[{}]", self.block, self.statement_index)
2789     }
2790 }
2791
2792 impl Location {
2793     pub const START: Location = Location { block: START_BLOCK, statement_index: 0 };
2794
2795     /// Returns the location immediately after this one within the enclosing block.
2796     ///
2797     /// Note that if this location represents a terminator, then the
2798     /// resulting location would be out of bounds and invalid.
2799     pub fn successor_within_block(&self) -> Location {
2800         Location { block: self.block, statement_index: self.statement_index + 1 }
2801     }
2802
2803     /// Returns `true` if `other` is earlier in the control flow graph than `self`.
2804     pub fn is_predecessor_of<'tcx>(&self, other: Location, body: &Body<'tcx>) -> bool {
2805         // If we are in the same block as the other location and are an earlier statement
2806         // then we are a predecessor of `other`.
2807         if self.block == other.block && self.statement_index < other.statement_index {
2808             return true;
2809         }
2810
2811         let predecessors = body.predecessors();
2812
2813         // If we're in another block, then we want to check that block is a predecessor of `other`.
2814         let mut queue: Vec<BasicBlock> = predecessors[other.block].to_vec();
2815         let mut visited = FxHashSet::default();
2816
2817         while let Some(block) = queue.pop() {
2818             // If we haven't visited this block before, then make sure we visit it's predecessors.
2819             if visited.insert(block) {
2820                 queue.extend(predecessors[block].iter().cloned());
2821             } else {
2822                 continue;
2823             }
2824
2825             // If we found the block that `self` is in, then we are a predecessor of `other` (since
2826             // we found that block by looking at the predecessors of `other`).
2827             if self.block == block {
2828                 return true;
2829             }
2830         }
2831
2832         false
2833     }
2834
2835     pub fn dominates(&self, other: Location, dominators: &Dominators<BasicBlock>) -> bool {
2836         if self.block == other.block {
2837             self.statement_index <= other.statement_index
2838         } else {
2839             dominators.is_dominated_by(other.block, self.block)
2840         }
2841     }
2842 }