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