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