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