]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/mir/mod.rs
correct mirphase docs
[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::{
7     AllocRange, ConstAllocation, ConstValue, GlobalAlloc, LitToConstInput, Scalar,
8 };
9 use crate::mir::visit::MirVisitable;
10 use crate::ty::adjustment::PointerCast;
11 use crate::ty::codec::{TyDecoder, TyEncoder};
12 use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable, TypeVisitor};
13 use crate::ty::print::{FmtPrinter, Printer};
14 use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
15 use crate::ty::{self, List, Ty, TyCtxt};
16 use crate::ty::{AdtDef, InstanceDef, Region, ScalarInt, UserTypeAnnotationIndex};
17
18 use rustc_data_structures::captures::Captures;
19 use rustc_errors::ErrorGuaranteed;
20 use rustc_hir::def::{CtorKind, Namespace};
21 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
22 use rustc_hir::{self, GeneratorKind};
23 use rustc_hir::{self as hir, HirId};
24 use rustc_session::Session;
25 use rustc_target::abi::{Size, VariantIdx};
26
27 use polonius_engine::Atom;
28 pub use rustc_ast::Mutability;
29 use rustc_data_structures::fx::FxHashSet;
30 use rustc_data_structures::graph::dominators::{dominators, Dominators};
31 use rustc_data_structures::graph::{self, GraphSuccessors};
32 use rustc_index::bit_set::BitMatrix;
33 use rustc_index::vec::{Idx, IndexVec};
34 use rustc_serialize::{Decodable, Encodable};
35 use rustc_span::symbol::Symbol;
36 use rustc_span::{Span, DUMMY_SP};
37 use rustc_target::asm::InlineAsmRegOrRegClass;
38
39 use either::Either;
40
41 use std::borrow::Cow;
42 use std::convert::TryInto;
43 use std::fmt::{self, Debug, Display, Formatter, Write};
44 use std::ops::{ControlFlow, Index, IndexMut};
45 use std::slice;
46 use std::{iter, mem, option};
47
48 use self::graph_cyclic_cache::GraphIsCyclicCache;
49 use self::predecessors::{PredecessorCache, Predecessors};
50 pub use self::query::*;
51 use self::switch_sources::{SwitchSourceCache, SwitchSources};
52
53 pub mod coverage;
54 mod generic_graph;
55 pub mod generic_graphviz;
56 mod graph_cyclic_cache;
57 pub mod graphviz;
58 pub mod interpret;
59 pub mod mono;
60 pub mod patch;
61 mod predecessors;
62 pub mod pretty;
63 mod query;
64 pub mod spanview;
65 mod switch_sources;
66 pub mod tcx;
67 pub mod terminator;
68 use crate::mir::traversal::PostorderCache;
69 pub use terminator::*;
70
71 pub mod traversal;
72 mod type_foldable;
73 pub mod visit;
74
75 pub use self::generic_graph::graphviz_safe_def_name;
76 pub use self::graphviz::write_mir_graphviz;
77 pub use self::pretty::{
78     create_dump_file, display_allocation, dump_enabled, dump_mir, write_mir_pretty, PassWhere,
79 };
80
81 /// Types for locals
82 pub type LocalDecls<'tcx> = IndexVec<Local, LocalDecl<'tcx>>;
83
84 pub trait HasLocalDecls<'tcx> {
85     fn local_decls(&self) -> &LocalDecls<'tcx>;
86 }
87
88 impl<'tcx> HasLocalDecls<'tcx> for LocalDecls<'tcx> {
89     #[inline]
90     fn local_decls(&self) -> &LocalDecls<'tcx> {
91         self
92     }
93 }
94
95 impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
96     #[inline]
97     fn local_decls(&self) -> &LocalDecls<'tcx> {
98         &self.local_decls
99     }
100 }
101
102 /// A streamlined trait that you can implement to create a pass; the
103 /// pass will be named after the type, and it will consist of a main
104 /// loop that goes over each available MIR and applies `run_pass`.
105 pub trait MirPass<'tcx> {
106     fn name(&self) -> Cow<'_, str> {
107         let name = std::any::type_name::<Self>();
108         if let Some(tail) = name.rfind(':') {
109             Cow::from(&name[tail + 1..])
110         } else {
111             Cow::from(name)
112         }
113     }
114
115     /// Returns `true` if this pass is enabled with the current combination of compiler flags.
116     fn is_enabled(&self, _sess: &Session) -> bool {
117         true
118     }
119
120     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>);
121
122     /// If this pass causes the MIR to enter a new phase, return that phase.
123     fn phase_change(&self) -> Option<MirPhase> {
124         None
125     }
126
127     fn is_mir_dump_enabled(&self) -> bool {
128         true
129     }
130 }
131
132 /// The various "big phases" that MIR goes through.
133 ///
134 /// These phases all describe dialects of MIR. Since all MIR uses the same datastructures, the
135 /// dialects forbid certain variants or values in certain phases. The sections below summarize the
136 /// changes, but do not document them thoroughly. The full documentation is found in the appropriate
137 /// documentation for the thing the change is affecting.
138 ///
139 /// Warning: ordering of variants is significant.
140 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
141 #[derive(HashStable)]
142 pub enum MirPhase {
143     /// The dialect of MIR used during all phases before `DropsLowered` is the same. This is also
144     /// the MIR that analysis such as borrowck uses.
145     ///
146     /// One important thing to remember about the behavior of this section of MIR is that drop terminators
147     /// (including drop and replace) are *conditional*. The elaborate drops pass will then replace each
148     /// instance of a drop terminator with a nop, an unconditional drop, or a drop conditioned on a drop
149     /// flag. Of course, this means that it is important that the drop elaboration can accurately recognize
150     /// when things are initialized and when things are de-initialized. That means any code running on this
151     /// version of MIR must be sure to produce output that drop elaboration can reason about. See the
152     /// section on the drop terminatorss for more details.
153     Built = 0,
154     // FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query).
155     // We used to have this for pre-miri MIR based const eval.
156     Const = 1,
157     /// This phase checks the MIR for promotable elements and takes them out of the main MIR body
158     /// by creating a new MIR body per promoted element. After this phase (and thus the termination
159     /// of the `mir_promoted` query), these promoted elements are available in the `promoted_mir`
160     /// query.
161     ConstsPromoted = 2,
162     /// Beginning with this phase, the following variants are disallowed:
163     /// * [`TerminatorKind::DropAndReplace`](terminator::TerminatorKind::DropAndReplace)
164     /// * [`TerminatorKind::FalseUnwind`](terminator::TerminatorKind::FalseUnwind)
165     /// * [`TerminatorKind::FalseEdge`](terminator::TerminatorKind::FalseEdge)
166     /// * [`StatementKind::FakeRead`]
167     /// * [`StatementKind::AscribeUserType`]
168     /// * [`Rvalue::Ref`] with `BorrowKind::Shallow`
169     ///
170     /// And the following variant is allowed:
171     /// * [`StatementKind::Retag`]
172     ///
173     /// Furthermore, `Drop` now uses explicit drop flags visible in the MIR and reaching a `Drop`
174     /// terminator means that the auto-generated drop glue will be invoked. Also, `Copy` operands
175     /// are allowed for non-`Copy` types.
176     DropsLowered = 3,
177     /// After this projections may only contain deref projections as the first element.
178     Derefered = 4,
179     /// Beginning with this phase, the following variant is disallowed:
180     /// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array`
181     ///
182     /// And the following variant is allowed:
183     /// * [`StatementKind::SetDiscriminant`]
184     Deaggregated = 5,
185     /// Before this phase, generators are in the "source code" form, featuring `yield` statements
186     /// and such. With this phase change, they are transformed into a proper state machine. Running
187     /// optimizations before this change can be potentially dangerous because the source code is to
188     /// some extent a "lie." In particular, `yield` terminators effectively make the value of all
189     /// locals visible to the caller. This means that dead store elimination before them, or code
190     /// motion across them, is not correct in general. This is also exasperated by type checking
191     /// having pre-computed a list of the types that it thinks are ok to be live across a yield
192     /// point - this is necessary to decide eg whether autotraits are implemented. Introducing new
193     /// types across a yield point will lead to ICEs becaues of this.
194     ///
195     /// Beginning with this phase, the following variants are disallowed:
196     /// * [`TerminatorKind::Yield`](terminator::TerminatorKind::Yield)
197     /// * [`TerminatorKind::GeneratorDrop`](terminator::TerminatorKind::GeneratorDrop)
198     /// * [`ProjectionElem::Deref`] of `Box`
199     GeneratorsLowered = 6,
200     Optimized = 7,
201 }
202
203 impl MirPhase {
204     /// Gets the index of the current MirPhase within the set of all `MirPhase`s.
205     pub fn phase_index(&self) -> usize {
206         *self as usize
207     }
208 }
209
210 /// Where a specific `mir::Body` comes from.
211 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
212 #[derive(HashStable, TyEncodable, TyDecodable, TypeFoldable)]
213 pub struct MirSource<'tcx> {
214     pub instance: InstanceDef<'tcx>,
215
216     /// If `Some`, this is a promoted rvalue within the parent function.
217     pub promoted: Option<Promoted>,
218 }
219
220 impl<'tcx> MirSource<'tcx> {
221     pub fn item(def_id: DefId) -> Self {
222         MirSource {
223             instance: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
224             promoted: None,
225         }
226     }
227
228     pub fn from_instance(instance: InstanceDef<'tcx>) -> Self {
229         MirSource { instance, promoted: None }
230     }
231
232     pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> {
233         self.instance.with_opt_param()
234     }
235
236     #[inline]
237     pub fn def_id(&self) -> DefId {
238         self.instance.def_id()
239     }
240 }
241
242 #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)]
243 pub struct GeneratorInfo<'tcx> {
244     /// The yield type of the function, if it is a generator.
245     pub yield_ty: Option<Ty<'tcx>>,
246
247     /// Generator drop glue.
248     pub generator_drop: Option<Body<'tcx>>,
249
250     /// The layout of a generator. Produced by the state transformation.
251     pub generator_layout: Option<GeneratorLayout<'tcx>>,
252
253     /// If this is a generator then record the type of source expression that caused this generator
254     /// to be created.
255     pub generator_kind: GeneratorKind,
256 }
257
258 /// The lowered representation of a single function.
259 #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable)]
260 pub struct Body<'tcx> {
261     /// A list of basic blocks. References to basic block use a newtyped index type [`BasicBlock`]
262     /// that indexes into this vector.
263     basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
264
265     /// Records how far through the "desugaring and optimization" process this particular
266     /// MIR has traversed. This is particularly useful when inlining, since in that context
267     /// we instantiate the promoted constants and add them to our promoted vector -- but those
268     /// promoted items have already been optimized, whereas ours have not. This field allows
269     /// us to see the difference and forego optimization on the inlined promoted items.
270     pub phase: MirPhase,
271
272     pub source: MirSource<'tcx>,
273
274     /// A list of source scopes; these are referenced by statements
275     /// and used for debuginfo. Indexed by a `SourceScope`.
276     pub source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
277
278     pub generator: Option<Box<GeneratorInfo<'tcx>>>,
279
280     /// Declarations of locals.
281     ///
282     /// The first local is the return value pointer, followed by `arg_count`
283     /// locals for the function arguments, followed by any user-declared
284     /// variables and temporaries.
285     pub local_decls: LocalDecls<'tcx>,
286
287     /// User type annotations.
288     pub user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
289
290     /// The number of arguments this function takes.
291     ///
292     /// Starting at local 1, `arg_count` locals will be provided by the caller
293     /// and can be assumed to be initialized.
294     ///
295     /// If this MIR was built for a constant, this will be 0.
296     pub arg_count: usize,
297
298     /// Mark an argument local (which must be a tuple) as getting passed as
299     /// its individual components at the LLVM level.
300     ///
301     /// This is used for the "rust-call" ABI.
302     pub spread_arg: Option<Local>,
303
304     /// Debug information pertaining to user variables, including captures.
305     pub var_debug_info: Vec<VarDebugInfo<'tcx>>,
306
307     /// A span representing this MIR, for error reporting.
308     pub span: Span,
309
310     /// Constants that are required to evaluate successfully for this MIR to be well-formed.
311     /// We hold in this field all the constants we are not able to evaluate yet.
312     pub required_consts: Vec<Constant<'tcx>>,
313
314     /// Does this body use generic parameters. This is used for the `ConstEvaluatable` check.
315     ///
316     /// Note that this does not actually mean that this body is not computable right now.
317     /// The repeat count in the following example is polymorphic, but can still be evaluated
318     /// without knowing anything about the type parameter `T`.
319     ///
320     /// ```rust
321     /// fn test<T>() {
322     ///     let _ = [0; std::mem::size_of::<*mut T>()];
323     /// }
324     /// ```
325     ///
326     /// **WARNING**: Do not change this flags after the MIR was originally created, even if an optimization
327     /// removed the last mention of all generic params. We do not want to rely on optimizations and
328     /// potentially allow things like `[u8; std::mem::size_of::<T>() * 0]` due to this.
329     pub is_polymorphic: bool,
330
331     predecessor_cache: PredecessorCache,
332     switch_source_cache: SwitchSourceCache,
333     is_cyclic: GraphIsCyclicCache,
334     postorder_cache: PostorderCache,
335
336     pub tainted_by_errors: Option<ErrorGuaranteed>,
337 }
338
339 impl<'tcx> Body<'tcx> {
340     pub fn new(
341         source: MirSource<'tcx>,
342         basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
343         source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
344         local_decls: LocalDecls<'tcx>,
345         user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
346         arg_count: usize,
347         var_debug_info: Vec<VarDebugInfo<'tcx>>,
348         span: Span,
349         generator_kind: Option<GeneratorKind>,
350         tainted_by_errors: Option<ErrorGuaranteed>,
351     ) -> Self {
352         // We need `arg_count` locals, and one for the return place.
353         assert!(
354             local_decls.len() > arg_count,
355             "expected at least {} locals, got {}",
356             arg_count + 1,
357             local_decls.len()
358         );
359
360         let mut body = Body {
361             phase: MirPhase::Built,
362             source,
363             basic_blocks,
364             source_scopes,
365             generator: generator_kind.map(|generator_kind| {
366                 Box::new(GeneratorInfo {
367                     yield_ty: None,
368                     generator_drop: None,
369                     generator_layout: None,
370                     generator_kind,
371                 })
372             }),
373             local_decls,
374             user_type_annotations,
375             arg_count,
376             spread_arg: None,
377             var_debug_info,
378             span,
379             required_consts: Vec::new(),
380             is_polymorphic: false,
381             predecessor_cache: PredecessorCache::new(),
382             switch_source_cache: SwitchSourceCache::new(),
383             is_cyclic: GraphIsCyclicCache::new(),
384             postorder_cache: PostorderCache::new(),
385             tainted_by_errors,
386         };
387         body.is_polymorphic = body.has_param_types_or_consts();
388         body
389     }
390
391     /// Returns a partially initialized MIR body containing only a list of basic blocks.
392     ///
393     /// The returned MIR contains no `LocalDecl`s (even for the return place) or source scopes. It
394     /// is only useful for testing but cannot be `#[cfg(test)]` because it is used in a different
395     /// crate.
396     pub fn new_cfg_only(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self {
397         let mut body = Body {
398             phase: MirPhase::Built,
399             source: MirSource::item(CRATE_DEF_ID.to_def_id()),
400             basic_blocks,
401             source_scopes: IndexVec::new(),
402             generator: None,
403             local_decls: IndexVec::new(),
404             user_type_annotations: IndexVec::new(),
405             arg_count: 0,
406             spread_arg: None,
407             span: DUMMY_SP,
408             required_consts: Vec::new(),
409             var_debug_info: Vec::new(),
410             is_polymorphic: false,
411             predecessor_cache: PredecessorCache::new(),
412             switch_source_cache: SwitchSourceCache::new(),
413             is_cyclic: GraphIsCyclicCache::new(),
414             postorder_cache: PostorderCache::new(),
415             tainted_by_errors: None,
416         };
417         body.is_polymorphic = body.has_param_types_or_consts();
418         body
419     }
420
421     #[inline]
422     pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
423         &self.basic_blocks
424     }
425
426     #[inline]
427     pub fn basic_blocks_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
428         // Because the user could mutate basic block terminators via this reference, we need to
429         // invalidate the caches.
430         //
431         // FIXME: Use a finer-grained API for this, so only transformations that alter terminators
432         // invalidate the caches.
433         self.predecessor_cache.invalidate();
434         self.switch_source_cache.invalidate();
435         self.is_cyclic.invalidate();
436         self.postorder_cache.invalidate();
437         &mut self.basic_blocks
438     }
439
440     #[inline]
441     pub fn basic_blocks_and_local_decls_mut(
442         &mut self,
443     ) -> (&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, &mut LocalDecls<'tcx>) {
444         self.predecessor_cache.invalidate();
445         self.switch_source_cache.invalidate();
446         self.is_cyclic.invalidate();
447         self.postorder_cache.invalidate();
448         (&mut self.basic_blocks, &mut self.local_decls)
449     }
450
451     #[inline]
452     pub fn basic_blocks_local_decls_mut_and_var_debug_info(
453         &mut self,
454     ) -> (
455         &mut IndexVec<BasicBlock, BasicBlockData<'tcx>>,
456         &mut LocalDecls<'tcx>,
457         &mut Vec<VarDebugInfo<'tcx>>,
458     ) {
459         self.predecessor_cache.invalidate();
460         self.switch_source_cache.invalidate();
461         self.is_cyclic.invalidate();
462         self.postorder_cache.invalidate();
463         (&mut self.basic_blocks, &mut self.local_decls, &mut self.var_debug_info)
464     }
465
466     /// Returns `true` if a cycle exists in the control-flow graph that is reachable from the
467     /// `START_BLOCK`.
468     pub fn is_cfg_cyclic(&self) -> bool {
469         self.is_cyclic.is_cyclic(self)
470     }
471
472     #[inline]
473     pub fn local_kind(&self, local: Local) -> LocalKind {
474         let index = local.as_usize();
475         if index == 0 {
476             debug_assert!(
477                 self.local_decls[local].mutability == Mutability::Mut,
478                 "return place should be mutable"
479             );
480
481             LocalKind::ReturnPointer
482         } else if index < self.arg_count + 1 {
483             LocalKind::Arg
484         } else if self.local_decls[local].is_user_variable() {
485             LocalKind::Var
486         } else {
487             LocalKind::Temp
488         }
489     }
490
491     /// Returns an iterator over all user-declared mutable locals.
492     #[inline]
493     pub fn mut_vars_iter<'a>(&'a self) -> impl Iterator<Item = Local> + Captures<'tcx> + 'a {
494         (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
495             let local = Local::new(index);
496             let decl = &self.local_decls[local];
497             if decl.is_user_variable() && decl.mutability == Mutability::Mut {
498                 Some(local)
499             } else {
500                 None
501             }
502         })
503     }
504
505     /// Returns an iterator over all user-declared mutable arguments and locals.
506     #[inline]
507     pub fn mut_vars_and_args_iter<'a>(
508         &'a self,
509     ) -> impl Iterator<Item = Local> + Captures<'tcx> + 'a {
510         (1..self.local_decls.len()).filter_map(move |index| {
511             let local = Local::new(index);
512             let decl = &self.local_decls[local];
513             if (decl.is_user_variable() || index < self.arg_count + 1)
514                 && decl.mutability == Mutability::Mut
515             {
516                 Some(local)
517             } else {
518                 None
519             }
520         })
521     }
522
523     /// Returns an iterator over all function arguments.
524     #[inline]
525     pub fn args_iter(&self) -> impl Iterator<Item = Local> + ExactSizeIterator {
526         (1..self.arg_count + 1).map(Local::new)
527     }
528
529     /// Returns an iterator over all user-defined variables and compiler-generated temporaries (all
530     /// locals that are neither arguments nor the return place).
531     #[inline]
532     pub fn vars_and_temps_iter(
533         &self,
534     ) -> impl DoubleEndedIterator<Item = Local> + ExactSizeIterator {
535         (self.arg_count + 1..self.local_decls.len()).map(Local::new)
536     }
537
538     #[inline]
539     pub fn drain_vars_and_temps<'a>(&'a mut self) -> impl Iterator<Item = LocalDecl<'tcx>> + 'a {
540         self.local_decls.drain(self.arg_count + 1..)
541     }
542
543     /// Changes a statement to a nop. This is both faster than deleting instructions and avoids
544     /// invalidating statement indices in `Location`s.
545     pub fn make_statement_nop(&mut self, location: Location) {
546         let block = &mut self.basic_blocks[location.block];
547         debug_assert!(location.statement_index < block.statements.len());
548         block.statements[location.statement_index].make_nop()
549     }
550
551     /// Returns the source info associated with `location`.
552     pub fn source_info(&self, location: Location) -> &SourceInfo {
553         let block = &self[location.block];
554         let stmts = &block.statements;
555         let idx = location.statement_index;
556         if idx < stmts.len() {
557             &stmts[idx].source_info
558         } else {
559             assert_eq!(idx, stmts.len());
560             &block.terminator().source_info
561         }
562     }
563
564     /// Returns the return type; it always return first element from `local_decls` array.
565     #[inline]
566     pub fn return_ty(&self) -> Ty<'tcx> {
567         self.local_decls[RETURN_PLACE].ty
568     }
569
570     /// Gets the location of the terminator for the given block.
571     #[inline]
572     pub fn terminator_loc(&self, bb: BasicBlock) -> Location {
573         Location { block: bb, statement_index: self[bb].statements.len() }
574     }
575
576     pub fn stmt_at(&self, location: Location) -> Either<&Statement<'tcx>, &Terminator<'tcx>> {
577         let Location { block, statement_index } = location;
578         let block_data = &self.basic_blocks[block];
579         block_data
580             .statements
581             .get(statement_index)
582             .map(Either::Left)
583             .unwrap_or_else(|| Either::Right(block_data.terminator()))
584     }
585
586     #[inline]
587     pub fn predecessors(&self) -> &Predecessors {
588         self.predecessor_cache.compute(&self.basic_blocks)
589     }
590
591     /// `body.switch_sources()[&(target, switch)]` returns a list of switch
592     /// values that lead to a `target` block from a `switch` block.
593     #[inline]
594     pub fn switch_sources(&self) -> &SwitchSources {
595         self.switch_source_cache.compute(&self.basic_blocks)
596     }
597
598     #[inline]
599     pub fn dominators(&self) -> Dominators<BasicBlock> {
600         dominators(self)
601     }
602
603     #[inline]
604     pub fn yield_ty(&self) -> Option<Ty<'tcx>> {
605         self.generator.as_ref().and_then(|generator| generator.yield_ty)
606     }
607
608     #[inline]
609     pub fn generator_layout(&self) -> Option<&GeneratorLayout<'tcx>> {
610         self.generator.as_ref().and_then(|generator| generator.generator_layout.as_ref())
611     }
612
613     #[inline]
614     pub fn generator_drop(&self) -> Option<&Body<'tcx>> {
615         self.generator.as_ref().and_then(|generator| generator.generator_drop.as_ref())
616     }
617
618     #[inline]
619     pub fn generator_kind(&self) -> Option<GeneratorKind> {
620         self.generator.as_ref().map(|generator| generator.generator_kind)
621     }
622 }
623
624 #[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
625 pub enum Safety {
626     Safe,
627     /// Unsafe because of compiler-generated unsafe code, like `await` desugaring
628     BuiltinUnsafe,
629     /// Unsafe because of an unsafe fn
630     FnUnsafe,
631     /// Unsafe because of an `unsafe` block
632     ExplicitUnsafe(hir::HirId),
633 }
634
635 impl<'tcx> Index<BasicBlock> for Body<'tcx> {
636     type Output = BasicBlockData<'tcx>;
637
638     #[inline]
639     fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> {
640         &self.basic_blocks()[index]
641     }
642 }
643
644 impl<'tcx> IndexMut<BasicBlock> for Body<'tcx> {
645     #[inline]
646     fn index_mut(&mut self, index: BasicBlock) -> &mut BasicBlockData<'tcx> {
647         &mut self.basic_blocks_mut()[index]
648     }
649 }
650
651 #[derive(Copy, Clone, Debug, HashStable, TypeFoldable)]
652 pub enum ClearCrossCrate<T> {
653     Clear,
654     Set(T),
655 }
656
657 impl<T> ClearCrossCrate<T> {
658     pub fn as_ref(&self) -> ClearCrossCrate<&T> {
659         match self {
660             ClearCrossCrate::Clear => ClearCrossCrate::Clear,
661             ClearCrossCrate::Set(v) => ClearCrossCrate::Set(v),
662         }
663     }
664
665     pub fn assert_crate_local(self) -> T {
666         match self {
667             ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"),
668             ClearCrossCrate::Set(v) => v,
669         }
670     }
671 }
672
673 const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
674 const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
675
676 impl<E: TyEncoder, T: Encodable<E>> Encodable<E> for ClearCrossCrate<T> {
677     #[inline]
678     fn encode(&self, e: &mut E) {
679         if E::CLEAR_CROSS_CRATE {
680             return;
681         }
682
683         match *self {
684             ClearCrossCrate::Clear => TAG_CLEAR_CROSS_CRATE_CLEAR.encode(e),
685             ClearCrossCrate::Set(ref val) => {
686                 TAG_CLEAR_CROSS_CRATE_SET.encode(e);
687                 val.encode(e);
688             }
689         }
690     }
691 }
692 impl<D: TyDecoder, T: Decodable<D>> Decodable<D> for ClearCrossCrate<T> {
693     #[inline]
694     fn decode(d: &mut D) -> ClearCrossCrate<T> {
695         if D::CLEAR_CROSS_CRATE {
696             return ClearCrossCrate::Clear;
697         }
698
699         let discr = u8::decode(d);
700
701         match discr {
702             TAG_CLEAR_CROSS_CRATE_CLEAR => ClearCrossCrate::Clear,
703             TAG_CLEAR_CROSS_CRATE_SET => {
704                 let val = T::decode(d);
705                 ClearCrossCrate::Set(val)
706             }
707             tag => panic!("Invalid tag for ClearCrossCrate: {:?}", tag),
708         }
709     }
710 }
711
712 /// Grouped information about the source code origin of a MIR entity.
713 /// Intended to be inspected by diagnostics and debuginfo.
714 /// Most passes can work with it as a whole, within a single function.
715 // The unofficial Cranelift backend, at least as of #65828, needs `SourceInfo` to implement `Eq` and
716 // `Hash`. Please ping @bjorn3 if removing them.
717 #[derive(Copy, Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
718 pub struct SourceInfo {
719     /// The source span for the AST pertaining to this MIR entity.
720     pub span: Span,
721
722     /// The source scope, keeping track of which bindings can be
723     /// seen by debuginfo, active lint levels, `unsafe {...}`, etc.
724     pub scope: SourceScope,
725 }
726
727 impl SourceInfo {
728     #[inline]
729     pub fn outermost(span: Span) -> Self {
730         SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }
731     }
732 }
733
734 ///////////////////////////////////////////////////////////////////////////
735 // Borrow kinds
736
737 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, TyEncodable, TyDecodable)]
738 #[derive(Hash, HashStable)]
739 pub enum BorrowKind {
740     /// Data must be immutable and is aliasable.
741     Shared,
742
743     /// The immediately borrowed place must be immutable, but projections from
744     /// it don't need to be. For example, a shallow borrow of `a.b` doesn't
745     /// conflict with a mutable borrow of `a.b.c`.
746     ///
747     /// This is used when lowering matches: when matching on a place we want to
748     /// ensure that place have the same value from the start of the match until
749     /// an arm is selected. This prevents this code from compiling:
750     /// ```compile_fail,E0510
751     /// let mut x = &Some(0);
752     /// match *x {
753     ///     None => (),
754     ///     Some(_) if { x = &None; false } => (),
755     ///     Some(_) => (),
756     /// }
757     /// ```
758     /// This can't be a shared borrow because mutably borrowing (*x as Some).0
759     /// should not prevent `if let None = x { ... }`, for example, because the
760     /// mutating `(*x as Some).0` can't affect the discriminant of `x`.
761     /// We can also report errors with this kind of borrow differently.
762     Shallow,
763
764     /// Data must be immutable but not aliasable. This kind of borrow
765     /// cannot currently be expressed by the user and is used only in
766     /// implicit closure bindings. It is needed when the closure is
767     /// borrowing or mutating a mutable referent, e.g.:
768     /// ```
769     /// let mut z = 3;
770     /// let x: &mut isize = &mut z;
771     /// let y = || *x += 5;
772     /// ```
773     /// If we were to try to translate this closure into a more explicit
774     /// form, we'd encounter an error with the code as written:
775     /// ```compile_fail,E0594
776     /// struct Env<'a> { x: &'a &'a mut isize }
777     /// let mut z = 3;
778     /// let x: &mut isize = &mut z;
779     /// let y = (&mut Env { x: &x }, fn_ptr);  // Closure is pair of env and fn
780     /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
781     /// ```
782     /// This is then illegal because you cannot mutate an `&mut` found
783     /// in an aliasable location. To solve, you'd have to translate with
784     /// an `&mut` borrow:
785     /// ```compile_fail,E0596
786     /// struct Env<'a> { x: &'a mut &'a mut isize }
787     /// let mut z = 3;
788     /// let x: &mut isize = &mut z;
789     /// let y = (&mut Env { x: &mut x }, fn_ptr); // changed from &x to &mut x
790     /// fn fn_ptr(env: &mut Env) { **env.x += 5; }
791     /// ```
792     /// Now the assignment to `**env.x` is legal, but creating a
793     /// mutable pointer to `x` is not because `x` is not mutable. We
794     /// could fix this by declaring `x` as `let mut x`. This is ok in
795     /// user code, if awkward, but extra weird for closures, since the
796     /// borrow is hidden.
797     ///
798     /// So we introduce a "unique imm" borrow -- the referent is
799     /// immutable, but not aliasable. This solves the problem. For
800     /// simplicity, we don't give users the way to express this
801     /// borrow, it's just used when translating closures.
802     Unique,
803
804     /// Data is mutable and not aliasable.
805     Mut {
806         /// `true` if this borrow arose from method-call auto-ref
807         /// (i.e., `adjustment::Adjust::Borrow`).
808         allow_two_phase_borrow: bool,
809     },
810 }
811
812 impl BorrowKind {
813     pub fn allows_two_phase_borrow(&self) -> bool {
814         match *self {
815             BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => false,
816             BorrowKind::Mut { allow_two_phase_borrow } => allow_two_phase_borrow,
817         }
818     }
819
820     pub fn describe_mutability(&self) -> String {
821         match *self {
822             BorrowKind::Shared | BorrowKind::Shallow | BorrowKind::Unique => {
823                 "immutable".to_string()
824             }
825             BorrowKind::Mut { .. } => "mutable".to_string(),
826         }
827     }
828 }
829
830 ///////////////////////////////////////////////////////////////////////////
831 // Variables and temps
832
833 rustc_index::newtype_index! {
834     pub struct Local {
835         derive [HashStable]
836         DEBUG_FORMAT = "_{}",
837         const RETURN_PLACE = 0,
838     }
839 }
840
841 impl Atom for Local {
842     fn index(self) -> usize {
843         Idx::index(self)
844     }
845 }
846
847 /// Classifies locals into categories. See `Body::local_kind`.
848 #[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
849 pub enum LocalKind {
850     /// User-declared variable binding.
851     Var,
852     /// Compiler-introduced temporary.
853     Temp,
854     /// Function argument.
855     Arg,
856     /// Location of function's return value.
857     ReturnPointer,
858 }
859
860 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
861 pub struct VarBindingForm<'tcx> {
862     /// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`?
863     pub binding_mode: ty::BindingMode,
864     /// If an explicit type was provided for this variable binding,
865     /// this holds the source Span of that type.
866     ///
867     /// NOTE: if you want to change this to a `HirId`, be wary that
868     /// doing so breaks incremental compilation (as of this writing),
869     /// while a `Span` does not cause our tests to fail.
870     pub opt_ty_info: Option<Span>,
871     /// Place of the RHS of the =, or the subject of the `match` where this
872     /// variable is initialized. None in the case of `let PATTERN;`.
873     /// Some((None, ..)) in the case of and `let [mut] x = ...` because
874     /// (a) the right-hand side isn't evaluated as a place expression.
875     /// (b) it gives a way to separate this case from the remaining cases
876     ///     for diagnostics.
877     pub opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
878     /// The span of the pattern in which this variable was bound.
879     pub pat_span: Span,
880 }
881
882 #[derive(Clone, Debug, TyEncodable, TyDecodable)]
883 pub enum BindingForm<'tcx> {
884     /// This is a binding for a non-`self` binding, or a `self` that has an explicit type.
885     Var(VarBindingForm<'tcx>),
886     /// Binding for a `self`/`&self`/`&mut self` binding where the type is implicit.
887     ImplicitSelf(ImplicitSelfKind),
888     /// Reference used in a guard expression to ensure immutability.
889     RefForGuard,
890 }
891
892 /// Represents what type of implicit self a function has, if any.
893 #[derive(Clone, Copy, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
894 pub enum ImplicitSelfKind {
895     /// Represents a `fn x(self);`.
896     Imm,
897     /// Represents a `fn x(mut self);`.
898     Mut,
899     /// Represents a `fn x(&self);`.
900     ImmRef,
901     /// Represents a `fn x(&mut self);`.
902     MutRef,
903     /// Represents when a function does not have a self argument or
904     /// when a function has a `self: X` argument.
905     None,
906 }
907
908 TrivialTypeFoldableAndLiftImpls! { BindingForm<'tcx>, }
909
910 mod binding_form_impl {
911     use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
912     use rustc_query_system::ich::StableHashingContext;
913
914     impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for super::BindingForm<'tcx> {
915         fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
916             use super::BindingForm::*;
917             std::mem::discriminant(self).hash_stable(hcx, hasher);
918
919             match self {
920                 Var(binding) => binding.hash_stable(hcx, hasher),
921                 ImplicitSelf(kind) => kind.hash_stable(hcx, hasher),
922                 RefForGuard => (),
923             }
924         }
925     }
926 }
927
928 /// `BlockTailInfo` is attached to the `LocalDecl` for temporaries
929 /// created during evaluation of expressions in a block tail
930 /// expression; that is, a block like `{ STMT_1; STMT_2; EXPR }`.
931 ///
932 /// It is used to improve diagnostics when such temporaries are
933 /// involved in borrow_check errors, e.g., explanations of where the
934 /// temporaries come from, when their destructors are run, and/or how
935 /// one might revise the code to satisfy the borrow checker's rules.
936 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
937 pub struct BlockTailInfo {
938     /// If `true`, then the value resulting from evaluating this tail
939     /// expression is ignored by the block's expression context.
940     ///
941     /// Examples include `{ ...; tail };` and `let _ = { ...; tail };`
942     /// but not e.g., `let _x = { ...; tail };`
943     pub tail_result_is_ignored: bool,
944
945     /// `Span` of the tail expression.
946     pub span: Span,
947 }
948
949 /// A MIR local.
950 ///
951 /// This can be a binding declared by the user, a temporary inserted by the compiler, a function
952 /// argument, or the return place.
953 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
954 pub struct LocalDecl<'tcx> {
955     /// Whether this is a mutable binding (i.e., `let x` or `let mut x`).
956     ///
957     /// Temporaries and the return place are always mutable.
958     pub mutability: Mutability,
959
960     // FIXME(matthewjasper) Don't store in this in `Body`
961     pub local_info: Option<Box<LocalInfo<'tcx>>>,
962
963     /// `true` if this is an internal local.
964     ///
965     /// These locals are not based on types in the source code and are only used
966     /// for a few desugarings at the moment.
967     ///
968     /// The generator transformation will sanity check the locals which are live
969     /// across a suspension point against the type components of the generator
970     /// which type checking knows are live across a suspension point. We need to
971     /// flag drop flags to avoid triggering this check as they are introduced
972     /// outside of type inference.
973     ///
974     /// This should be sound because the drop flags are fully algebraic, and
975     /// therefore don't affect the auto-trait or outlives properties of the
976     /// generator.
977     pub internal: bool,
978
979     /// If this local is a temporary and `is_block_tail` is `Some`,
980     /// then it is a temporary created for evaluation of some
981     /// subexpression of some block's tail expression (with no
982     /// intervening statement context).
983     // FIXME(matthewjasper) Don't store in this in `Body`
984     pub is_block_tail: Option<BlockTailInfo>,
985
986     /// The type of this local.
987     pub ty: Ty<'tcx>,
988
989     /// If the user manually ascribed a type to this variable,
990     /// e.g., via `let x: T`, then we carry that type here. The MIR
991     /// borrow checker needs this information since it can affect
992     /// region inference.
993     // FIXME(matthewjasper) Don't store in this in `Body`
994     pub user_ty: Option<Box<UserTypeProjections>>,
995
996     /// The *syntactic* (i.e., not visibility) source scope the local is defined
997     /// in. If the local was defined in a let-statement, this
998     /// is *within* the let-statement, rather than outside
999     /// of it.
1000     ///
1001     /// This is needed because the visibility source scope of locals within
1002     /// a let-statement is weird.
1003     ///
1004     /// The reason is that we want the local to be *within* the let-statement
1005     /// for lint purposes, but we want the local to be *after* the let-statement
1006     /// for names-in-scope purposes.
1007     ///
1008     /// That's it, if we have a let-statement like the one in this
1009     /// function:
1010     ///
1011     /// ```
1012     /// fn foo(x: &str) {
1013     ///     #[allow(unused_mut)]
1014     ///     let mut x: u32 = { // <- one unused mut
1015     ///         let mut y: u32 = x.parse().unwrap();
1016     ///         y + 2
1017     ///     };
1018     ///     drop(x);
1019     /// }
1020     /// ```
1021     ///
1022     /// Then, from a lint point of view, the declaration of `x: u32`
1023     /// (and `y: u32`) are within the `#[allow(unused_mut)]` scope - the
1024     /// lint scopes are the same as the AST/HIR nesting.
1025     ///
1026     /// However, from a name lookup point of view, the scopes look more like
1027     /// as if the let-statements were `match` expressions:
1028     ///
1029     /// ```
1030     /// fn foo(x: &str) {
1031     ///     match {
1032     ///         match x.parse::<u32>().unwrap() {
1033     ///             y => y + 2
1034     ///         }
1035     ///     } {
1036     ///         x => drop(x)
1037     ///     };
1038     /// }
1039     /// ```
1040     ///
1041     /// We care about the name-lookup scopes for debuginfo - if the
1042     /// debuginfo instruction pointer is at the call to `x.parse()`, we
1043     /// want `x` to refer to `x: &str`, but if it is at the call to
1044     /// `drop(x)`, we want it to refer to `x: u32`.
1045     ///
1046     /// To allow both uses to work, we need to have more than a single scope
1047     /// for a local. We have the `source_info.scope` represent the "syntactic"
1048     /// lint scope (with a variable being under its let block) while the
1049     /// `var_debug_info.source_info.scope` represents the "local variable"
1050     /// scope (where the "rest" of a block is under all prior let-statements).
1051     ///
1052     /// The end result looks like this:
1053     ///
1054     /// ```text
1055     /// ROOT SCOPE
1056     ///  │{ argument x: &str }
1057     ///  │
1058     ///  │ │{ #[allow(unused_mut)] } // This is actually split into 2 scopes
1059     ///  │ │                         // in practice because I'm lazy.
1060     ///  │ │
1061     ///  │ │← x.source_info.scope
1062     ///  │ │← `x.parse().unwrap()`
1063     ///  │ │
1064     ///  │ │ │← y.source_info.scope
1065     ///  │ │
1066     ///  │ │ │{ let y: u32 }
1067     ///  │ │ │
1068     ///  │ │ │← y.var_debug_info.source_info.scope
1069     ///  │ │ │← `y + 2`
1070     ///  │
1071     ///  │ │{ let x: u32 }
1072     ///  │ │← x.var_debug_info.source_info.scope
1073     ///  │ │← `drop(x)` // This accesses `x: u32`.
1074     /// ```
1075     pub source_info: SourceInfo,
1076 }
1077
1078 // `LocalDecl` is used a lot. Make sure it doesn't unintentionally get bigger.
1079 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
1080 static_assert_size!(LocalDecl<'_>, 56);
1081
1082 /// Extra information about a some locals that's used for diagnostics and for
1083 /// classifying variables into local variables, statics, etc, which is needed e.g.
1084 /// for unsafety checking.
1085 ///
1086 /// Not used for non-StaticRef temporaries, the return place, or anonymous
1087 /// function parameters.
1088 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
1089 pub enum LocalInfo<'tcx> {
1090     /// A user-defined local variable or function parameter
1091     ///
1092     /// The `BindingForm` is solely used for local diagnostics when generating
1093     /// warnings/errors when compiling the current crate, and therefore it need
1094     /// not be visible across crates.
1095     User(ClearCrossCrate<BindingForm<'tcx>>),
1096     /// A temporary created that references the static with the given `DefId`.
1097     StaticRef { def_id: DefId, is_thread_local: bool },
1098     /// A temporary created that references the const with the given `DefId`
1099     ConstRef { def_id: DefId },
1100     /// A temporary created during the creation of an aggregate
1101     /// (e.g. a temporary for `foo` in `MyStruct { my_field: foo }`)
1102     AggregateTemp,
1103     /// A temporary created during the pass `Derefer` to avoid it's retagging
1104     DerefTemp,
1105 }
1106
1107 impl<'tcx> LocalDecl<'tcx> {
1108     /// Returns `true` only if local is a binding that can itself be
1109     /// made mutable via the addition of the `mut` keyword, namely
1110     /// something like the occurrences of `x` in:
1111     /// - `fn foo(x: Type) { ... }`,
1112     /// - `let x = ...`,
1113     /// - or `match ... { C(x) => ... }`
1114     pub fn can_be_made_mutable(&self) -> bool {
1115         matches!(
1116             self.local_info,
1117             Some(box LocalInfo::User(ClearCrossCrate::Set(
1118                 BindingForm::Var(VarBindingForm {
1119                     binding_mode: ty::BindingMode::BindByValue(_),
1120                     opt_ty_info: _,
1121                     opt_match_place: _,
1122                     pat_span: _,
1123                 }) | BindingForm::ImplicitSelf(ImplicitSelfKind::Imm),
1124             )))
1125         )
1126     }
1127
1128     /// Returns `true` if local is definitely not a `ref ident` or
1129     /// `ref mut ident` binding. (Such bindings cannot be made into
1130     /// mutable bindings, but the inverse does not necessarily hold).
1131     pub fn is_nonref_binding(&self) -> bool {
1132         matches!(
1133             self.local_info,
1134             Some(box LocalInfo::User(ClearCrossCrate::Set(
1135                 BindingForm::Var(VarBindingForm {
1136                     binding_mode: ty::BindingMode::BindByValue(_),
1137                     opt_ty_info: _,
1138                     opt_match_place: _,
1139                     pat_span: _,
1140                 }) | BindingForm::ImplicitSelf(_),
1141             )))
1142         )
1143     }
1144
1145     /// Returns `true` if this variable is a named variable or function
1146     /// parameter declared by the user.
1147     #[inline]
1148     pub fn is_user_variable(&self) -> bool {
1149         matches!(self.local_info, Some(box LocalInfo::User(_)))
1150     }
1151
1152     /// Returns `true` if this is a reference to a variable bound in a `match`
1153     /// expression that is used to access said variable for the guard of the
1154     /// match arm.
1155     pub fn is_ref_for_guard(&self) -> bool {
1156         matches!(
1157             self.local_info,
1158             Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard)))
1159         )
1160     }
1161
1162     /// Returns `Some` if this is a reference to a static item that is used to
1163     /// access that static.
1164     pub fn is_ref_to_static(&self) -> bool {
1165         matches!(self.local_info, Some(box LocalInfo::StaticRef { .. }))
1166     }
1167
1168     /// Returns `Some` if this is a reference to a thread-local static item that is used to
1169     /// access that static.
1170     pub fn is_ref_to_thread_local(&self) -> bool {
1171         match self.local_info {
1172             Some(box LocalInfo::StaticRef { is_thread_local, .. }) => is_thread_local,
1173             _ => false,
1174         }
1175     }
1176
1177     /// Returns `true` is the local is from a compiler desugaring, e.g.,
1178     /// `__next` from a `for` loop.
1179     #[inline]
1180     pub fn from_compiler_desugaring(&self) -> bool {
1181         self.source_info.span.desugaring_kind().is_some()
1182     }
1183
1184     /// Creates a new `LocalDecl` for a temporary: mutable, non-internal.
1185     #[inline]
1186     pub fn new(ty: Ty<'tcx>, span: Span) -> Self {
1187         Self::with_source_info(ty, SourceInfo::outermost(span))
1188     }
1189
1190     /// Like `LocalDecl::new`, but takes a `SourceInfo` instead of a `Span`.
1191     #[inline]
1192     pub fn with_source_info(ty: Ty<'tcx>, source_info: SourceInfo) -> Self {
1193         LocalDecl {
1194             mutability: Mutability::Mut,
1195             local_info: None,
1196             internal: false,
1197             is_block_tail: None,
1198             ty,
1199             user_ty: None,
1200             source_info,
1201         }
1202     }
1203
1204     /// Converts `self` into same `LocalDecl` except tagged as internal.
1205     #[inline]
1206     pub fn internal(mut self) -> Self {
1207         self.internal = true;
1208         self
1209     }
1210
1211     /// Converts `self` into same `LocalDecl` except tagged as immutable.
1212     #[inline]
1213     pub fn immutable(mut self) -> Self {
1214         self.mutability = Mutability::Not;
1215         self
1216     }
1217
1218     /// Converts `self` into same `LocalDecl` except tagged as internal temporary.
1219     #[inline]
1220     pub fn block_tail(mut self, info: BlockTailInfo) -> Self {
1221         assert!(self.is_block_tail.is_none());
1222         self.is_block_tail = Some(info);
1223         self
1224     }
1225 }
1226
1227 #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
1228 pub enum VarDebugInfoContents<'tcx> {
1229     /// NOTE(eddyb) There's an unenforced invariant that this `Place` is
1230     /// based on a `Local`, not a `Static`, and contains no indexing.
1231     Place(Place<'tcx>),
1232     Const(Constant<'tcx>),
1233 }
1234
1235 impl<'tcx> Debug for VarDebugInfoContents<'tcx> {
1236     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
1237         match self {
1238             VarDebugInfoContents::Const(c) => write!(fmt, "{}", c),
1239             VarDebugInfoContents::Place(p) => write!(fmt, "{:?}", p),
1240         }
1241     }
1242 }
1243
1244 /// Debug information pertaining to a user variable.
1245 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
1246 pub struct VarDebugInfo<'tcx> {
1247     pub name: Symbol,
1248
1249     /// Source info of the user variable, including the scope
1250     /// within which the variable is visible (to debuginfo)
1251     /// (see `LocalDecl`'s `source_info` field for more details).
1252     pub source_info: SourceInfo,
1253
1254     /// Where the data for this user variable is to be found.
1255     pub value: VarDebugInfoContents<'tcx>,
1256 }
1257
1258 ///////////////////////////////////////////////////////////////////////////
1259 // BasicBlock
1260
1261 rustc_index::newtype_index! {
1262     /// A node in the MIR [control-flow graph][CFG].
1263     ///
1264     /// There are no branches (e.g., `if`s, function calls, etc.) within a basic block, which makes
1265     /// it easier to do [data-flow analyses] and optimizations. Instead, branches are represented
1266     /// as an edge in a graph between basic blocks.
1267     ///
1268     /// Basic blocks consist of a series of [statements][Statement], ending with a
1269     /// [terminator][Terminator]. Basic blocks can have multiple predecessors and successors,
1270     /// however there is a MIR pass ([`CriticalCallEdges`]) that removes *critical edges*, which
1271     /// are edges that go from a multi-successor node to a multi-predecessor node. This pass is
1272     /// needed because some analyses require that there are no critical edges in the CFG.
1273     ///
1274     /// Note that this type is just an index into [`Body.basic_blocks`](Body::basic_blocks);
1275     /// the actual data that a basic block holds is in [`BasicBlockData`].
1276     ///
1277     /// Read more about basic blocks in the [rustc-dev-guide][guide-mir].
1278     ///
1279     /// [CFG]: https://rustc-dev-guide.rust-lang.org/appendix/background.html#cfg
1280     /// [data-flow analyses]:
1281     ///     https://rustc-dev-guide.rust-lang.org/appendix/background.html#what-is-a-dataflow-analysis
1282     /// [`CriticalCallEdges`]: ../../rustc_const_eval/transform/add_call_guards/enum.AddCallGuards.html#variant.CriticalCallEdges
1283     /// [guide-mir]: https://rustc-dev-guide.rust-lang.org/mir/
1284     pub struct BasicBlock {
1285         derive [HashStable]
1286         DEBUG_FORMAT = "bb{}",
1287         const START_BLOCK = 0,
1288     }
1289 }
1290
1291 impl BasicBlock {
1292     pub fn start_location(self) -> Location {
1293         Location { block: self, statement_index: 0 }
1294     }
1295 }
1296
1297 ///////////////////////////////////////////////////////////////////////////
1298 // BasicBlockData and Terminator
1299
1300 /// See [`BasicBlock`] for documentation on what basic blocks are at a high level.
1301 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
1302 pub struct BasicBlockData<'tcx> {
1303     /// List of statements in this block.
1304     pub statements: Vec<Statement<'tcx>>,
1305
1306     /// Terminator for this block.
1307     ///
1308     /// N.B., this should generally ONLY be `None` during construction.
1309     /// Therefore, you should generally access it via the
1310     /// `terminator()` or `terminator_mut()` methods. The only
1311     /// exception is that certain passes, such as `simplify_cfg`, swap
1312     /// out the terminator temporarily with `None` while they continue
1313     /// to recurse over the set of basic blocks.
1314     pub terminator: Option<Terminator<'tcx>>,
1315
1316     /// If true, this block lies on an unwind path. This is used
1317     /// during codegen where distinct kinds of basic blocks may be
1318     /// generated (particularly for MSVC cleanup). Unwind blocks must
1319     /// only branch to other unwind blocks.
1320     pub is_cleanup: bool,
1321 }
1322
1323 /// Information about an assertion failure.
1324 #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, PartialOrd)]
1325 pub enum AssertKind<O> {
1326     BoundsCheck { len: O, index: O },
1327     Overflow(BinOp, O, O),
1328     OverflowNeg(O),
1329     DivisionByZero(O),
1330     RemainderByZero(O),
1331     ResumedAfterReturn(GeneratorKind),
1332     ResumedAfterPanic(GeneratorKind),
1333 }
1334
1335 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
1336 pub enum InlineAsmOperand<'tcx> {
1337     In {
1338         reg: InlineAsmRegOrRegClass,
1339         value: Operand<'tcx>,
1340     },
1341     Out {
1342         reg: InlineAsmRegOrRegClass,
1343         late: bool,
1344         place: Option<Place<'tcx>>,
1345     },
1346     InOut {
1347         reg: InlineAsmRegOrRegClass,
1348         late: bool,
1349         in_value: Operand<'tcx>,
1350         out_place: Option<Place<'tcx>>,
1351     },
1352     Const {
1353         value: Box<Constant<'tcx>>,
1354     },
1355     SymFn {
1356         value: Box<Constant<'tcx>>,
1357     },
1358     SymStatic {
1359         def_id: DefId,
1360     },
1361 }
1362
1363 /// Type for MIR `Assert` terminator error messages.
1364 pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
1365
1366 pub type Successors<'a> = impl Iterator<Item = BasicBlock> + 'a;
1367 pub type SuccessorsMut<'a> =
1368     iter::Chain<option::IntoIter<&'a mut BasicBlock>, slice::IterMut<'a, BasicBlock>>;
1369
1370 impl<'tcx> BasicBlockData<'tcx> {
1371     pub fn new(terminator: Option<Terminator<'tcx>>) -> BasicBlockData<'tcx> {
1372         BasicBlockData { statements: vec![], terminator, is_cleanup: false }
1373     }
1374
1375     /// Accessor for terminator.
1376     ///
1377     /// Terminator may not be None after construction of the basic block is complete. This accessor
1378     /// provides a convenience way to reach the terminator.
1379     #[inline]
1380     pub fn terminator(&self) -> &Terminator<'tcx> {
1381         self.terminator.as_ref().expect("invalid terminator state")
1382     }
1383
1384     #[inline]
1385     pub fn terminator_mut(&mut self) -> &mut Terminator<'tcx> {
1386         self.terminator.as_mut().expect("invalid terminator state")
1387     }
1388
1389     pub fn retain_statements<F>(&mut self, mut f: F)
1390     where
1391         F: FnMut(&mut Statement<'_>) -> bool,
1392     {
1393         for s in &mut self.statements {
1394             if !f(s) {
1395                 s.make_nop();
1396             }
1397         }
1398     }
1399
1400     pub fn expand_statements<F, I>(&mut self, mut f: F)
1401     where
1402         F: FnMut(&mut Statement<'tcx>) -> Option<I>,
1403         I: iter::TrustedLen<Item = Statement<'tcx>>,
1404     {
1405         // Gather all the iterators we'll need to splice in, and their positions.
1406         let mut splices: Vec<(usize, I)> = vec![];
1407         let mut extra_stmts = 0;
1408         for (i, s) in self.statements.iter_mut().enumerate() {
1409             if let Some(mut new_stmts) = f(s) {
1410                 if let Some(first) = new_stmts.next() {
1411                     // We can already store the first new statement.
1412                     *s = first;
1413
1414                     // Save the other statements for optimized splicing.
1415                     let remaining = new_stmts.size_hint().0;
1416                     if remaining > 0 {
1417                         splices.push((i + 1 + extra_stmts, new_stmts));
1418                         extra_stmts += remaining;
1419                     }
1420                 } else {
1421                     s.make_nop();
1422                 }
1423             }
1424         }
1425
1426         // Splice in the new statements, from the end of the block.
1427         // FIXME(eddyb) This could be more efficient with a "gap buffer"
1428         // where a range of elements ("gap") is left uninitialized, with
1429         // splicing adding new elements to the end of that gap and moving
1430         // existing elements from before the gap to the end of the gap.
1431         // For now, this is safe code, emulating a gap but initializing it.
1432         let mut gap = self.statements.len()..self.statements.len() + extra_stmts;
1433         self.statements.resize(
1434             gap.end,
1435             Statement { source_info: SourceInfo::outermost(DUMMY_SP), kind: StatementKind::Nop },
1436         );
1437         for (splice_start, new_stmts) in splices.into_iter().rev() {
1438             let splice_end = splice_start + new_stmts.size_hint().0;
1439             while gap.end > splice_end {
1440                 gap.start -= 1;
1441                 gap.end -= 1;
1442                 self.statements.swap(gap.start, gap.end);
1443             }
1444             self.statements.splice(splice_start..splice_end, new_stmts);
1445             gap.end = splice_start;
1446         }
1447     }
1448
1449     pub fn visitable(&self, index: usize) -> &dyn MirVisitable<'tcx> {
1450         if index < self.statements.len() { &self.statements[index] } else { &self.terminator }
1451     }
1452 }
1453
1454 impl<O> AssertKind<O> {
1455     /// Getting a description does not require `O` to be printable, and does not
1456     /// require allocation.
1457     /// The caller is expected to handle `BoundsCheck` separately.
1458     pub fn description(&self) -> &'static str {
1459         use AssertKind::*;
1460         match self {
1461             Overflow(BinOp::Add, _, _) => "attempt to add with overflow",
1462             Overflow(BinOp::Sub, _, _) => "attempt to subtract with overflow",
1463             Overflow(BinOp::Mul, _, _) => "attempt to multiply with overflow",
1464             Overflow(BinOp::Div, _, _) => "attempt to divide with overflow",
1465             Overflow(BinOp::Rem, _, _) => "attempt to calculate the remainder with overflow",
1466             OverflowNeg(_) => "attempt to negate with overflow",
1467             Overflow(BinOp::Shr, _, _) => "attempt to shift right with overflow",
1468             Overflow(BinOp::Shl, _, _) => "attempt to shift left with overflow",
1469             Overflow(op, _, _) => bug!("{:?} cannot overflow", op),
1470             DivisionByZero(_) => "attempt to divide by zero",
1471             RemainderByZero(_) => "attempt to calculate the remainder with a divisor of zero",
1472             ResumedAfterReturn(GeneratorKind::Gen) => "generator resumed after completion",
1473             ResumedAfterReturn(GeneratorKind::Async(_)) => "`async fn` resumed after completion",
1474             ResumedAfterPanic(GeneratorKind::Gen) => "generator resumed after panicking",
1475             ResumedAfterPanic(GeneratorKind::Async(_)) => "`async fn` resumed after panicking",
1476             BoundsCheck { .. } => bug!("Unexpected AssertKind"),
1477         }
1478     }
1479
1480     /// Format the message arguments for the `assert(cond, msg..)` terminator in MIR printing.
1481     pub fn fmt_assert_args<W: Write>(&self, f: &mut W) -> fmt::Result
1482     where
1483         O: Debug,
1484     {
1485         use AssertKind::*;
1486         match self {
1487             BoundsCheck { ref len, ref index } => write!(
1488                 f,
1489                 "\"index out of bounds: the length is {{}} but the index is {{}}\", {:?}, {:?}",
1490                 len, index
1491             ),
1492
1493             OverflowNeg(op) => {
1494                 write!(f, "\"attempt to negate `{{}}`, which would overflow\", {:?}", op)
1495             }
1496             DivisionByZero(op) => write!(f, "\"attempt to divide `{{}}` by zero\", {:?}", op),
1497             RemainderByZero(op) => write!(
1498                 f,
1499                 "\"attempt to calculate the remainder of `{{}}` with a divisor of zero\", {:?}",
1500                 op
1501             ),
1502             Overflow(BinOp::Add, l, r) => write!(
1503                 f,
1504                 "\"attempt to compute `{{}} + {{}}`, which would overflow\", {:?}, {:?}",
1505                 l, r
1506             ),
1507             Overflow(BinOp::Sub, l, r) => write!(
1508                 f,
1509                 "\"attempt to compute `{{}} - {{}}`, which would overflow\", {:?}, {:?}",
1510                 l, r
1511             ),
1512             Overflow(BinOp::Mul, l, r) => write!(
1513                 f,
1514                 "\"attempt to compute `{{}} * {{}}`, which would overflow\", {:?}, {:?}",
1515                 l, r
1516             ),
1517             Overflow(BinOp::Div, l, r) => write!(
1518                 f,
1519                 "\"attempt to compute `{{}} / {{}}`, which would overflow\", {:?}, {:?}",
1520                 l, r
1521             ),
1522             Overflow(BinOp::Rem, l, r) => write!(
1523                 f,
1524                 "\"attempt to compute the remainder of `{{}} % {{}}`, which would overflow\", {:?}, {:?}",
1525                 l, r
1526             ),
1527             Overflow(BinOp::Shr, _, r) => {
1528                 write!(f, "\"attempt to shift right by `{{}}`, which would overflow\", {:?}", r)
1529             }
1530             Overflow(BinOp::Shl, _, r) => {
1531                 write!(f, "\"attempt to shift left by `{{}}`, which would overflow\", {:?}", r)
1532             }
1533             _ => write!(f, "\"{}\"", self.description()),
1534         }
1535     }
1536 }
1537
1538 impl<O: fmt::Debug> fmt::Debug for AssertKind<O> {
1539     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1540         use AssertKind::*;
1541         match self {
1542             BoundsCheck { ref len, ref index } => write!(
1543                 f,
1544                 "index out of bounds: the length is {:?} but the index is {:?}",
1545                 len, index
1546             ),
1547             OverflowNeg(op) => write!(f, "attempt to negate `{:#?}`, which would overflow", op),
1548             DivisionByZero(op) => write!(f, "attempt to divide `{:#?}` by zero", op),
1549             RemainderByZero(op) => write!(
1550                 f,
1551                 "attempt to calculate the remainder of `{:#?}` with a divisor of zero",
1552                 op
1553             ),
1554             Overflow(BinOp::Add, l, r) => {
1555                 write!(f, "attempt to compute `{:#?} + {:#?}`, which would overflow", l, r)
1556             }
1557             Overflow(BinOp::Sub, l, r) => {
1558                 write!(f, "attempt to compute `{:#?} - {:#?}`, which would overflow", l, r)
1559             }
1560             Overflow(BinOp::Mul, l, r) => {
1561                 write!(f, "attempt to compute `{:#?} * {:#?}`, which would overflow", l, r)
1562             }
1563             Overflow(BinOp::Div, l, r) => {
1564                 write!(f, "attempt to compute `{:#?} / {:#?}`, which would overflow", l, r)
1565             }
1566             Overflow(BinOp::Rem, l, r) => write!(
1567                 f,
1568                 "attempt to compute the remainder of `{:#?} % {:#?}`, which would overflow",
1569                 l, r
1570             ),
1571             Overflow(BinOp::Shr, _, r) => {
1572                 write!(f, "attempt to shift right by `{:#?}`, which would overflow", r)
1573             }
1574             Overflow(BinOp::Shl, _, r) => {
1575                 write!(f, "attempt to shift left by `{:#?}`, which would overflow", r)
1576             }
1577             _ => write!(f, "{}", self.description()),
1578         }
1579     }
1580 }
1581
1582 ///////////////////////////////////////////////////////////////////////////
1583 // Statements
1584
1585 #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
1586 pub struct Statement<'tcx> {
1587     pub source_info: SourceInfo,
1588     pub kind: StatementKind<'tcx>,
1589 }
1590
1591 // `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
1592 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
1593 static_assert_size!(Statement<'_>, 32);
1594
1595 impl Statement<'_> {
1596     /// Changes a statement to a nop. This is both faster than deleting instructions and avoids
1597     /// invalidating statement indices in `Location`s.
1598     pub fn make_nop(&mut self) {
1599         self.kind = StatementKind::Nop
1600     }
1601
1602     /// Changes a statement to a nop and returns the original statement.
1603     #[must_use = "If you don't need the statement, use `make_nop` instead"]
1604     pub fn replace_nop(&mut self) -> Self {
1605         Statement {
1606             source_info: self.source_info,
1607             kind: mem::replace(&mut self.kind, StatementKind::Nop),
1608         }
1609     }
1610 }
1611
1612 /// The various kinds of statements that can appear in MIR.
1613 ///
1614 /// Not all of these are allowed at every [`MirPhase`]. Check the documentation there to see which
1615 /// ones you do not have to worry about. The MIR validator will generally enforce such restrictions,
1616 /// causing an ICE if they are violated.
1617 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
1618 pub enum StatementKind<'tcx> {
1619     /// Assign statements roughly correspond to an assignment in Rust proper (`x = ...`) except
1620     /// without the possibility of dropping the previous value (that must be done separately, if at
1621     /// all). The *exact* way this works is undecided. It probably does something like evaluating
1622     /// the LHS to a place and the RHS to a value, and then storing the value to the place. Various
1623     /// parts of this may do type specific things that are more complicated than simply copying
1624     /// bytes.
1625     ///
1626     /// **Needs clarification**: The implication of the above idea would be that assignment implies
1627     /// that the resulting value is initialized. I believe we could commit to this separately from
1628     /// committing to whatever part of the memory model we would need to decide on to make the above
1629     /// paragragh precise. Do we want to?
1630     ///
1631     /// Assignments in which the types of the place and rvalue differ are not well-formed.
1632     ///
1633     /// **Needs clarification**: Do we ever want to worry about non-free (in the body) lifetimes for
1634     /// the typing requirement in post drop-elaboration MIR? I think probably not - I'm not sure we
1635     /// could meaningfully require this anyway. How about free lifetimes? Is ignoring this
1636     /// interesting for optimizations? Do we want to allow such optimizations?
1637     ///
1638     /// **Needs clarification**: We currently require that the LHS place not overlap with any place
1639     /// read as part of computation of the RHS for some rvalues (generally those not producing
1640     /// primitives). This requirement is under discussion in [#68364]. As a part of this discussion,
1641     /// it is also unclear in what order the components are evaluated.
1642     ///
1643     /// [#68364]: https://github.com/rust-lang/rust/issues/68364
1644     ///
1645     /// See [`Rvalue`] documentation for details on each of those.
1646     Assign(Box<(Place<'tcx>, Rvalue<'tcx>)>),
1647
1648     /// This represents all the reading that a pattern match may do (e.g., inspecting constants and
1649     /// discriminant values), and the kind of pattern it comes from. This is in order to adapt
1650     /// potential error messages to these specific patterns.
1651     ///
1652     /// Note that this also is emitted for regular `let` bindings to ensure that locals that are
1653     /// never accessed still get some sanity checks for, e.g., `let x: ! = ..;`
1654     ///
1655     /// When executed at runtime this is a nop.
1656     ///
1657     /// Disallowed after drop elaboration.
1658     FakeRead(Box<(FakeReadCause, Place<'tcx>)>),
1659
1660     /// Write the discriminant for a variant to the enum Place.
1661     ///
1662     /// This is permitted for both generators and ADTs. This does not necessarily write to the
1663     /// entire place; instead, it writes to the minimum set of bytes as required by the layout for
1664     /// the type.
1665     SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
1666
1667     /// Deinitializes the place.
1668     ///
1669     /// This writes `uninit` bytes to the entire place.
1670     Deinit(Box<Place<'tcx>>),
1671
1672     /// `StorageLive` and `StorageDead` statements mark the live range of a local.
1673     ///
1674     /// Using a local before a `StorageLive` or after a `StorageDead` is not well-formed. These
1675     /// statements are not required. If the entire MIR body contains no `StorageLive`/`StorageDead`
1676     /// statements for a particular local, the local is always considered live.
1677     ///
1678     /// More precisely, the MIR validator currently does a `MaybeStorageLiveLocals` analysis to
1679     /// check validity of each use of a local. I believe this is equivalent to requiring for every
1680     /// use of a local, there exist at least one path from the root to that use that contains a
1681     /// `StorageLive` more recently than a `StorageDead`.
1682     ///
1683     /// **Needs clarification**: Is it permitted to have two `StorageLive`s without an intervening
1684     /// `StorageDead`? Two `StorageDead`s without an intervening `StorageLive`? LLVM says poison,
1685     /// yes. If the answer to any of these is "no," is breaking that rule UB or is it an error to
1686     /// have a path in the CFG that might do this?
1687     StorageLive(Local),
1688
1689     /// See `StorageLive` above.
1690     StorageDead(Local),
1691
1692     /// Retag references in the given place, ensuring they got fresh tags.
1693     ///
1694     /// This is part of the Stacked Borrows model. These statements are currently only interpreted
1695     /// by miri and only generated when `-Z mir-emit-retag` is passed. See
1696     /// <https://internals.rust-lang.org/t/stacked-borrows-an-aliasing-model-for-rust/8153/> for
1697     /// more details.
1698     ///
1699     /// For code that is not specific to stacked borrows, you should consider retags to read
1700     /// and modify the place in an opaque way.
1701     Retag(RetagKind, Box<Place<'tcx>>),
1702
1703     /// Encodes a user's type ascription. These need to be preserved
1704     /// intact so that NLL can respect them. For example:
1705     /// ```ignore (illustrative)
1706     /// let a: T = y;
1707     /// ```
1708     /// The effect of this annotation is to relate the type `T_y` of the place `y`
1709     /// to the user-given type `T`. The effect depends on the specified variance:
1710     ///
1711     /// - `Covariant` -- requires that `T_y <: T`
1712     /// - `Contravariant` -- requires that `T_y :> T`
1713     /// - `Invariant` -- requires that `T_y == T`
1714     /// - `Bivariant` -- no effect
1715     ///
1716     /// When executed at runtime this is a nop.
1717     ///
1718     /// Disallowed after drop elaboration.
1719     AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>, ty::Variance),
1720
1721     /// Marks the start of a "coverage region", injected with '-Cinstrument-coverage'. A
1722     /// `Coverage` statement carries metadata about the coverage region, used to inject a coverage
1723     /// map into the binary. If `Coverage::kind` is a `Counter`, the statement also generates
1724     /// executable code, to increment a counter variable at runtime, each time the code region is
1725     /// executed.
1726     Coverage(Box<Coverage>),
1727
1728     /// Denotes a call to the intrinsic function `copy_nonoverlapping`.
1729     ///
1730     /// First, all three operands are evaluated. `src` and `dest` must each be a reference, pointer,
1731     /// or `Box` pointing to the same type `T`. `count` must evaluate to a `usize`. Then, `src` and
1732     /// `dest` are dereferenced, and `count * size_of::<T>()` bytes beginning with the first byte of
1733     /// the `src` place are copied to the continguous range of bytes beginning with the first byte
1734     /// of `dest`.
1735     ///
1736     /// **Needs clarification**: In what order are operands computed and dereferenced? It should
1737     /// probably match the order for assignment, but that is also undecided.
1738     ///
1739     /// **Needs clarification**: Is this typed or not, ie is there a typed load and store involved?
1740     /// I vaguely remember Ralf saying somewhere that he thought it should not be.
1741     CopyNonOverlapping(Box<CopyNonOverlapping<'tcx>>),
1742
1743     /// No-op. Useful for deleting instructions without affecting statement indices.
1744     Nop,
1745 }
1746
1747 impl<'tcx> StatementKind<'tcx> {
1748     pub fn as_assign_mut(&mut self) -> Option<&mut (Place<'tcx>, Rvalue<'tcx>)> {
1749         match self {
1750             StatementKind::Assign(x) => Some(x),
1751             _ => None,
1752         }
1753     }
1754
1755     pub fn as_assign(&self) -> Option<&(Place<'tcx>, Rvalue<'tcx>)> {
1756         match self {
1757             StatementKind::Assign(x) => Some(x),
1758             _ => None,
1759         }
1760     }
1761 }
1762
1763 /// Describes what kind of retag is to be performed.
1764 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, Hash, HashStable)]
1765 pub enum RetagKind {
1766     /// The initial retag when entering a function.
1767     FnEntry,
1768     /// Retag preparing for a two-phase borrow.
1769     TwoPhase,
1770     /// Retagging raw pointers.
1771     Raw,
1772     /// A "normal" retag.
1773     Default,
1774 }
1775
1776 /// The `FakeReadCause` describes the type of pattern why a FakeRead statement exists.
1777 #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, Hash, HashStable, PartialEq)]
1778 pub enum FakeReadCause {
1779     /// Inject a fake read of the borrowed input at the end of each guards
1780     /// code.
1781     ///
1782     /// This should ensure that you cannot change the variant for an enum while
1783     /// you are in the midst of matching on it.
1784     ForMatchGuard,
1785
1786     /// `let x: !; match x {}` doesn't generate any read of x so we need to
1787     /// generate a read of x to check that it is initialized and safe.
1788     ///
1789     /// If a closure pattern matches a Place starting with an Upvar, then we introduce a
1790     /// FakeRead for that Place outside the closure, in such a case this option would be
1791     /// Some(closure_def_id).
1792     /// Otherwise, the value of the optional DefId will be None.
1793     ForMatchedPlace(Option<DefId>),
1794
1795     /// A fake read of the RefWithinGuard version of a bind-by-value variable
1796     /// in a match guard to ensure that its value hasn't change by the time
1797     /// we create the OutsideGuard version.
1798     ForGuardBinding,
1799
1800     /// Officially, the semantics of
1801     ///
1802     /// `let pattern = <expr>;`
1803     ///
1804     /// is that `<expr>` is evaluated into a temporary and then this temporary is
1805     /// into the pattern.
1806     ///
1807     /// However, if we see the simple pattern `let var = <expr>`, we optimize this to
1808     /// evaluate `<expr>` directly into the variable `var`. This is mostly unobservable,
1809     /// but in some cases it can affect the borrow checker, as in #53695.
1810     /// Therefore, we insert a "fake read" here to ensure that we get
1811     /// appropriate errors.
1812     ///
1813     /// If a closure pattern matches a Place starting with an Upvar, then we introduce a
1814     /// FakeRead for that Place outside the closure, in such a case this option would be
1815     /// Some(closure_def_id).
1816     /// Otherwise, the value of the optional DefId will be None.
1817     ForLet(Option<DefId>),
1818
1819     /// If we have an index expression like
1820     ///
1821     /// (*x)[1][{ x = y; 4}]
1822     ///
1823     /// then the first bounds check is invalidated when we evaluate the second
1824     /// index expression. Thus we create a fake borrow of `x` across the second
1825     /// indexer, which will cause a borrow check error.
1826     ForIndex,
1827 }
1828
1829 impl Debug for Statement<'_> {
1830     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
1831         use self::StatementKind::*;
1832         match self.kind {
1833             Assign(box (ref place, ref rv)) => write!(fmt, "{:?} = {:?}", place, rv),
1834             FakeRead(box (ref cause, ref place)) => {
1835                 write!(fmt, "FakeRead({:?}, {:?})", cause, place)
1836             }
1837             Retag(ref kind, ref place) => write!(
1838                 fmt,
1839                 "Retag({}{:?})",
1840                 match kind {
1841                     RetagKind::FnEntry => "[fn entry] ",
1842                     RetagKind::TwoPhase => "[2phase] ",
1843                     RetagKind::Raw => "[raw] ",
1844                     RetagKind::Default => "",
1845                 },
1846                 place,
1847             ),
1848             StorageLive(ref place) => write!(fmt, "StorageLive({:?})", place),
1849             StorageDead(ref place) => write!(fmt, "StorageDead({:?})", place),
1850             SetDiscriminant { ref place, variant_index } => {
1851                 write!(fmt, "discriminant({:?}) = {:?}", place, variant_index)
1852             }
1853             Deinit(ref place) => write!(fmt, "Deinit({:?})", place),
1854             AscribeUserType(box (ref place, ref c_ty), ref variance) => {
1855                 write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
1856             }
1857             Coverage(box self::Coverage { ref kind, code_region: Some(ref rgn) }) => {
1858                 write!(fmt, "Coverage::{:?} for {:?}", kind, rgn)
1859             }
1860             Coverage(box ref coverage) => write!(fmt, "Coverage::{:?}", coverage.kind),
1861             CopyNonOverlapping(box crate::mir::CopyNonOverlapping {
1862                 ref src,
1863                 ref dst,
1864                 ref count,
1865             }) => {
1866                 write!(fmt, "copy_nonoverlapping(src={:?}, dst={:?}, count={:?})", src, dst, count)
1867             }
1868             Nop => write!(fmt, "nop"),
1869         }
1870     }
1871 }
1872
1873 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
1874 pub struct Coverage {
1875     pub kind: CoverageKind,
1876     pub code_region: Option<CodeRegion>,
1877 }
1878
1879 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
1880 pub struct CopyNonOverlapping<'tcx> {
1881     pub src: Operand<'tcx>,
1882     pub dst: Operand<'tcx>,
1883     /// Number of elements to copy from src to dest, not bytes.
1884     pub count: Operand<'tcx>,
1885 }
1886
1887 ///////////////////////////////////////////////////////////////////////////
1888 // Places
1889
1890 /// Places roughly correspond to a "location in memory." Places in MIR are the same mathematical
1891 /// object as places in Rust. This of course means that what exactly they are is undecided and part
1892 /// of the Rust memory model. However, they will likely contain at least the following pieces of
1893 /// information in some form:
1894 ///
1895 ///  1. The address in memory that the place refers to.
1896 ///  2. The provenance with which the place is being accessed.
1897 ///  3. The type of the place and an optional variant index. See [`PlaceTy`][tcx::PlaceTy].
1898 ///  4. Optionally, some metadata. This exists if and only if the type of the place is not `Sized`.
1899 ///
1900 /// We'll give a description below of how all pieces of the place except for the provenance are
1901 /// calculated. We cannot give a description of the provenance, because that is part of the
1902 /// undecided aliasing model - we only include it here at all to acknowledge its existence.
1903 ///
1904 /// Each local naturally corresponds to the place `Place { local, projection: [] }`. This place has
1905 /// the address of the local's allocation and the type of the local.
1906 ///
1907 /// **Needs clarification:** Unsized locals seem to present a bit of an issue. Their allocation
1908 /// can't actually be created on `StorageLive`, because it's unclear how big to make the allocation.
1909 /// Furthermore, MIR produces assignments to unsized locals, although that is not permitted under
1910 /// `#![feature(unsized_locals)]` in Rust. Besides just putting "unsized locals are special and
1911 /// different" in a bunch of places, I (JakobDegen) don't know how to incorporate this behavior into
1912 /// the current MIR semantics in a clean way - possibly this needs some design work first.
1913 ///
1914 /// For places that are not locals, ie they have a non-empty list of projections, we define the
1915 /// values as a function of the parent place, that is the place with its last [`ProjectionElem`]
1916 /// stripped. The way this is computed of course depends on the kind of that last projection
1917 /// element:
1918 ///
1919 ///  - [`Downcast`](ProjectionElem::Downcast): This projection sets the place's variant index to the
1920 ///    given one, and makes no other changes. A `Downcast` projection on a place with its variant
1921 ///    index already set is not well-formed.
1922 ///  - [`Field`](ProjectionElem::Field): `Field` projections take their parent place and create a
1923 ///    place referring to one of the fields of the type. The resulting address is the parent
1924 ///    address, plus the offset of the field. The type becomes the type of the field. If the parent
1925 ///    was unsized and so had metadata associated with it, then the metadata is retained if the
1926 ///    field is unsized and thrown out if it is sized.
1927 ///
1928 ///    These projections are only legal for tuples, ADTs, closures, and generators. If the ADT or
1929 ///    generator has more than one variant, the parent place's variant index must be set, indicating
1930 ///    which variant is being used. If it has just one variant, the variant index may or may not be
1931 ///    included - the single possible variant is inferred if it is not included.
1932 ///  - [`ConstantIndex`](ProjectionElem::ConstantIndex): Computes an offset in units of `T` into the
1933 ///    place as described in the documentation for the `ProjectionElem`. The resulting address is
1934 ///    the parent's address plus that offset, and the type is `T`. This is only legal if the parent
1935 ///    place has type `[T;  N]` or `[T]` (*not* `&[T]`). Since such a `T` is always sized, any
1936 ///    resulting metadata is thrown out.
1937 ///  - [`Subslice`](ProjectionElem::Subslice): This projection calculates an offset and a new
1938 ///    address in a similar manner as `ConstantIndex`. It is also only legal on `[T; N]` and `[T]`.
1939 ///    However, this yields a `Place` of type `[T]`, and additionally sets the metadata to be the
1940 ///    length of the subslice.
1941 ///  - [`Index`](ProjectionElem::Index): Like `ConstantIndex`, only legal on `[T; N]` or `[T]`.
1942 ///    However, `Index` additionally takes a local from which the value of the index is computed at
1943 ///    runtime. Computing the value of the index involves interpreting the `Local` as a
1944 ///    `Place { local, projection: [] }`, and then computing its value as if done via
1945 ///    [`Operand::Copy`]. The array/slice is then indexed with the resulting value. The local must
1946 ///    have type `usize`.
1947 ///  - [`Deref`](ProjectionElem::Deref): Derefs are the last type of projection, and the most
1948 ///    complicated. They are only legal on parent places that are references, pointers, or `Box`. A
1949 ///    `Deref` projection begins by loading a value from the parent place, as if by
1950 ///    [`Operand::Copy`]. It then dereferences the resulting pointer, creating a place of the
1951 ///    pointee's type. The resulting address is the address that was stored in the pointer. If the
1952 ///    pointee type is unsized, the pointer additionally stored the value of the metadata.
1953 ///
1954 /// Computing a place may cause UB. One possibility is that the pointer used for a `Deref` may not
1955 /// be suitably aligned. Another possibility is that the place is not in bounds, meaning it does not
1956 /// point to an actual allocation.
1957 ///
1958 /// However, if this is actually UB and when the UB kicks in is undecided. This is being discussed
1959 /// in [UCG#319]. The options include that every place must obey those rules, that only some places
1960 /// must obey them, or that places impose no rules of their own.
1961 ///
1962 /// [UCG#319]: https://github.com/rust-lang/unsafe-code-guidelines/issues/319
1963 ///
1964 /// Rust currently requires that every place obey those two rules. This is checked by MIRI and taken
1965 /// advantage of by codegen (via `gep inbounds`). That is possibly subject to change.
1966 #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, HashStable)]
1967 pub struct Place<'tcx> {
1968     pub local: Local,
1969
1970     /// projection out of a place (access a field, deref a pointer, etc)
1971     pub projection: &'tcx List<PlaceElem<'tcx>>,
1972 }
1973
1974 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
1975 static_assert_size!(Place<'_>, 16);
1976
1977 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1978 #[derive(TyEncodable, TyDecodable, HashStable)]
1979 pub enum ProjectionElem<V, T> {
1980     Deref,
1981     Field(Field, T),
1982     /// Index into a slice/array.
1983     ///
1984     /// Note that this does not also dereference, and so it does not exactly correspond to slice
1985     /// indexing in Rust. In other words, in the below Rust code:
1986     ///
1987     /// ```rust
1988     /// let x = &[1, 2, 3, 4];
1989     /// let i = 2;
1990     /// x[i];
1991     /// ```
1992     ///
1993     /// The `x[i]` is turned into a `Deref` followed by an `Index`, not just an `Index`. The same
1994     /// thing is true of the `ConstantIndex` and `Subslice` projections below.
1995     Index(V),
1996
1997     /// These indices are generated by slice patterns. Easiest to explain
1998     /// by example:
1999     ///
2000     /// ```ignore (illustrative)
2001     /// [X, _, .._, _, _] => { offset: 0, min_length: 4, from_end: false },
2002     /// [_, X, .._, _, _] => { offset: 1, min_length: 4, from_end: false },
2003     /// [_, _, .._, X, _] => { offset: 2, min_length: 4, from_end: true },
2004     /// [_, _, .._, _, X] => { offset: 1, min_length: 4, from_end: true },
2005     /// ```
2006     ConstantIndex {
2007         /// index or -index (in Python terms), depending on from_end
2008         offset: u64,
2009         /// The thing being indexed must be at least this long. For arrays this
2010         /// is always the exact length.
2011         min_length: u64,
2012         /// Counting backwards from end? This is always false when indexing an
2013         /// array.
2014         from_end: bool,
2015     },
2016
2017     /// These indices are generated by slice patterns.
2018     ///
2019     /// If `from_end` is true `slice[from..slice.len() - to]`.
2020     /// Otherwise `array[from..to]`.
2021     Subslice {
2022         from: u64,
2023         to: u64,
2024         /// Whether `to` counts from the start or end of the array/slice.
2025         /// For `PlaceElem`s this is `true` if and only if the base is a slice.
2026         /// For `ProjectionKind`, this can also be `true` for arrays.
2027         from_end: bool,
2028     },
2029
2030     /// "Downcast" to a variant of an enum or a generator.
2031     ///
2032     /// The included Symbol is the name of the variant, used for printing MIR.
2033     Downcast(Option<Symbol>, VariantIdx),
2034 }
2035
2036 impl<V, T> ProjectionElem<V, T> {
2037     /// Returns `true` if the target of this projection may refer to a different region of memory
2038     /// than the base.
2039     fn is_indirect(&self) -> bool {
2040         match self {
2041             Self::Deref => true,
2042
2043             Self::Field(_, _)
2044             | Self::Index(_)
2045             | Self::ConstantIndex { .. }
2046             | Self::Subslice { .. }
2047             | Self::Downcast(_, _) => false,
2048         }
2049     }
2050
2051     /// Returns `true` if this is a `Downcast` projection with the given `VariantIdx`.
2052     pub fn is_downcast_to(&self, v: VariantIdx) -> bool {
2053         matches!(*self, Self::Downcast(_, x) if x == v)
2054     }
2055
2056     /// Returns `true` if this is a `Field` projection with the given index.
2057     pub fn is_field_to(&self, f: Field) -> bool {
2058         matches!(*self, Self::Field(x, _) if x == f)
2059     }
2060 }
2061
2062 /// Alias for projections as they appear in places, where the base is a place
2063 /// and the index is a local.
2064 pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
2065
2066 // This type is fairly frequently used, so we shouldn't unintentionally increase
2067 // its size.
2068 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
2069 static_assert_size!(PlaceElem<'_>, 24);
2070
2071 /// Alias for projections as they appear in `UserTypeProjection`, where we
2072 /// need neither the `V` parameter for `Index` nor the `T` for `Field`.
2073 pub type ProjectionKind = ProjectionElem<(), ()>;
2074
2075 rustc_index::newtype_index! {
2076     /// A [newtype'd][wrapper] index type in the MIR [control-flow graph][CFG]
2077     ///
2078     /// A field (e.g., `f` in `_1.f`) is one variant of [`ProjectionElem`]. Conceptually,
2079     /// rustc can identify that a field projection refers to either two different regions of memory
2080     /// or the same one between the base and the 'projection element'.
2081     /// Read more about projections in the [rustc-dev-guide][mir-datatypes]
2082     ///
2083     /// [wrapper]: https://rustc-dev-guide.rust-lang.org/appendix/glossary.html#newtype
2084     /// [CFG]: https://rustc-dev-guide.rust-lang.org/appendix/background.html#cfg
2085     /// [mir-datatypes]: https://rustc-dev-guide.rust-lang.org/mir/index.html#mir-data-types
2086     pub struct Field {
2087         derive [HashStable]
2088         DEBUG_FORMAT = "field[{}]"
2089     }
2090 }
2091
2092 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2093 pub struct PlaceRef<'tcx> {
2094     pub local: Local,
2095     pub projection: &'tcx [PlaceElem<'tcx>],
2096 }
2097
2098 // Once we stop implementing `Ord` for `DefId`,
2099 // this impl will be unnecessary. Until then, we'll
2100 // leave this impl in place to prevent re-adding a
2101 // dependnecy on the `Ord` impl for `DefId`
2102 impl<'tcx> !PartialOrd for PlaceRef<'tcx> {}
2103
2104 impl<'tcx> Place<'tcx> {
2105     // FIXME change this to a const fn by also making List::empty a const fn.
2106     pub fn return_place() -> Place<'tcx> {
2107         Place { local: RETURN_PLACE, projection: List::empty() }
2108     }
2109
2110     /// Returns `true` if this `Place` contains a `Deref` projection.
2111     ///
2112     /// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
2113     /// same region of memory as its base.
2114     pub fn is_indirect(&self) -> bool {
2115         self.projection.iter().any(|elem| elem.is_indirect())
2116     }
2117
2118     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
2119     /// a single deref of a local.
2120     #[inline(always)]
2121     pub fn local_or_deref_local(&self) -> Option<Local> {
2122         self.as_ref().local_or_deref_local()
2123     }
2124
2125     /// If this place represents a local variable like `_X` with no
2126     /// projections, return `Some(_X)`.
2127     #[inline(always)]
2128     pub fn as_local(&self) -> Option<Local> {
2129         self.as_ref().as_local()
2130     }
2131
2132     #[inline]
2133     pub fn as_ref(&self) -> PlaceRef<'tcx> {
2134         PlaceRef { local: self.local, projection: &self.projection }
2135     }
2136
2137     /// Iterate over the projections in evaluation order, i.e., the first element is the base with
2138     /// its projection and then subsequently more projections are added.
2139     /// As a concrete example, given the place a.b.c, this would yield:
2140     /// - (a, .b)
2141     /// - (a.b, .c)
2142     ///
2143     /// Given a place without projections, the iterator is empty.
2144     #[inline]
2145     pub fn iter_projections(
2146         self,
2147     ) -> impl Iterator<Item = (PlaceRef<'tcx>, PlaceElem<'tcx>)> + DoubleEndedIterator {
2148         self.projection.iter().enumerate().map(move |(i, proj)| {
2149             let base = PlaceRef { local: self.local, projection: &self.projection[..i] };
2150             (base, proj)
2151         })
2152     }
2153
2154     /// Generates a new place by appending `more_projections` to the existing ones
2155     /// and interning the result.
2156     pub fn project_deeper(self, more_projections: &[PlaceElem<'tcx>], tcx: TyCtxt<'tcx>) -> Self {
2157         if more_projections.is_empty() {
2158             return self;
2159         }
2160
2161         let mut v: Vec<PlaceElem<'tcx>>;
2162
2163         let new_projections = if self.projection.is_empty() {
2164             more_projections
2165         } else {
2166             v = Vec::with_capacity(self.projection.len() + more_projections.len());
2167             v.extend(self.projection);
2168             v.extend(more_projections);
2169             &v
2170         };
2171
2172         Place { local: self.local, projection: tcx.intern_place_elems(new_projections) }
2173     }
2174 }
2175
2176 impl From<Local> for Place<'_> {
2177     fn from(local: Local) -> Self {
2178         Place { local, projection: List::empty() }
2179     }
2180 }
2181
2182 impl<'tcx> PlaceRef<'tcx> {
2183     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
2184     /// a single deref of a local.
2185     pub fn local_or_deref_local(&self) -> Option<Local> {
2186         match *self {
2187             PlaceRef { local, projection: [] }
2188             | PlaceRef { local, projection: [ProjectionElem::Deref] } => Some(local),
2189             _ => None,
2190         }
2191     }
2192
2193     /// If this place represents a local variable like `_X` with no
2194     /// projections, return `Some(_X)`.
2195     #[inline]
2196     pub fn as_local(&self) -> Option<Local> {
2197         match *self {
2198             PlaceRef { local, projection: [] } => Some(local),
2199             _ => None,
2200         }
2201     }
2202
2203     #[inline]
2204     pub fn last_projection(&self) -> Option<(PlaceRef<'tcx>, PlaceElem<'tcx>)> {
2205         if let &[ref proj_base @ .., elem] = self.projection {
2206             Some((PlaceRef { local: self.local, projection: proj_base }, elem))
2207         } else {
2208             None
2209         }
2210     }
2211 }
2212
2213 impl Debug for Place<'_> {
2214     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
2215         for elem in self.projection.iter().rev() {
2216             match elem {
2217                 ProjectionElem::Downcast(_, _) | ProjectionElem::Field(_, _) => {
2218                     write!(fmt, "(").unwrap();
2219                 }
2220                 ProjectionElem::Deref => {
2221                     write!(fmt, "(*").unwrap();
2222                 }
2223                 ProjectionElem::Index(_)
2224                 | ProjectionElem::ConstantIndex { .. }
2225                 | ProjectionElem::Subslice { .. } => {}
2226             }
2227         }
2228
2229         write!(fmt, "{:?}", self.local)?;
2230
2231         for elem in self.projection.iter() {
2232             match elem {
2233                 ProjectionElem::Downcast(Some(name), _index) => {
2234                     write!(fmt, " as {})", name)?;
2235                 }
2236                 ProjectionElem::Downcast(None, index) => {
2237                     write!(fmt, " as variant#{:?})", index)?;
2238                 }
2239                 ProjectionElem::Deref => {
2240                     write!(fmt, ")")?;
2241                 }
2242                 ProjectionElem::Field(field, ty) => {
2243                     write!(fmt, ".{:?}: {:?})", field.index(), ty)?;
2244                 }
2245                 ProjectionElem::Index(ref index) => {
2246                     write!(fmt, "[{:?}]", index)?;
2247                 }
2248                 ProjectionElem::ConstantIndex { offset, min_length, from_end: false } => {
2249                     write!(fmt, "[{:?} of {:?}]", offset, min_length)?;
2250                 }
2251                 ProjectionElem::ConstantIndex { offset, min_length, from_end: true } => {
2252                     write!(fmt, "[-{:?} of {:?}]", offset, min_length)?;
2253                 }
2254                 ProjectionElem::Subslice { from, to, from_end: true } if to == 0 => {
2255                     write!(fmt, "[{:?}:]", from)?;
2256                 }
2257                 ProjectionElem::Subslice { from, to, from_end: true } if from == 0 => {
2258                     write!(fmt, "[:-{:?}]", to)?;
2259                 }
2260                 ProjectionElem::Subslice { from, to, from_end: true } => {
2261                     write!(fmt, "[{:?}:-{:?}]", from, to)?;
2262                 }
2263                 ProjectionElem::Subslice { from, to, from_end: false } => {
2264                     write!(fmt, "[{:?}..{:?}]", from, to)?;
2265                 }
2266             }
2267         }
2268
2269         Ok(())
2270     }
2271 }
2272
2273 ///////////////////////////////////////////////////////////////////////////
2274 // Scopes
2275
2276 rustc_index::newtype_index! {
2277     pub struct SourceScope {
2278         derive [HashStable]
2279         DEBUG_FORMAT = "scope[{}]",
2280         const OUTERMOST_SOURCE_SCOPE = 0,
2281     }
2282 }
2283
2284 impl SourceScope {
2285     /// Finds the original HirId this MIR item came from.
2286     /// This is necessary after MIR optimizations, as otherwise we get a HirId
2287     /// from the function that was inlined instead of the function call site.
2288     pub fn lint_root<'tcx>(
2289         self,
2290         source_scopes: &IndexVec<SourceScope, SourceScopeData<'tcx>>,
2291     ) -> Option<HirId> {
2292         let mut data = &source_scopes[self];
2293         // FIXME(oli-obk): we should be able to just walk the `inlined_parent_scope`, but it
2294         // does not work as I thought it would. Needs more investigation and documentation.
2295         while data.inlined.is_some() {
2296             trace!(?data);
2297             data = &source_scopes[data.parent_scope.unwrap()];
2298         }
2299         trace!(?data);
2300         match &data.local_data {
2301             ClearCrossCrate::Set(data) => Some(data.lint_root),
2302             ClearCrossCrate::Clear => None,
2303         }
2304     }
2305 }
2306
2307 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
2308 pub struct SourceScopeData<'tcx> {
2309     pub span: Span,
2310     pub parent_scope: Option<SourceScope>,
2311
2312     /// Whether this scope is the root of a scope tree of another body,
2313     /// inlined into this body by the MIR inliner.
2314     /// `ty::Instance` is the callee, and the `Span` is the call site.
2315     pub inlined: Option<(ty::Instance<'tcx>, Span)>,
2316
2317     /// Nearest (transitive) parent scope (if any) which is inlined.
2318     /// This is an optimization over walking up `parent_scope`
2319     /// until a scope with `inlined: Some(...)` is found.
2320     pub inlined_parent_scope: Option<SourceScope>,
2321
2322     /// Crate-local information for this source scope, that can't (and
2323     /// needn't) be tracked across crates.
2324     pub local_data: ClearCrossCrate<SourceScopeLocalData>,
2325 }
2326
2327 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
2328 pub struct SourceScopeLocalData {
2329     /// An `HirId` with lint levels equivalent to this scope's lint levels.
2330     pub lint_root: hir::HirId,
2331     /// The unsafe block that contains this node.
2332     pub safety: Safety,
2333 }
2334
2335 ///////////////////////////////////////////////////////////////////////////
2336 // Operands
2337
2338 /// An operand in MIR represents a "value" in Rust, the definition of which is undecided and part of
2339 /// the memory model. One proposal for a definition of values can be found [on UCG][value-def].
2340 ///
2341 /// [value-def]: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/value-domain.md
2342 ///
2343 /// The most common way to create values is via loading a place. Loading a place is an operation
2344 /// which reads the memory of the place and converts it to a value. This is a fundamentally *typed*
2345 /// operation. The nature of the value produced depends on the type of the conversion. Furthermore,
2346 /// there may be other effects: if the type has a validity constraint loading the place might be UB
2347 /// if the validity constraint is not met.
2348 ///
2349 /// **Needs clarification:** Ralf proposes that loading a place not have side-effects.
2350 /// This is what is implemented in miri today. Are these the semantics we want for MIR? Is this
2351 /// something we can even decide without knowing more about Rust's memory model?
2352 ///
2353 /// **Needs clarifiation:** Is loading a place that has its variant index set well-formed? Miri
2354 /// currently implements it, but it seems like this may be something to check against in the
2355 /// validator.
2356 #[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
2357 pub enum Operand<'tcx> {
2358     /// Creates a value by loading the given place.
2359     ///
2360     /// Before drop elaboration, the type of the place must be `Copy`. After drop elaboration there
2361     /// is no such requirement.
2362     Copy(Place<'tcx>),
2363
2364     /// Creates a value by performing loading the place, just like the `Copy` operand.
2365     ///
2366     /// This *may* additionally overwrite the place with `uninit` bytes, depending on how we decide
2367     /// in [UCG#188]. You should not emit MIR that may attempt a subsequent second load of this
2368     /// place without first re-initializing it.
2369     ///
2370     /// [UCG#188]: https://github.com/rust-lang/unsafe-code-guidelines/issues/188
2371     Move(Place<'tcx>),
2372
2373     /// Constants are already semantically values, and remain unchanged.
2374     Constant(Box<Constant<'tcx>>),
2375 }
2376
2377 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
2378 static_assert_size!(Operand<'_>, 24);
2379
2380 impl<'tcx> Debug for Operand<'tcx> {
2381     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
2382         use self::Operand::*;
2383         match *self {
2384             Constant(ref a) => write!(fmt, "{:?}", a),
2385             Copy(ref place) => write!(fmt, "{:?}", place),
2386             Move(ref place) => write!(fmt, "move {:?}", place),
2387         }
2388     }
2389 }
2390
2391 impl<'tcx> Operand<'tcx> {
2392     /// Convenience helper to make a constant that refers to the fn
2393     /// with given `DefId` and substs. Since this is used to synthesize
2394     /// MIR, assumes `user_ty` is None.
2395     pub fn function_handle(
2396         tcx: TyCtxt<'tcx>,
2397         def_id: DefId,
2398         substs: SubstsRef<'tcx>,
2399         span: Span,
2400     ) -> Self {
2401         let ty = tcx.bound_type_of(def_id).subst(tcx, substs);
2402         Operand::Constant(Box::new(Constant {
2403             span,
2404             user_ty: None,
2405             literal: ConstantKind::Val(ConstValue::zst(), ty),
2406         }))
2407     }
2408
2409     pub fn is_move(&self) -> bool {
2410         matches!(self, Operand::Move(..))
2411     }
2412
2413     /// Convenience helper to make a literal-like constant from a given scalar value.
2414     /// Since this is used to synthesize MIR, assumes `user_ty` is None.
2415     pub fn const_from_scalar(
2416         tcx: TyCtxt<'tcx>,
2417         ty: Ty<'tcx>,
2418         val: Scalar,
2419         span: Span,
2420     ) -> Operand<'tcx> {
2421         debug_assert!({
2422             let param_env_and_ty = ty::ParamEnv::empty().and(ty);
2423             let type_size = tcx
2424                 .layout_of(param_env_and_ty)
2425                 .unwrap_or_else(|e| panic!("could not compute layout for {:?}: {:?}", ty, e))
2426                 .size;
2427             let scalar_size = match val {
2428                 Scalar::Int(int) => int.size(),
2429                 _ => panic!("Invalid scalar type {:?}", val),
2430             };
2431             scalar_size == type_size
2432         });
2433         Operand::Constant(Box::new(Constant {
2434             span,
2435             user_ty: None,
2436             literal: ConstantKind::Val(ConstValue::Scalar(val), ty),
2437         }))
2438     }
2439
2440     pub fn to_copy(&self) -> Self {
2441         match *self {
2442             Operand::Copy(_) | Operand::Constant(_) => self.clone(),
2443             Operand::Move(place) => Operand::Copy(place),
2444         }
2445     }
2446
2447     /// Returns the `Place` that is the target of this `Operand`, or `None` if this `Operand` is a
2448     /// constant.
2449     pub fn place(&self) -> Option<Place<'tcx>> {
2450         match self {
2451             Operand::Copy(place) | Operand::Move(place) => Some(*place),
2452             Operand::Constant(_) => None,
2453         }
2454     }
2455
2456     /// Returns the `Constant` that is the target of this `Operand`, or `None` if this `Operand` is a
2457     /// place.
2458     pub fn constant(&self) -> Option<&Constant<'tcx>> {
2459         match self {
2460             Operand::Constant(x) => Some(&**x),
2461             Operand::Copy(_) | Operand::Move(_) => None,
2462         }
2463     }
2464
2465     /// Gets the `ty::FnDef` from an operand if it's a constant function item.
2466     ///
2467     /// While this is unlikely in general, it's the normal case of what you'll
2468     /// find as the `func` in a [`TerminatorKind::Call`].
2469     pub fn const_fn_def(&self) -> Option<(DefId, SubstsRef<'tcx>)> {
2470         let const_ty = self.constant()?.literal.ty();
2471         if let ty::FnDef(def_id, substs) = *const_ty.kind() { Some((def_id, substs)) } else { None }
2472     }
2473 }
2474
2475 ///////////////////////////////////////////////////////////////////////////
2476 /// Rvalues
2477
2478 #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
2479 /// The various kinds of rvalues that can appear in MIR.
2480 ///
2481 /// Not all of these are allowed at every [`MirPhase`] - when this is the case, it's stated below.
2482 ///
2483 /// Computing any rvalue begins by evaluating the places and operands in some order (**Needs
2484 /// clarification**: Which order?). These are then used to produce a "value" - the same kind of
2485 /// value that an [`Operand`] produces.
2486 pub enum Rvalue<'tcx> {
2487     /// Yields the operand unchanged
2488     Use(Operand<'tcx>),
2489
2490     /// Creates an array where each element is the value of the operand.
2491     ///
2492     /// This is the cause of a bug in the case where the repetition count is zero because the value
2493     /// is not dropped, see [#74836].
2494     ///
2495     /// Corresponds to source code like `[x; 32]`.
2496     ///
2497     /// [#74836]: https://github.com/rust-lang/rust/issues/74836
2498     Repeat(Operand<'tcx>, ty::Const<'tcx>),
2499
2500     /// Creates a reference of the indicated kind to the place.
2501     ///
2502     /// There is not much to document here, because besides the obvious parts the semantics of this
2503     /// are essentially entirely a part of the aliasing model. There are many UCG issues discussing
2504     /// exactly what the behavior of this operation should be.
2505     ///
2506     /// `Shallow` borrows are disallowed after drop lowering.
2507     Ref(Region<'tcx>, BorrowKind, Place<'tcx>),
2508
2509     /// Creates a pointer/reference to the given thread local.
2510     ///
2511     /// The yielded type is a `*mut T` if the static is mutable, otherwise if the static is extern a
2512     /// `*const T`, and if neither of those apply a `&T`.
2513     ///
2514     /// **Note:** This is a runtime operation that actually executes code and is in this sense more
2515     /// like a function call. Also, eliminating dead stores of this rvalue causes `fn main() {}` to
2516     /// SIGILL for some reason that I (JakobDegen) never got a chance to look into.
2517     ///
2518     /// **Needs clarification**: Are there weird additional semantics here related to the runtime
2519     /// nature of this operation?
2520     ThreadLocalRef(DefId),
2521
2522     /// Creates a pointer with the indicated mutability to the place.
2523     ///
2524     /// This is generated by pointer casts like `&v as *const _` or raw address of expressions like
2525     /// `&raw v` or `addr_of!(v)`.
2526     ///
2527     /// Like with references, the semantics of this operation are heavily dependent on the aliasing
2528     /// model.
2529     AddressOf(Mutability, Place<'tcx>),
2530
2531     /// Yields the length of the place, as a `usize`.
2532     ///
2533     /// If the type of the place is an array, this is the array length. For slices (`[T]`, not
2534     /// `&[T]`) this accesses the place's metadata to determine the length. This rvalue is
2535     /// ill-formed for places of other types.
2536     Len(Place<'tcx>),
2537
2538     /// Performs essentially all of the casts that can be performed via `as`.
2539     ///
2540     /// This allows for casts from/to a variety of types.
2541     ///
2542     /// **FIXME**: Document exactly which `CastKind`s allow which types of casts. Figure out why
2543     /// `ArrayToPointer` and `MutToConstPointer` are special.
2544     Cast(CastKind, Operand<'tcx>, Ty<'tcx>),
2545
2546     /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
2547     ///   parameter may be a `usize` as well.
2548     /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
2549     ///   raw pointers, or function pointers and return a `bool`. The types of the operands must be
2550     ///   matching, up to the usual caveat of the lifetimes in function pointers.
2551     /// * Left and right shift operations accept signed or unsigned integers not necessarily of the
2552     ///   same type and return a value of the same type as their LHS. Like in Rust, the RHS is
2553     ///   truncated as needed.
2554     /// * The `Bit*` operations accept signed integers, unsigned integers, or bools with matching
2555     ///   types and return a value of that type.
2556     /// * The remaining operations accept signed integers, unsigned integers, or floats with
2557     ///   matching types and return a value of that type.
2558     BinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
2559
2560     /// Same as `BinaryOp`, but yields `(T, bool)` instead of `T`. In addition to performing the
2561     /// same computation as the matching `BinaryOp`, checks if the infinite precison result would be
2562     /// unequal to the actual result and sets the `bool` if this is the case.
2563     ///
2564     /// This only supports addition, subtraction, multiplication, and shift operations on integers.
2565     CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
2566
2567     /// Computes a value as described by the operation.
2568     NullaryOp(NullOp, Ty<'tcx>),
2569
2570     /// Exactly like `BinaryOp`, but less operands.
2571     ///
2572     /// Also does two's-complement arithmetic. Negation requires a signed integer or a float;
2573     /// bitwise not requires a signed integer, unsigned integer, or bool. Both operation kinds
2574     /// return a value with the same type as their operand.
2575     UnaryOp(UnOp, Operand<'tcx>),
2576
2577     /// Computes the discriminant of the place, returning it as an integer of type
2578     /// [`discriminant_ty`]. Returns zero for types without discriminant.
2579     ///
2580     /// The validity requirements for the underlying value are undecided for this rvalue, see
2581     /// [#91095]. Note too that the value of the discriminant is not the same thing as the
2582     /// variant index; use [`discriminant_for_variant`] to convert.
2583     ///
2584     /// [`discriminant_ty`]: crate::ty::Ty::discriminant_ty
2585     /// [#91095]: https://github.com/rust-lang/rust/issues/91095
2586     /// [`discriminant_for_variant`]: crate::ty::Ty::discriminant_for_variant
2587     Discriminant(Place<'tcx>),
2588
2589     /// Creates an aggregate value, like a tuple or struct.
2590     ///
2591     /// This is needed because dataflow analysis needs to distinguish
2592     /// `dest = Foo { x: ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case that `Foo`
2593     /// has a destructor.
2594     ///
2595     /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
2596     /// generator lowering, `Generator` aggregate kinds are disallowed too.
2597     Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
2598
2599     /// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
2600     ///
2601     /// This is different from a normal transmute because dataflow analysis will treat the box as
2602     /// initialized but its content as uninitialized. Like other pointer casts, this in general
2603     /// affects alias analysis.
2604     ShallowInitBox(Operand<'tcx>, Ty<'tcx>),
2605 }
2606
2607 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
2608 static_assert_size!(Rvalue<'_>, 40);
2609
2610 impl<'tcx> Rvalue<'tcx> {
2611     /// Returns true if rvalue can be safely removed when the result is unused.
2612     #[inline]
2613     pub fn is_safe_to_remove(&self) -> bool {
2614         match self {
2615             // Pointer to int casts may be side-effects due to exposing the provenance.
2616             // While the model is undecided, we should be conservative. See
2617             // <https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html>
2618             Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => false,
2619
2620             Rvalue::Use(_)
2621             | Rvalue::Repeat(_, _)
2622             | Rvalue::Ref(_, _, _)
2623             | Rvalue::ThreadLocalRef(_)
2624             | Rvalue::AddressOf(_, _)
2625             | Rvalue::Len(_)
2626             | Rvalue::Cast(
2627                 CastKind::Misc | CastKind::Pointer(_) | CastKind::PointerFromExposedAddress,
2628                 _,
2629                 _,
2630             )
2631             | Rvalue::BinaryOp(_, _)
2632             | Rvalue::CheckedBinaryOp(_, _)
2633             | Rvalue::NullaryOp(_, _)
2634             | Rvalue::UnaryOp(_, _)
2635             | Rvalue::Discriminant(_)
2636             | Rvalue::Aggregate(_, _)
2637             | Rvalue::ShallowInitBox(_, _) => true,
2638         }
2639     }
2640 }
2641
2642 #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
2643 pub enum CastKind {
2644     /// An exposing pointer to address cast. A cast between a pointer and an integer type, or
2645     /// between a function pointer and an integer type.
2646     /// See the docs on `expose_addr` for more details.
2647     PointerExposeAddress,
2648     /// An address-to-pointer cast that picks up an exposed provenance.
2649     /// See the docs on `from_exposed_addr` for more details.
2650     PointerFromExposedAddress,
2651     /// All sorts of pointer-to-pointer casts. Note that reference-to-raw-ptr casts are
2652     /// translated into `&raw mut/const *r`, i.e., they are not actually casts.
2653     Pointer(PointerCast),
2654     /// Remaining unclassified casts.
2655     Misc,
2656 }
2657
2658 #[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
2659 pub enum AggregateKind<'tcx> {
2660     /// The type is of the element
2661     Array(Ty<'tcx>),
2662     Tuple,
2663
2664     /// The second field is the variant index. It's equal to 0 for struct
2665     /// and union expressions. The fourth field is
2666     /// active field number and is present only for union expressions
2667     /// -- e.g., for a union expression `SomeUnion { c: .. }`, the
2668     /// active field index would identity the field `c`
2669     Adt(DefId, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<usize>),
2670
2671     Closure(DefId, SubstsRef<'tcx>),
2672     Generator(DefId, SubstsRef<'tcx>, hir::Movability),
2673 }
2674
2675 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
2676 static_assert_size!(AggregateKind<'_>, 48);
2677
2678 #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
2679 pub enum BinOp {
2680     /// The `+` operator (addition)
2681     Add,
2682     /// The `-` operator (subtraction)
2683     Sub,
2684     /// The `*` operator (multiplication)
2685     Mul,
2686     /// The `/` operator (division)
2687     ///
2688     /// Division by zero is UB, because the compiler should have inserted checks
2689     /// prior to this.
2690     Div,
2691     /// The `%` operator (modulus)
2692     ///
2693     /// Using zero as the modulus (second operand) is UB, because the compiler
2694     /// should have inserted checks prior to this.
2695     Rem,
2696     /// The `^` operator (bitwise xor)
2697     BitXor,
2698     /// The `&` operator (bitwise and)
2699     BitAnd,
2700     /// The `|` operator (bitwise or)
2701     BitOr,
2702     /// The `<<` operator (shift left)
2703     ///
2704     /// The offset is truncated to the size of the first operand before shifting.
2705     Shl,
2706     /// The `>>` operator (shift right)
2707     ///
2708     /// The offset is truncated to the size of the first operand before shifting.
2709     Shr,
2710     /// The `==` operator (equality)
2711     Eq,
2712     /// The `<` operator (less than)
2713     Lt,
2714     /// The `<=` operator (less than or equal to)
2715     Le,
2716     /// The `!=` operator (not equal to)
2717     Ne,
2718     /// The `>=` operator (greater than or equal to)
2719     Ge,
2720     /// The `>` operator (greater than)
2721     Gt,
2722     /// The `ptr.offset` operator
2723     Offset,
2724 }
2725
2726 impl BinOp {
2727     pub fn is_checkable(self) -> bool {
2728         use self::BinOp::*;
2729         matches!(self, Add | Sub | Mul | Shl | Shr)
2730     }
2731 }
2732
2733 #[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
2734 pub enum NullOp {
2735     /// Returns the size of a value of that type
2736     SizeOf,
2737     /// Returns the minimum alignment of a type
2738     AlignOf,
2739 }
2740
2741 #[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
2742 pub enum UnOp {
2743     /// The `!` operator for logical inversion
2744     Not,
2745     /// The `-` operator for negation
2746     Neg,
2747 }
2748
2749 impl<'tcx> Debug for Rvalue<'tcx> {
2750     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
2751         use self::Rvalue::*;
2752
2753         match *self {
2754             Use(ref place) => write!(fmt, "{:?}", place),
2755             Repeat(ref a, b) => {
2756                 write!(fmt, "[{:?}; ", a)?;
2757                 pretty_print_const(b, fmt, false)?;
2758                 write!(fmt, "]")
2759             }
2760             Len(ref a) => write!(fmt, "Len({:?})", a),
2761             Cast(ref kind, ref place, ref ty) => {
2762                 write!(fmt, "{:?} as {:?} ({:?})", place, ty, kind)
2763             }
2764             BinaryOp(ref op, box (ref a, ref b)) => write!(fmt, "{:?}({:?}, {:?})", op, a, b),
2765             CheckedBinaryOp(ref op, box (ref a, ref b)) => {
2766                 write!(fmt, "Checked{:?}({:?}, {:?})", op, a, b)
2767             }
2768             UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
2769             Discriminant(ref place) => write!(fmt, "discriminant({:?})", place),
2770             NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t),
2771             ThreadLocalRef(did) => ty::tls::with(|tcx| {
2772                 let muta = tcx.static_mutability(did).unwrap().prefix_str();
2773                 write!(fmt, "&/*tls*/ {}{}", muta, tcx.def_path_str(did))
2774             }),
2775             Ref(region, borrow_kind, ref place) => {
2776                 let kind_str = match borrow_kind {
2777                     BorrowKind::Shared => "",
2778                     BorrowKind::Shallow => "shallow ",
2779                     BorrowKind::Mut { .. } | BorrowKind::Unique => "mut ",
2780                 };
2781
2782                 // When printing regions, add trailing space if necessary.
2783                 let print_region = ty::tls::with(|tcx| {
2784                     tcx.sess.verbose() || tcx.sess.opts.debugging_opts.identify_regions
2785                 });
2786                 let region = if print_region {
2787                     let mut region = region.to_string();
2788                     if !region.is_empty() {
2789                         region.push(' ');
2790                     }
2791                     region
2792                 } else {
2793                     // Do not even print 'static
2794                     String::new()
2795                 };
2796                 write!(fmt, "&{}{}{:?}", region, kind_str, place)
2797             }
2798
2799             AddressOf(mutability, ref place) => {
2800                 let kind_str = match mutability {
2801                     Mutability::Mut => "mut",
2802                     Mutability::Not => "const",
2803                 };
2804
2805                 write!(fmt, "&raw {} {:?}", kind_str, place)
2806             }
2807
2808             Aggregate(ref kind, ref places) => {
2809                 let fmt_tuple = |fmt: &mut Formatter<'_>, name: &str| {
2810                     let mut tuple_fmt = fmt.debug_tuple(name);
2811                     for place in places {
2812                         tuple_fmt.field(place);
2813                     }
2814                     tuple_fmt.finish()
2815                 };
2816
2817                 match **kind {
2818                     AggregateKind::Array(_) => write!(fmt, "{:?}", places),
2819
2820                     AggregateKind::Tuple => {
2821                         if places.is_empty() {
2822                             write!(fmt, "()")
2823                         } else {
2824                             fmt_tuple(fmt, "")
2825                         }
2826                     }
2827
2828                     AggregateKind::Adt(adt_did, variant, substs, _user_ty, _) => {
2829                         ty::tls::with(|tcx| {
2830                             let variant_def = &tcx.adt_def(adt_did).variant(variant);
2831                             let substs = tcx.lift(substs).expect("could not lift for printing");
2832                             let name = FmtPrinter::new(tcx, Namespace::ValueNS)
2833                                 .print_def_path(variant_def.def_id, substs)?
2834                                 .into_buffer();
2835
2836                             match variant_def.ctor_kind {
2837                                 CtorKind::Const => fmt.write_str(&name),
2838                                 CtorKind::Fn => fmt_tuple(fmt, &name),
2839                                 CtorKind::Fictive => {
2840                                     let mut struct_fmt = fmt.debug_struct(&name);
2841                                     for (field, place) in iter::zip(&variant_def.fields, places) {
2842                                         struct_fmt.field(field.name.as_str(), place);
2843                                     }
2844                                     struct_fmt.finish()
2845                                 }
2846                             }
2847                         })
2848                     }
2849
2850                     AggregateKind::Closure(def_id, substs) => ty::tls::with(|tcx| {
2851                         if let Some(def_id) = def_id.as_local() {
2852                             let name = if tcx.sess.opts.debugging_opts.span_free_formats {
2853                                 let substs = tcx.lift(substs).unwrap();
2854                                 format!(
2855                                     "[closure@{}]",
2856                                     tcx.def_path_str_with_substs(def_id.to_def_id(), substs),
2857                                 )
2858                             } else {
2859                                 let span = tcx.def_span(def_id);
2860                                 format!(
2861                                     "[closure@{}]",
2862                                     tcx.sess.source_map().span_to_diagnostic_string(span)
2863                                 )
2864                             };
2865                             let mut struct_fmt = fmt.debug_struct(&name);
2866
2867                             // FIXME(project-rfc-2229#48): This should be a list of capture names/places
2868                             if let Some(upvars) = tcx.upvars_mentioned(def_id) {
2869                                 for (&var_id, place) in iter::zip(upvars.keys(), places) {
2870                                     let var_name = tcx.hir().name(var_id);
2871                                     struct_fmt.field(var_name.as_str(), place);
2872                                 }
2873                             }
2874
2875                             struct_fmt.finish()
2876                         } else {
2877                             write!(fmt, "[closure]")
2878                         }
2879                     }),
2880
2881                     AggregateKind::Generator(def_id, _, _) => ty::tls::with(|tcx| {
2882                         if let Some(def_id) = def_id.as_local() {
2883                             let name = format!("[generator@{:?}]", tcx.def_span(def_id));
2884                             let mut struct_fmt = fmt.debug_struct(&name);
2885
2886                             // FIXME(project-rfc-2229#48): This should be a list of capture names/places
2887                             if let Some(upvars) = tcx.upvars_mentioned(def_id) {
2888                                 for (&var_id, place) in iter::zip(upvars.keys(), places) {
2889                                     let var_name = tcx.hir().name(var_id);
2890                                     struct_fmt.field(var_name.as_str(), place);
2891                                 }
2892                             }
2893
2894                             struct_fmt.finish()
2895                         } else {
2896                             write!(fmt, "[generator]")
2897                         }
2898                     }),
2899                 }
2900             }
2901
2902             ShallowInitBox(ref place, ref ty) => {
2903                 write!(fmt, "ShallowInitBox({:?}, {:?})", place, ty)
2904             }
2905         }
2906     }
2907 }
2908
2909 ///////////////////////////////////////////////////////////////////////////
2910 /// Constants
2911 ///
2912 /// Two constants are equal if they are the same constant. Note that
2913 /// this does not necessarily mean that they are `==` in Rust. In
2914 /// particular, one must be wary of `NaN`!
2915
2916 #[derive(Clone, Copy, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
2917 pub struct Constant<'tcx> {
2918     pub span: Span,
2919
2920     /// Optional user-given type: for something like
2921     /// `collect::<Vec<_>>`, this would be present and would
2922     /// indicate that `Vec<_>` was explicitly specified.
2923     ///
2924     /// Needed for NLL to impose user-given type constraints.
2925     pub user_ty: Option<UserTypeAnnotationIndex>,
2926
2927     pub literal: ConstantKind<'tcx>,
2928 }
2929
2930 #[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable, Debug)]
2931 #[derive(Lift)]
2932 pub enum ConstantKind<'tcx> {
2933     /// This constant came from the type system
2934     Ty(ty::Const<'tcx>),
2935     /// This constant cannot go back into the type system, as it represents
2936     /// something the type system cannot handle (e.g. pointers).
2937     Val(interpret::ConstValue<'tcx>, Ty<'tcx>),
2938 }
2939
2940 impl<'tcx> Constant<'tcx> {
2941     pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
2942         match self.literal.try_to_scalar() {
2943             Some(Scalar::Ptr(ptr, _size)) => match tcx.global_alloc(ptr.provenance) {
2944                 GlobalAlloc::Static(def_id) => {
2945                     assert!(!tcx.is_thread_local_static(def_id));
2946                     Some(def_id)
2947                 }
2948                 _ => None,
2949             },
2950             _ => None,
2951         }
2952     }
2953     #[inline]
2954     pub fn ty(&self) -> Ty<'tcx> {
2955         self.literal.ty()
2956     }
2957 }
2958
2959 impl<'tcx> ConstantKind<'tcx> {
2960     /// Returns `None` if the constant is not trivially safe for use in the type system.
2961     #[inline]
2962     pub fn const_for_ty(&self) -> Option<ty::Const<'tcx>> {
2963         match self {
2964             ConstantKind::Ty(c) => Some(*c),
2965             ConstantKind::Val(..) => None,
2966         }
2967     }
2968
2969     #[inline(always)]
2970     pub fn ty(&self) -> Ty<'tcx> {
2971         match self {
2972             ConstantKind::Ty(c) => c.ty(),
2973             ConstantKind::Val(_, ty) => *ty,
2974         }
2975     }
2976
2977     #[inline]
2978     pub fn try_to_value(self, tcx: TyCtxt<'tcx>) -> Option<interpret::ConstValue<'tcx>> {
2979         match self {
2980             ConstantKind::Ty(c) => match c.kind() {
2981                 ty::ConstKind::Value(valtree) => Some(tcx.valtree_to_const_val((c.ty(), valtree))),
2982                 _ => None,
2983             },
2984             ConstantKind::Val(val, _) => Some(val),
2985         }
2986     }
2987
2988     #[inline]
2989     pub fn try_to_scalar(self) -> Option<Scalar> {
2990         match self {
2991             ConstantKind::Ty(c) => match c.kind() {
2992                 ty::ConstKind::Value(valtree) => match valtree {
2993                     ty::ValTree::Leaf(scalar_int) => Some(Scalar::Int(scalar_int)),
2994                     ty::ValTree::Branch(_) => None,
2995                 },
2996                 _ => None,
2997             },
2998             ConstantKind::Val(val, _) => val.try_to_scalar(),
2999         }
3000     }
3001
3002     #[inline]
3003     pub fn try_to_scalar_int(self) -> Option<ScalarInt> {
3004         Some(self.try_to_scalar()?.assert_int())
3005     }
3006
3007     #[inline]
3008     pub fn try_to_bits(self, size: Size) -> Option<u128> {
3009         self.try_to_scalar_int()?.to_bits(size).ok()
3010     }
3011
3012     #[inline]
3013     pub fn try_to_bool(self) -> Option<bool> {
3014         self.try_to_scalar_int()?.try_into().ok()
3015     }
3016
3017     #[inline]
3018     pub fn eval(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
3019         match self {
3020             Self::Ty(c) => {
3021                 if let Some(val) = c.kind().try_eval_for_mir(tcx, param_env) {
3022                     match val {
3023                         Ok(val) => Self::Val(val, c.ty()),
3024                         Err(_) => Self::Ty(tcx.const_error(self.ty())),
3025                     }
3026                 } else {
3027                     self
3028                 }
3029             }
3030             Self::Val(_, _) => self,
3031         }
3032     }
3033
3034     /// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type.
3035     #[inline]
3036     pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 {
3037         self.try_eval_bits(tcx, param_env, ty)
3038             .unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self))
3039     }
3040
3041     #[inline]
3042     pub fn try_eval_bits(
3043         &self,
3044         tcx: TyCtxt<'tcx>,
3045         param_env: ty::ParamEnv<'tcx>,
3046         ty: Ty<'tcx>,
3047     ) -> Option<u128> {
3048         match self {
3049             Self::Ty(ct) => ct.try_eval_bits(tcx, param_env, ty),
3050             Self::Val(val, t) => {
3051                 assert_eq!(*t, ty);
3052                 let size =
3053                     tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size;
3054                 val.try_to_bits(size)
3055             }
3056         }
3057     }
3058
3059     #[inline]
3060     pub fn try_eval_bool(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option<bool> {
3061         match self {
3062             Self::Ty(ct) => ct.try_eval_bool(tcx, param_env),
3063             Self::Val(val, _) => val.try_to_bool(),
3064         }
3065     }
3066
3067     #[inline]
3068     pub fn try_eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Option<u64> {
3069         match self {
3070             Self::Ty(ct) => ct.try_eval_usize(tcx, param_env),
3071             Self::Val(val, _) => val.try_to_machine_usize(tcx),
3072         }
3073     }
3074
3075     #[inline]
3076     pub fn from_value(val: ConstValue<'tcx>, ty: Ty<'tcx>) -> Self {
3077         Self::Val(val, ty)
3078     }
3079
3080     pub fn from_bits(
3081         tcx: TyCtxt<'tcx>,
3082         bits: u128,
3083         param_env_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
3084     ) -> Self {
3085         let size = tcx
3086             .layout_of(param_env_ty)
3087             .unwrap_or_else(|e| {
3088                 bug!("could not compute layout for {:?}: {:?}", param_env_ty.value, e)
3089             })
3090             .size;
3091         let cv = ConstValue::Scalar(Scalar::from_uint(bits, size));
3092
3093         Self::Val(cv, param_env_ty.value)
3094     }
3095
3096     #[inline]
3097     pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> Self {
3098         let cv = ConstValue::from_bool(v);
3099         Self::Val(cv, tcx.types.bool)
3100     }
3101
3102     #[inline]
3103     pub fn zero_sized(ty: Ty<'tcx>) -> Self {
3104         let cv = ConstValue::Scalar(Scalar::ZST);
3105         Self::Val(cv, ty)
3106     }
3107
3108     pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> Self {
3109         let ty = tcx.types.usize;
3110         Self::from_bits(tcx, n as u128, ty::ParamEnv::empty().and(ty))
3111     }
3112
3113     #[inline]
3114     pub fn from_scalar(_tcx: TyCtxt<'tcx>, s: Scalar, ty: Ty<'tcx>) -> Self {
3115         let val = ConstValue::Scalar(s);
3116         Self::Val(val, ty)
3117     }
3118
3119     /// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly
3120     /// converted to a constant, everything else becomes `Unevaluated`.
3121     pub fn from_anon_const(
3122         tcx: TyCtxt<'tcx>,
3123         def_id: LocalDefId,
3124         param_env: ty::ParamEnv<'tcx>,
3125     ) -> Self {
3126         Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id), param_env)
3127     }
3128
3129     #[instrument(skip(tcx), level = "debug")]
3130     pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
3131         let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
3132         let body_id = match tcx.hir().get(hir_id) {
3133             hir::Node::AnonConst(ac) => ac.body,
3134             _ => span_bug!(
3135                 tcx.def_span(def_id.to_def_id()),
3136                 "from_inline_const can only process anonymous constants"
3137             ),
3138         };
3139         let expr = &tcx.hir().body(body_id).value;
3140         let ty = tcx.typeck(def_id).node_type(hir_id);
3141
3142         let lit_input = match expr.kind {
3143             hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
3144             hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
3145                 hir::ExprKind::Lit(ref lit) => {
3146                     Some(LitToConstInput { lit: &lit.node, ty, neg: true })
3147                 }
3148                 _ => None,
3149             },
3150             _ => None,
3151         };
3152         if let Some(lit_input) = lit_input {
3153             // If an error occurred, ignore that it's a literal and leave reporting the error up to
3154             // mir.
3155             match tcx.at(expr.span).lit_to_mir_constant(lit_input) {
3156                 Ok(c) => return c,
3157                 Err(_) => {}
3158             }
3159         }
3160
3161         let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id());
3162         let parent_substs =
3163             tcx.erase_regions(InternalSubsts::identity_for_item(tcx, typeck_root_def_id));
3164         let substs =
3165             ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
3166                 .substs;
3167         let uneval_const = tcx.mk_const(ty::ConstS {
3168             kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
3169                 def: ty::WithOptConstParam::unknown(def_id).to_global(),
3170                 substs,
3171                 promoted: None,
3172             }),
3173             ty,
3174         });
3175         debug!(?uneval_const);
3176         debug_assert!(!uneval_const.has_free_regions());
3177
3178         Self::Ty(uneval_const)
3179     }
3180
3181     #[instrument(skip(tcx), level = "debug")]
3182     fn from_opt_const_arg_anon_const(
3183         tcx: TyCtxt<'tcx>,
3184         def: ty::WithOptConstParam<LocalDefId>,
3185         param_env: ty::ParamEnv<'tcx>,
3186     ) -> Self {
3187         let body_id = match tcx.hir().get_by_def_id(def.did) {
3188             hir::Node::AnonConst(ac) => ac.body,
3189             _ => span_bug!(
3190                 tcx.def_span(def.did.to_def_id()),
3191                 "from_anon_const can only process anonymous constants"
3192             ),
3193         };
3194
3195         let expr = &tcx.hir().body(body_id).value;
3196         debug!(?expr);
3197
3198         // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
3199         // currently have to be wrapped in curly brackets, so it's necessary to special-case.
3200         let expr = match &expr.kind {
3201             hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
3202                 block.expr.as_ref().unwrap()
3203             }
3204             _ => expr,
3205         };
3206         debug!("expr.kind: {:?}", expr.kind);
3207
3208         let ty = tcx.type_of(def.def_id_for_type_of());
3209         debug!(?ty);
3210
3211         // FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
3212         // does not provide the parents generics to anonymous constants. We still allow generic const
3213         // parameters by themselves however, e.g. `N`.  These constants would cause an ICE if we were to
3214         // ever try to substitute the generic parameters in their bodies.
3215         //
3216         // While this doesn't happen as these constants are always used as `ty::ConstKind::Param`, it does
3217         // cause issues if we were to remove that special-case and try to evaluate the constant instead.
3218         use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath};
3219         match expr.kind {
3220             ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => {
3221                 // Find the name and index of the const parameter by indexing the generics of
3222                 // the parent item and construct a `ParamConst`.
3223                 let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
3224                 let item_id = tcx.hir().get_parent_node(hir_id);
3225                 let item_def_id = tcx.hir().local_def_id(item_id);
3226                 let generics = tcx.generics_of(item_def_id.to_def_id());
3227                 let index = generics.param_def_id_to_index[&def_id];
3228                 let name = tcx.hir().name(hir_id);
3229                 let ty_const = tcx.mk_const(ty::ConstS {
3230                     kind: ty::ConstKind::Param(ty::ParamConst::new(index, name)),
3231                     ty,
3232                 });
3233                 debug!(?ty_const);
3234
3235                 return Self::Ty(ty_const);
3236             }
3237             _ => {}
3238         }
3239
3240         let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
3241         let parent_substs = if let Some(parent_hir_id) = tcx.hir().find_parent_node(hir_id) {
3242             if let Some(parent_did) = tcx.hir().opt_local_def_id(parent_hir_id) {
3243                 InternalSubsts::identity_for_item(tcx, parent_did.to_def_id())
3244             } else {
3245                 tcx.mk_substs(Vec::<GenericArg<'tcx>>::new().into_iter())
3246             }
3247         } else {
3248             tcx.mk_substs(Vec::<GenericArg<'tcx>>::new().into_iter())
3249         };
3250         debug!(?parent_substs);
3251
3252         let did = def.did.to_def_id();
3253         let child_substs = InternalSubsts::identity_for_item(tcx, did);
3254         let substs = tcx.mk_substs(parent_substs.into_iter().chain(child_substs.into_iter()));
3255         debug!(?substs);
3256
3257         let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
3258         let span = tcx.hir().span(hir_id);
3259         let uneval = ty::Unevaluated::new(def.to_global(), substs);
3260         debug!(?span, ?param_env);
3261
3262         match tcx.const_eval_resolve(param_env, uneval, Some(span)) {
3263             Ok(val) => {
3264                 debug!("evaluated const value: {:?}", val);
3265                 Self::Val(val, ty)
3266             }
3267             Err(_) => {
3268                 debug!("error encountered during evaluation");
3269                 // Error was handled in `const_eval_resolve`. Here we just create a
3270                 // new unevaluated const and error hard later in codegen
3271                 let ty_const = tcx.mk_const(ty::ConstS {
3272                     kind: ty::ConstKind::Unevaluated(ty::Unevaluated {
3273                         def: def.to_global(),
3274                         substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
3275                         promoted: None,
3276                     }),
3277                     ty,
3278                 });
3279                 debug!(?ty_const);
3280
3281                 Self::Ty(ty_const)
3282             }
3283         }
3284     }
3285
3286     pub fn from_const(c: ty::Const<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
3287         match c.kind() {
3288             ty::ConstKind::Value(valtree) => {
3289                 let const_val = tcx.valtree_to_const_val((c.ty(), valtree));
3290                 Self::Val(const_val, c.ty())
3291             }
3292             _ => Self::Ty(c),
3293         }
3294     }
3295 }
3296
3297 /// A collection of projections into user types.
3298 ///
3299 /// They are projections because a binding can occur a part of a
3300 /// parent pattern that has been ascribed a type.
3301 ///
3302 /// Its a collection because there can be multiple type ascriptions on
3303 /// the path from the root of the pattern down to the binding itself.
3304 ///
3305 /// An example:
3306 ///
3307 /// ```ignore (illustrative)
3308 /// struct S<'a>((i32, &'a str), String);
3309 /// let S((_, w): (i32, &'static str), _): S = ...;
3310 /// //    ------  ^^^^^^^^^^^^^^^^^^^ (1)
3311 /// //  ---------------------------------  ^ (2)
3312 /// ```
3313 ///
3314 /// The highlights labelled `(1)` show the subpattern `(_, w)` being
3315 /// ascribed the type `(i32, &'static str)`.
3316 ///
3317 /// The highlights labelled `(2)` show the whole pattern being
3318 /// ascribed the type `S`.
3319 ///
3320 /// In this example, when we descend to `w`, we will have built up the
3321 /// following two projected types:
3322 ///
3323 ///   * base: `S`,                   projection: `(base.0).1`
3324 ///   * base: `(i32, &'static str)`, projection: `base.1`
3325 ///
3326 /// The first will lead to the constraint `w: &'1 str` (for some
3327 /// inferred region `'1`). The second will lead to the constraint `w:
3328 /// &'static str`.
3329 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
3330 pub struct UserTypeProjections {
3331     pub contents: Vec<(UserTypeProjection, Span)>,
3332 }
3333
3334 impl<'tcx> UserTypeProjections {
3335     pub fn none() -> Self {
3336         UserTypeProjections { contents: vec![] }
3337     }
3338
3339     pub fn is_empty(&self) -> bool {
3340         self.contents.is_empty()
3341     }
3342
3343     pub fn projections_and_spans(
3344         &self,
3345     ) -> impl Iterator<Item = &(UserTypeProjection, Span)> + ExactSizeIterator {
3346         self.contents.iter()
3347     }
3348
3349     pub fn projections(&self) -> impl Iterator<Item = &UserTypeProjection> + ExactSizeIterator {
3350         self.contents.iter().map(|&(ref user_type, _span)| user_type)
3351     }
3352
3353     pub fn push_projection(mut self, user_ty: &UserTypeProjection, span: Span) -> Self {
3354         self.contents.push((user_ty.clone(), span));
3355         self
3356     }
3357
3358     fn map_projections(
3359         mut self,
3360         mut f: impl FnMut(UserTypeProjection) -> UserTypeProjection,
3361     ) -> Self {
3362         self.contents = self.contents.into_iter().map(|(proj, span)| (f(proj), span)).collect();
3363         self
3364     }
3365
3366     pub fn index(self) -> Self {
3367         self.map_projections(|pat_ty_proj| pat_ty_proj.index())
3368     }
3369
3370     pub fn subslice(self, from: u64, to: u64) -> Self {
3371         self.map_projections(|pat_ty_proj| pat_ty_proj.subslice(from, to))
3372     }
3373
3374     pub fn deref(self) -> Self {
3375         self.map_projections(|pat_ty_proj| pat_ty_proj.deref())
3376     }
3377
3378     pub fn leaf(self, field: Field) -> Self {
3379         self.map_projections(|pat_ty_proj| pat_ty_proj.leaf(field))
3380     }
3381
3382     pub fn variant(self, adt_def: AdtDef<'tcx>, variant_index: VariantIdx, field: Field) -> Self {
3383         self.map_projections(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field))
3384     }
3385 }
3386
3387 /// Encodes the effect of a user-supplied type annotation on the
3388 /// subcomponents of a pattern. The effect is determined by applying the
3389 /// given list of projections to some underlying base type. Often,
3390 /// the projection element list `projs` is empty, in which case this
3391 /// directly encodes a type in `base`. But in the case of complex patterns with
3392 /// subpatterns and bindings, we want to apply only a *part* of the type to a variable,
3393 /// in which case the `projs` vector is used.
3394 ///
3395 /// Examples:
3396 ///
3397 /// * `let x: T = ...` -- here, the `projs` vector is empty.
3398 ///
3399 /// * `let (x, _): T = ...` -- here, the `projs` vector would contain
3400 ///   `field[0]` (aka `.0`), indicating that the type of `s` is
3401 ///   determined by finding the type of the `.0` field from `T`.
3402 #[derive(Clone, Debug, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
3403 pub struct UserTypeProjection {
3404     pub base: UserTypeAnnotationIndex,
3405     pub projs: Vec<ProjectionKind>,
3406 }
3407
3408 impl Copy for ProjectionKind {}
3409
3410 impl UserTypeProjection {
3411     pub(crate) fn index(mut self) -> Self {
3412         self.projs.push(ProjectionElem::Index(()));
3413         self
3414     }
3415
3416     pub(crate) fn subslice(mut self, from: u64, to: u64) -> Self {
3417         self.projs.push(ProjectionElem::Subslice { from, to, from_end: true });
3418         self
3419     }
3420
3421     pub(crate) fn deref(mut self) -> Self {
3422         self.projs.push(ProjectionElem::Deref);
3423         self
3424     }
3425
3426     pub(crate) fn leaf(mut self, field: Field) -> Self {
3427         self.projs.push(ProjectionElem::Field(field, ()));
3428         self
3429     }
3430
3431     pub(crate) fn variant(
3432         mut self,
3433         adt_def: AdtDef<'_>,
3434         variant_index: VariantIdx,
3435         field: Field,
3436     ) -> Self {
3437         self.projs.push(ProjectionElem::Downcast(
3438             Some(adt_def.variant(variant_index).name),
3439             variant_index,
3440         ));
3441         self.projs.push(ProjectionElem::Field(field, ()));
3442         self
3443     }
3444 }
3445
3446 TrivialTypeFoldableAndLiftImpls! { ProjectionKind, }
3447
3448 impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
3449     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
3450         Ok(UserTypeProjection {
3451             base: self.base.try_fold_with(folder)?,
3452             projs: self.projs.try_fold_with(folder)?,
3453         })
3454     }
3455
3456     fn visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<Vs::BreakTy> {
3457         self.base.visit_with(visitor)
3458         // Note: there's nothing in `self.proj` to visit.
3459     }
3460 }
3461
3462 rustc_index::newtype_index! {
3463     pub struct Promoted {
3464         derive [HashStable]
3465         DEBUG_FORMAT = "promoted[{}]"
3466     }
3467 }
3468
3469 impl<'tcx> Debug for Constant<'tcx> {
3470     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
3471         write!(fmt, "{}", self)
3472     }
3473 }
3474
3475 impl<'tcx> Display for Constant<'tcx> {
3476     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
3477         match self.ty().kind() {
3478             ty::FnDef(..) => {}
3479             _ => write!(fmt, "const ")?,
3480         }
3481         Display::fmt(&self.literal, fmt)
3482     }
3483 }
3484
3485 impl<'tcx> Display for ConstantKind<'tcx> {
3486     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
3487         match *self {
3488             ConstantKind::Ty(c) => pretty_print_const(c, fmt, true),
3489             ConstantKind::Val(val, ty) => pretty_print_const_value(val, ty, fmt, true),
3490         }
3491     }
3492 }
3493
3494 fn pretty_print_const<'tcx>(
3495     c: ty::Const<'tcx>,
3496     fmt: &mut Formatter<'_>,
3497     print_types: bool,
3498 ) -> fmt::Result {
3499     use crate::ty::print::PrettyPrinter;
3500     ty::tls::with(|tcx| {
3501         let literal = tcx.lift(c).unwrap();
3502         let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
3503         cx.print_alloc_ids = true;
3504         let cx = cx.pretty_print_const(literal, print_types)?;
3505         fmt.write_str(&cx.into_buffer())?;
3506         Ok(())
3507     })
3508 }
3509
3510 fn pretty_print_byte_str(fmt: &mut Formatter<'_>, byte_str: &[u8]) -> fmt::Result {
3511     fmt.write_str("b\"")?;
3512     for &c in byte_str {
3513         for e in std::ascii::escape_default(c) {
3514             fmt.write_char(e as char)?;
3515         }
3516     }
3517     fmt.write_str("\"")?;
3518
3519     Ok(())
3520 }
3521
3522 fn comma_sep<'tcx>(fmt: &mut Formatter<'_>, elems: Vec<ConstantKind<'tcx>>) -> fmt::Result {
3523     let mut first = true;
3524     for elem in elems {
3525         if !first {
3526             fmt.write_str(", ")?;
3527         }
3528         fmt.write_str(&format!("{}", elem))?;
3529         first = false;
3530     }
3531     Ok(())
3532 }
3533
3534 // FIXME: Move that into `mir/pretty.rs`.
3535 fn pretty_print_const_value<'tcx>(
3536     ct: ConstValue<'tcx>,
3537     ty: Ty<'tcx>,
3538     fmt: &mut Formatter<'_>,
3539     print_ty: bool,
3540 ) -> fmt::Result {
3541     use crate::ty::print::PrettyPrinter;
3542
3543     ty::tls::with(|tcx| {
3544         let ct = tcx.lift(ct).unwrap();
3545         let ty = tcx.lift(ty).unwrap();
3546
3547         if tcx.sess.verbose() {
3548             fmt.write_str(&format!("ConstValue({:?}: {})", ct, ty))?;
3549             return Ok(());
3550         }
3551
3552         let u8_type = tcx.types.u8;
3553         match (ct, ty.kind()) {
3554             // Byte/string slices, printed as (byte) string literals.
3555             (ConstValue::Slice { data, start, end }, ty::Ref(_, inner, _)) => {
3556                 match inner.kind() {
3557                     ty::Slice(t) => {
3558                         if *t == u8_type {
3559                             // The `inspect` here is okay since we checked the bounds, and there are
3560                             // no relocations (we have an active slice reference here). We don't use
3561                             // this result to affect interpreter execution.
3562                             let byte_str = data
3563                                 .inner()
3564                                 .inspect_with_uninit_and_ptr_outside_interpreter(start..end);
3565                             pretty_print_byte_str(fmt, byte_str)?;
3566                             return Ok(());
3567                         }
3568                     }
3569                     ty::Str => {
3570                         // The `inspect` here is okay since we checked the bounds, and there are no
3571                         // relocations (we have an active `str` reference here). We don't use this
3572                         // result to affect interpreter execution.
3573                         let slice = data
3574                             .inner()
3575                             .inspect_with_uninit_and_ptr_outside_interpreter(start..end);
3576                         fmt.write_str(&format!("{:?}", String::from_utf8_lossy(slice)))?;
3577                         return Ok(());
3578                     }
3579                     _ => {}
3580                 }
3581             }
3582             (ConstValue::ByRef { alloc, offset }, ty::Array(t, n)) if *t == u8_type => {
3583                 let n = n.kind().try_to_bits(tcx.data_layout.pointer_size).unwrap();
3584                 // cast is ok because we already checked for pointer size (32 or 64 bit) above
3585                 let range = AllocRange { start: offset, size: Size::from_bytes(n) };
3586                 let byte_str = alloc.inner().get_bytes(&tcx, range).unwrap();
3587                 fmt.write_str("*")?;
3588                 pretty_print_byte_str(fmt, byte_str)?;
3589                 return Ok(());
3590             }
3591             // Aggregates, printed as array/tuple/struct/variant construction syntax.
3592             //
3593             // NB: the `has_param_types_or_consts` check ensures that we can use
3594             // the `destructure_const` query with an empty `ty::ParamEnv` without
3595             // introducing ICEs (e.g. via `layout_of`) from missing bounds.
3596             // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized`
3597             // to be able to destructure the tuple into `(0u8, *mut T)
3598             //
3599             // FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the
3600             // correct `ty::ParamEnv` to allow printing *all* constant values.
3601             (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => {
3602                 let ct = tcx.lift(ct).unwrap();
3603                 let ty = tcx.lift(ty).unwrap();
3604                 if let Some(contents) = tcx.try_destructure_mir_constant(
3605                     ty::ParamEnv::reveal_all().and(ConstantKind::Val(ct, ty)),
3606                 ) {
3607                     let fields = contents.fields.iter().copied().collect::<Vec<_>>();
3608                     match *ty.kind() {
3609                         ty::Array(..) => {
3610                             fmt.write_str("[")?;
3611                             comma_sep(fmt, fields)?;
3612                             fmt.write_str("]")?;
3613                         }
3614                         ty::Tuple(..) => {
3615                             fmt.write_str("(")?;
3616                             comma_sep(fmt, fields)?;
3617                             if contents.fields.len() == 1 {
3618                                 fmt.write_str(",")?;
3619                             }
3620                             fmt.write_str(")")?;
3621                         }
3622                         ty::Adt(def, _) if def.variants().is_empty() => {
3623                             fmt.write_str(&format!("{{unreachable(): {}}}", ty))?;
3624                         }
3625                         ty::Adt(def, substs) => {
3626                             let variant_idx = contents
3627                                 .variant
3628                                 .expect("destructed mir constant of adt without variant idx");
3629                             let variant_def = &def.variant(variant_idx);
3630                             let substs = tcx.lift(substs).unwrap();
3631                             let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
3632                             cx.print_alloc_ids = true;
3633                             let cx = cx.print_value_path(variant_def.def_id, substs)?;
3634                             fmt.write_str(&cx.into_buffer())?;
3635
3636                             match variant_def.ctor_kind {
3637                                 CtorKind::Const => {}
3638                                 CtorKind::Fn => {
3639                                     fmt.write_str("(")?;
3640                                     comma_sep(fmt, fields)?;
3641                                     fmt.write_str(")")?;
3642                                 }
3643                                 CtorKind::Fictive => {
3644                                     fmt.write_str(" {{ ")?;
3645                                     let mut first = true;
3646                                     for (field_def, field) in iter::zip(&variant_def.fields, fields)
3647                                     {
3648                                         if !first {
3649                                             fmt.write_str(", ")?;
3650                                         }
3651                                         fmt.write_str(&format!("{}: {}", field_def.name, field))?;
3652                                         first = false;
3653                                     }
3654                                     fmt.write_str(" }}")?;
3655                                 }
3656                             }
3657                         }
3658                         _ => unreachable!(),
3659                     }
3660                     return Ok(());
3661                 } else {
3662                     // Fall back to debug pretty printing for invalid constants.
3663                     fmt.write_str(&format!("{:?}", ct))?;
3664                     if print_ty {
3665                         fmt.write_str(&format!(": {}", ty))?;
3666                     }
3667                     return Ok(());
3668                 };
3669             }
3670             (ConstValue::Scalar(scalar), _) => {
3671                 let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
3672                 cx.print_alloc_ids = true;
3673                 let ty = tcx.lift(ty).unwrap();
3674                 cx = cx.pretty_print_const_scalar(scalar, ty, print_ty)?;
3675                 fmt.write_str(&cx.into_buffer())?;
3676                 return Ok(());
3677             }
3678             // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
3679             // their fields instead of just dumping the memory.
3680             _ => {}
3681         }
3682         // fallback
3683         fmt.write_str(&format!("{:?}", ct))?;
3684         if print_ty {
3685             fmt.write_str(&format!(": {}", ty))?;
3686         }
3687         Ok(())
3688     })
3689 }
3690
3691 impl<'tcx> graph::DirectedGraph for Body<'tcx> {
3692     type Node = BasicBlock;
3693 }
3694
3695 impl<'tcx> graph::WithNumNodes for Body<'tcx> {
3696     #[inline]
3697     fn num_nodes(&self) -> usize {
3698         self.basic_blocks.len()
3699     }
3700 }
3701
3702 impl<'tcx> graph::WithStartNode for Body<'tcx> {
3703     #[inline]
3704     fn start_node(&self) -> Self::Node {
3705         START_BLOCK
3706     }
3707 }
3708
3709 impl<'tcx> graph::WithSuccessors for Body<'tcx> {
3710     #[inline]
3711     fn successors(&self, node: Self::Node) -> <Self as GraphSuccessors<'_>>::Iter {
3712         self.basic_blocks[node].terminator().successors()
3713     }
3714 }
3715
3716 impl<'a, 'b> graph::GraphSuccessors<'b> for Body<'a> {
3717     type Item = BasicBlock;
3718     type Iter = Successors<'b>;
3719 }
3720
3721 impl<'tcx, 'graph> graph::GraphPredecessors<'graph> for Body<'tcx> {
3722     type Item = BasicBlock;
3723     type Iter = std::iter::Copied<std::slice::Iter<'graph, BasicBlock>>;
3724 }
3725
3726 impl<'tcx> graph::WithPredecessors for Body<'tcx> {
3727     #[inline]
3728     fn predecessors(&self, node: Self::Node) -> <Self as graph::GraphPredecessors<'_>>::Iter {
3729         self.predecessors()[node].iter().copied()
3730     }
3731 }
3732
3733 /// `Location` represents the position of the start of the statement; or, if
3734 /// `statement_index` equals the number of statements, then the start of the
3735 /// terminator.
3736 #[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable)]
3737 pub struct Location {
3738     /// The block that the location is within.
3739     pub block: BasicBlock,
3740
3741     pub statement_index: usize,
3742 }
3743
3744 impl fmt::Debug for Location {
3745     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
3746         write!(fmt, "{:?}[{}]", self.block, self.statement_index)
3747     }
3748 }
3749
3750 impl Location {
3751     pub const START: Location = Location { block: START_BLOCK, statement_index: 0 };
3752
3753     /// Returns the location immediately after this one within the enclosing block.
3754     ///
3755     /// Note that if this location represents a terminator, then the
3756     /// resulting location would be out of bounds and invalid.
3757     pub fn successor_within_block(&self) -> Location {
3758         Location { block: self.block, statement_index: self.statement_index + 1 }
3759     }
3760
3761     /// Returns `true` if `other` is earlier in the control flow graph than `self`.
3762     pub fn is_predecessor_of<'tcx>(&self, other: Location, body: &Body<'tcx>) -> bool {
3763         // If we are in the same block as the other location and are an earlier statement
3764         // then we are a predecessor of `other`.
3765         if self.block == other.block && self.statement_index < other.statement_index {
3766             return true;
3767         }
3768
3769         let predecessors = body.predecessors();
3770
3771         // If we're in another block, then we want to check that block is a predecessor of `other`.
3772         let mut queue: Vec<BasicBlock> = predecessors[other.block].to_vec();
3773         let mut visited = FxHashSet::default();
3774
3775         while let Some(block) = queue.pop() {
3776             // If we haven't visited this block before, then make sure we visit its predecessors.
3777             if visited.insert(block) {
3778                 queue.extend(predecessors[block].iter().cloned());
3779             } else {
3780                 continue;
3781             }
3782
3783             // If we found the block that `self` is in, then we are a predecessor of `other` (since
3784             // we found that block by looking at the predecessors of `other`).
3785             if self.block == block {
3786                 return true;
3787             }
3788         }
3789
3790         false
3791     }
3792
3793     pub fn dominates(&self, other: Location, dominators: &Dominators<BasicBlock>) -> bool {
3794         if self.block == other.block {
3795             self.statement_index <= other.statement_index
3796         } else {
3797             dominators.is_dominated_by(other.block, self.block)
3798         }
3799     }
3800 }