From 468742b025004862320237d288308cc562a5573e Mon Sep 17 00:00:00 2001 From: kadmin Date: Thu, 12 May 2022 05:05:44 +0000 Subject: [PATCH 1/2] Add dataflow analysis of enum variants Constify `Discriminant` Fix wrong size scalar in const_from_scalar Kill aliasable enums bless mir Praise the mir Switch to FxHashMap Rm bots Attempt btreemap instead of hash Maybe there were issues with queries? Reattempt index vec Implement cache for dataflow analysis Add test Move single enum after const prop --- .../rustc_mir_dataflow/src/framework/fmt.rs | 25 + .../src/framework/lattice.rs | 180 +++++++ compiler/rustc_mir_dataflow/src/impls/mod.rs | 2 + .../src/impls/single_enum_variant.rs | 171 +++++++ compiler/rustc_mir_dataflow/src/lib.rs | 1 + compiler/rustc_mir_transform/src/lib.rs | 2 + .../rustc_mir_transform/src/single_enum.rs | 59 +++ .../mir-opt/enum_prop.main.SingleEnum.diff | 475 ++++++++++++++++++ src/test/mir-opt/enum_prop.rs | 20 + src/test/ui/drop/issue-90752.rs | 4 +- src/test/ui/let-else/let-else-run-pass.rs | 6 +- 11 files changed, 940 insertions(+), 5 deletions(-) create mode 100644 compiler/rustc_mir_dataflow/src/impls/single_enum_variant.rs create mode 100644 compiler/rustc_mir_transform/src/single_enum.rs create mode 100644 src/test/mir-opt/enum_prop.main.SingleEnum.diff create mode 100644 src/test/mir-opt/enum_prop.rs diff --git a/compiler/rustc_mir_dataflow/src/framework/fmt.rs b/compiler/rustc_mir_dataflow/src/framework/fmt.rs index 209e6f7ac9fe4..4acf47e75a57e 100644 --- a/compiler/rustc_mir_dataflow/src/framework/fmt.rs +++ b/compiler/rustc_mir_dataflow/src/framework/fmt.rs @@ -1,6 +1,7 @@ //! Custom formatting traits used when outputting Graphviz diagrams with the results of a dataflow //! analysis. +use crate::lattice::{FactArray, FactCache}; use rustc_index::bit_set::{BitSet, ChunkedBitSet, HybridBitSet}; use rustc_index::vec::Idx; use std::fmt; @@ -124,6 +125,30 @@ where } } +impl DebugWithContext for FactArray +where + T: DebugWithContext, +{ + fn fmt_with(&self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_map() + .entries( + self.arr + .iter() + .enumerate() + .map(|(i, ref v)| (i, DebugWithAdapter { this: *v, ctxt })), + ) + .finish() + } +} + +impl + DebugWithContext for FactCache +{ + fn fmt_with(&self, _: &C, _: &mut fmt::Formatter<'_>) -> fmt::Result { + todo!(); + } +} + fn fmt_diff( inserted: &HybridBitSet, removed: &HybridBitSet, diff --git a/compiler/rustc_mir_dataflow/src/framework/lattice.rs b/compiler/rustc_mir_dataflow/src/framework/lattice.rs index d6b89eb82275e..ddddd09e535a8 100644 --- a/compiler/rustc_mir_dataflow/src/framework/lattice.rs +++ b/compiler/rustc_mir_dataflow/src/framework/lattice.rs @@ -250,3 +250,183 @@ impl MeetSemiLattice for FlatSet { true } } + +macro_rules! packed_int_join_semi_lattice { + ($name: ident, $base: ty) => { + #[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)] + pub struct $name($base); + impl $name { + pub const TOP: Self = Self(<$base>::MAX); + // If the value is too large it will be top, which is more conservative and thus + // alright. It is only unsafe to make items bot. + #[inline] + pub const fn new(v: $base) -> Self { + Self(v) + } + + #[inline] + pub fn saturating_new(v: impl TryInto<$base>) -> Self { + v.try_into().map(|v| Self(v)).unwrap_or(Self::TOP) + } + + pub const fn inner(self) -> $base { + self.0 + } + } + + impl JoinSemiLattice for $name { + #[inline] + fn join(&mut self, other: &Self) -> bool { + match (*self, *other) { + (Self::TOP, _) => false, + (a, b) if a == b => false, + _ => { + *self = Self::TOP; + true + } + } + } + } + + impl crate::fmt::DebugWithContext for $name { + fn fmt_with(&self, _: &C, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if *self == Self::TOP { write!(f, "TOP") } else { write!(f, "{}", self.inner()) } + } + } + }; +} + +packed_int_join_semi_lattice!(PackedU8JoinSemiLattice, u8); + +#[derive(Eq, PartialEq, Copy, Clone, Debug)] +pub struct FactArray { + // FIXME(julianknodt): maybe map Idxs to each N element? + pub arr: [T; N], +} + +impl FactArray { + #[inline] + pub fn insert(&mut self, i: impl Idx, fact: T) { + let Some(v) = self.arr.get_mut(i.index()) else { return }; + *v = fact; + } + #[inline] + pub fn get(&self, i: &impl Idx) -> Option<&T> { + self.arr.get(i.index()) + } +} + +impl JoinSemiLattice for FactArray { + fn join(&mut self, other: &Self) -> bool { + let mut changed = false; + for (a, b) in self.arr.iter_mut().zip(other.arr.iter()) { + changed |= a.join(b); + } + changed + } +} + +impl MeetSemiLattice for FactArray { + fn meet(&mut self, other: &Self) -> bool { + let mut changed = false; + for (a, b) in self.arr.iter_mut().zip(other.arr.iter()) { + changed |= a.meet(b); + } + changed + } +} + +#[derive(Eq, PartialEq, Copy, Clone, Debug)] +pub struct FactCache { + facts: [F; N], + ord: [(I, L); N], + len: usize, +} + +impl FactCache { + pub fn new(empty_i: I, empty_l: L, empty_f: F) -> Self + where + F: Copy, + { + Self { facts: [empty_f; N], ord: [(empty_i, empty_l); N], len: 0 } + } + /// inserts a fact into the cache, evicting the oldest one, + /// Or updating it if there is information on one already. If the new fact being + /// inserted is older than the previous fact, it will not be inserted. + pub fn insert(&mut self, i: I, l: L, fact: F) { + let mut idx = None; + for (j, (ci, cl)) in self.ord[..self.len].iter_mut().enumerate() { + if *ci == i { + assert!(*cl <= l); + idx = Some(j); + break; + } + } + if idx.is_none() && self.len < N { + let new_len = self.len + 1; + idx = Some(std::mem::replace(&mut self.len, new_len)); + }; + if let Some(idx) = idx { + self.facts[idx] = fact; + self.ord[idx] = (i, l); + return; + }; + let (p, (_, old_l)) = self.ord.iter().enumerate().min_by_key(|k| k.1.1).unwrap(); + // FIXME(julianknodt) maybe don't make this an assert but just don't update? + assert!(*old_l <= l); + self.ord[p] = (i, l); + self.facts[p] = fact; + } + pub fn get(&self, i: I) -> Option<(&L, &F)> { + let (p, (_, loc)) = + self.ord[..self.len].iter().enumerate().find(|(_, iloc)| iloc.0 == i)?; + Some((loc, &self.facts[p])) + } + pub fn remove(&mut self, i: I) -> bool { + let Some(pos) = self.ord[..self.len].iter().position(|(ci, _)| *ci == i) + else { return false }; + + self.remove_idx(pos); + return true; + } + #[inline] + fn remove_idx(&mut self, i: usize) { + assert!(i < self.len); + self.ord.swap(i, self.len); + self.facts.swap(i, self.len); + self.len -= 1; + } + + fn drain_filter(&mut self, mut should_rm: impl FnMut(&I, &mut L, &mut F) -> bool) { + let mut i = 0; + while i < self.len { + let (idx, l) = &mut self.ord[i]; + let f = &mut self.facts[i]; + if should_rm(idx, l, f) { + self.remove_idx(i); + continue; + } + i += 1; + } + } +} + +impl JoinSemiLattice for FactCache { + fn join(&mut self, other: &Self) -> bool { + let mut changed = false; + self.drain_filter(|i, l, f| { + let Some((other_loc, other_fact)) = other.get(*i) else { + changed = true; + return true; + }; + if other_fact == f { + *l = (*l).max(*other_loc); + return false; + } + changed = true; + return true; + }); + + changed + } +} diff --git a/compiler/rustc_mir_dataflow/src/impls/mod.rs b/compiler/rustc_mir_dataflow/src/impls/mod.rs index af6a1bb1545ea..77f088fd00550 100644 --- a/compiler/rustc_mir_dataflow/src/impls/mod.rs +++ b/compiler/rustc_mir_dataflow/src/impls/mod.rs @@ -21,6 +21,7 @@ use crate::{lattice, AnalysisDomain, GenKill, GenKillAnalysis}; mod borrowed_locals; mod init_locals; mod liveness; +mod single_enum_variant; mod storage_liveness; pub use self::borrowed_locals::borrowed_locals; @@ -28,6 +29,7 @@ pub use self::borrowed_locals::MaybeBorrowedLocals; pub use self::init_locals::MaybeInitializedLocals; pub use self::liveness::MaybeLiveLocals; pub use self::liveness::MaybeTransitiveLiveLocals; +pub use self::single_enum_variant::SingleEnumVariant; pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageLive}; /// `MaybeInitializedPlaces` tracks all places that might be diff --git a/compiler/rustc_mir_dataflow/src/impls/single_enum_variant.rs b/compiler/rustc_mir_dataflow/src/impls/single_enum_variant.rs new file mode 100644 index 0000000000000..ab515f6c1cfee --- /dev/null +++ b/compiler/rustc_mir_dataflow/src/impls/single_enum_variant.rs @@ -0,0 +1,171 @@ +use super::*; +//use crate::lattice::PackedU8JoinSemiLattice as Fact; + +//use crate::lattice::FactArray; +use crate::lattice::FactCache; +use rustc_target::abi::VariantIdx; + +use rustc_middle::mir::*; + +use crate::{Analysis, AnalysisDomain}; + +/// A dataflow analysis that tracks whether an enum can hold 0, 1, or more than one variants. +pub struct SingleEnumVariant<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + body: &'a mir::Body<'tcx>, +} + +impl<'tcx> AnalysisDomain<'tcx> for SingleEnumVariant<'_, 'tcx> { + /// For each local, keep track of which enum index it is, if its uninhabited, or unknown. + //type Domain = FactArray; + type Domain = FactCache; + + const NAME: &'static str = "single_enum_variant"; + + fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain { + //FactArray { arr: [Fact::TOP; 128] } + FactCache::new(Local::from_u32(0), Location::START, VariantIdx::MAX) + } + + fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut Self::Domain) { + // assume everything is top initially. + let local_decls = body.local_decls(); + for (l, _) in local_decls.iter_enumerated() { + state.remove(l); + //state.insert(l, Fact::TOP); + //state[l] = Fact::TOP; + } + } +} + +impl<'tcx> SingleEnumVariant<'_, 'tcx> { + pub fn new<'a>(tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>) -> SingleEnumVariant<'a, 'tcx> { + SingleEnumVariant { tcx, body } + } + #[inline] + pub fn is_tracked(&self, place: &Place<'tcx>) -> bool { + place.ty(self.body, self.tcx).ty.is_enum() + } + fn assign( + &self, + state: &mut >::Domain, + lhs: &Place<'tcx>, + rhs: &Operand<'tcx>, + location: Location, + ) { + let _: Option<_> = try { + if !self.is_tracked(lhs) { + return; + } + let lhs_local = lhs.local_or_deref_local()?; + + let new_fact = match rhs { + Operand::Copy(rhs) | Operand::Move(rhs) => { + if let Some(rhs_local) = rhs.local_or_deref_local() { + state.get(rhs_local).map(|f| f.1).copied() + } else { + rhs.ty(self.body, self.tcx).variant_index.map(|var_idx| var_idx) + } + } + // Assigning a constant does not affect discriminant? + Operand::Constant(_c) => return, + }; + if let Some(new_fact) = new_fact { + state.insert(lhs_local, location, new_fact); + } else { + state.remove(lhs_local); + } + }; + } +} + +impl<'tcx> Analysis<'tcx> for SingleEnumVariant<'_, 'tcx> { + fn apply_statement_effect( + &self, + state: &mut Self::Domain, + statement: &Statement<'tcx>, + loc: Location, + ) { + let (place, fact) = match &statement.kind { + StatementKind::Deinit(box place) => (place, None), + StatementKind::SetDiscriminant { box place, variant_index } => { + (place, Some(*variant_index)) + } + StatementKind::Assign(box (lhs, Rvalue::Use(op))) => { + return self.assign(state, lhs, op, loc); + } + /* may alias/mutate RHS need to specify that it is no longer a single value */ + StatementKind::Assign(box ( + _, + Rvalue::Ref(_, BorrowKind::Mut { .. }, rhs) + | Rvalue::AddressOf(Mutability::Mut, rhs), + )) => (rhs, None), + StatementKind::CopyNonOverlapping(box ref copy) => { + let place = match ©.dst { + Operand::Copy(p) | Operand::Move(p) => p, + _ => return, + }; + (place, None) + } + _ => return, + }; + if !self.is_tracked(place) { + return; + } + let Some(local) = place.local_or_deref_local() else { return }; + if let Some(fact) = fact { + state.insert(local, loc, fact); + } else { + state.remove(local); + } + } + fn apply_terminator_effect( + &self, + state: &mut Self::Domain, + terminator: &Terminator<'tcx>, + loc: Location, + ) { + match &terminator.kind { + TerminatorKind::DropAndReplace { place, value, .. } => { + self.assign(state, place, value, loc) + } + TerminatorKind::Drop { place, .. } if self.is_tracked(place) => { + let Some(local) = place.local_or_deref_local() else { return }; + state.remove(local); + } + _ => {} + } + } + + fn apply_call_return_effect( + &self, + _: &mut Self::Domain, + _: BasicBlock, + _: CallReturnPlaces<'_, 'tcx>, + ) { + } + + fn apply_switch_int_edge_effects( + &self, + _block: BasicBlock, + discr: &Operand<'tcx>, + apply_edge_effects: &mut impl SwitchIntEdgeEffects, + ) { + let Some(place) = discr.place() else { return }; + if !self.is_tracked(&place) { + return; + } + let Some(local) = place.local_or_deref_local() else { return }; + apply_edge_effects.apply(|state, target| { + // This probably isn't right, need to check that it fits. + let new_fact = target.value.map(|v| VariantIdx::from_u32(v as u32)); + + if let Some(new_fact) = new_fact { + let loc = Location { block: target.target, statement_index: 0 }; + state.insert(local, loc, new_fact); + } else { + state.remove(local); + } + }); + } +} diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index e4c130f0807dd..e13ac96b1fb16 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -6,6 +6,7 @@ #![feature(once_cell)] #![feature(stmt_expr_attributes)] #![feature(trusted_step)] +#![feature(try_blocks)] #![recursion_limit = "256"] #[macro_use] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 0887775aae5ed..519e52e9fcf5d 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -82,6 +82,7 @@ mod required_consts; mod reveal_all; mod separate_const_switch; mod shim; +mod single_enum; // This pass is public to allow external drivers to perform MIR cleanup pub mod simplify; mod simplify_branches; @@ -491,6 +492,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // // Const-prop runs unconditionally, but doesn't mutate the MIR at mir-opt-level=0. &const_debuginfo::ConstDebugInfo, + &single_enum::SingleEnum, &o1(simplify_branches::SimplifyConstCondition::new("after-const-prop")), &early_otherwise_branch::EarlyOtherwiseBranch, &simplify_comparison_integral::SimplifyComparisonIntegral, diff --git a/compiler/rustc_mir_transform/src/single_enum.rs b/compiler/rustc_mir_transform/src/single_enum.rs new file mode 100644 index 0000000000000..1b6e781e75f42 --- /dev/null +++ b/compiler/rustc_mir_transform/src/single_enum.rs @@ -0,0 +1,59 @@ +use rustc_middle::mir::interpret::Scalar; +use rustc_middle::mir::*; +use rustc_middle::ty::{ParamEnv, TyCtxt}; +use rustc_mir_dataflow::impls::SingleEnumVariant; +use rustc_mir_dataflow::Analysis; +use rustc_span::DUMMY_SP; + +use crate::MirPass; + +pub struct SingleEnum; + +impl<'tcx> MirPass<'tcx> for SingleEnum { + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let mut single_enum_variants = SingleEnumVariant::new(tcx, body) + .into_engine(tcx, body) + .iterate_to_fixpoint() + .into_results_cursor(body); + + let mut discrs = vec![]; + + for (bb, block) in body.basic_blocks().iter_enumerated() { + for (i, stmt) in block.statements.iter().enumerate() { + let stmt_loc = Location { block: bb.clone(), statement_index: i }; + let StatementKind::Assign(box(_, Rvalue::Discriminant(src))) = stmt.kind + else { continue }; + if !src.ty(body, tcx).ty.is_enum() { + continue; + } + let Some(src_local) = src.local_or_deref_local() else { continue }; + + single_enum_variants.seek_before_primary_effect(stmt_loc); + match single_enum_variants.get().get(src_local) { + None => {} + Some((_, &v)) => discrs.push((stmt_loc, v)), + }; + } + } + + for (Location { block, statement_index }, val) in discrs { + let (bbs, local_decls) = &mut body.basic_blocks_and_local_decls_mut(); + let stmt = &mut bbs[block].statements[statement_index]; + let Some((lhs, rval)) = stmt.kind.as_assign_mut() else { unreachable!() }; + let Rvalue::Discriminant(rhs) = rval else { unreachable!() }; + + let Some(disc) = rhs.ty(*local_decls, tcx).ty.discriminant_for_variant(tcx, val) + else { continue }; + + let scalar_ty = lhs.ty(*local_decls, tcx).ty; + let layout = tcx.layout_of(ParamEnv::empty().and(scalar_ty)).unwrap().layout; + let ct = Operand::const_from_scalar( + tcx, + scalar_ty, + Scalar::from_uint(disc.val, layout.size()), + DUMMY_SP, + ); + *rval = Rvalue::Use(ct); + } + } +} diff --git a/src/test/mir-opt/enum_prop.main.SingleEnum.diff b/src/test/mir-opt/enum_prop.main.SingleEnum.diff new file mode 100644 index 0000000000000..3cad6799938e8 --- /dev/null +++ b/src/test/mir-opt/enum_prop.main.SingleEnum.diff @@ -0,0 +1,475 @@ +- // MIR for `main` before SingleEnum ++ // MIR for `main` after SingleEnum + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/enum_prop.rs:3:11: 3:11 + let _1: i32; // in scope 0 at $DIR/enum_prop.rs:4:7: 4:8 + let mut _2: std::option::Option>; // in scope 0 at $DIR/enum_prop.rs:4:17: 4:35 + let mut _3: std::boxed::Box; // in scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + let mut _4: isize; // in scope 0 at $DIR/enum_prop.rs:5:5: 5:12 + let _5: std::boxed::Box; // in scope 0 at $DIR/enum_prop.rs:5:10: 5:11 + let _6: (); // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let _7: (); // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _8: std::fmt::Arguments; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _9: &[&str]; // in scope 0 at $DIR/enum_prop.rs:6:16: 6:20 + let mut _10: &[&str; 2]; // in scope 0 at $DIR/enum_prop.rs:6:16: 6:20 + let _11: &[&str; 2]; // in scope 0 at $DIR/enum_prop.rs:6:16: 6:20 + let _12: [&str; 2]; // in scope 0 at $DIR/enum_prop.rs:6:16: 6:20 + let mut _13: &[std::fmt::ArgumentV1]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _14: &[std::fmt::ArgumentV1; 1]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let _15: &[std::fmt::ArgumentV1; 1]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let _16: [std::fmt::ArgumentV1; 1]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL + let mut _17: std::fmt::ArgumentV1; // in scope 0 at $DIR/enum_prop.rs:6:22: 6:23 + let mut _18: &std::boxed::Box; // in scope 0 at $DIR/enum_prop.rs:6:22: 6:23 + let _19: &std::boxed::Box; // in scope 0 at $DIR/enum_prop.rs:6:22: 6:23 + let _20: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _21: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _22: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _23: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _24: i32; // in scope 0 at $DIR/enum_prop.rs:11:16: 11:18 + let mut _27: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _28: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _29: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _30: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _31: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _33: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _34: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _35: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _36: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _37: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _38: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _39: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _41: std::option::Option; // in scope 0 at $DIR/enum_prop.rs:14:17: 14:24 + let mut _42: isize; // in scope 0 at $DIR/enum_prop.rs:15:14: 15:21 + let _44: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _45: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _46: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _47: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _48: i32; // in scope 0 at $DIR/enum_prop.rs:18:17: 18:18 + let mut _51: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _52: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _53: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _54: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _55: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _57: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _58: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _59: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _60: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _61: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _62: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _63: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _68: bool; // in scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + let mut _69: isize; // in scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + let mut _70: isize; // in scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + let mut _71: isize; // in scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + let mut _72: i32; // in scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + scope 1 { + debug v => _1; // in scope 1 at $DIR/enum_prop.rs:4:7: 4:8 + let _25: &i32; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _26: &i32; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _40: i32; // in scope 1 at $DIR/enum_prop.rs:14:7: 14:8 + let _43: &std::option::Option; // in scope 1 at $DIR/enum_prop.rs:15:5: 15:21 + let mut _65: &std::option::Option; // in scope 1 at $DIR/enum_prop.rs:15:5: 15:21 + let mut _66: &i32; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 3 { + debug left_val => _25; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _26; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _32: core::panicking::AssertKind; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 4 { + debug kind => _32; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + } + scope 5 { + debug x => _40; // in scope 5 at $DIR/enum_prop.rs:14:7: 14:8 + let _49: &i32; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _50: &i32; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _64: &i32; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 7 { + debug left_val => _49; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _50; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _56: core::panicking::AssertKind; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + scope 8 { + debug kind => _56; // in scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + } + } + scope 6 { + debug _y => _43; // in scope 6 at $DIR/enum_prop.rs:15:5: 15:21 + } + } + scope 2 { + debug x => _5; // in scope 2 at $DIR/enum_prop.rs:5:10: 5:11 + let mut _67: &[&str; 2]; // in scope 2 at $DIR/enum_prop.rs:6:16: 6:20 + scope 11 (inlined ArgumentV1::new_display::>) { // at $DIR/enum_prop.rs:6:22: 6:23 + debug x => _18; // in scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _76: &std::boxed::Box; // in scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _77: for<'r, 's, 't0> fn(&'r std::boxed::Box, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + scope 12 (inlined ArgumentV1::new::>) { // at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + debug x => _76; // in scope 12 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + debug f => _77; // in scope 12 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _78: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 12 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _79: for<'r, 's, 't0> fn(&'r std::boxed::Box, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 12 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _80: &core::fmt::Opaque; // in scope 12 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + let mut _81: &std::boxed::Box; // in scope 12 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + scope 13 { + } + } + } + } + scope 9 (inlined Box::::new) { // at $DIR/enum_prop.rs:4:22: 4:34 + debug x => _72; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _73: usize; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _74: usize; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _75: *mut u8; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + scope 10 { + } + } + + bb0: { + _68 = const false; // scope 0 at $DIR/enum_prop.rs:4:7: 4:8 + StorageLive(_1); // scope 0 at $DIR/enum_prop.rs:4:7: 4:8 + StorageLive(_2); // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 + StorageLive(_3); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageLive(_72); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + _72 = const 10_i32; // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageLive(_73); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageLive(_74); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageLive(_75); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + _73 = const 4_usize; // scope 10 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _74 = const 4_usize; // scope 10 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _75 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> [return: bb20, unwind: bb21]; // scope 10 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/alloc/src/boxed.rs:LL:COL + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar()) } + } + + bb1: { + _1 = const 3_i32; // scope 0 at $DIR/enum_prop.rs:9:10: 9:11 + goto -> bb18; // scope 0 at $DIR/enum_prop.rs:9:10: 9:11 + } + + bb2: { + StorageLive(_5); // scope 0 at $DIR/enum_prop.rs:5:10: 5:11 + _68 = const false; // scope 0 at $DIR/enum_prop.rs:5:10: 5:11 + _5 = move ((_2 as Some).0: std::boxed::Box); // scope 0 at $DIR/enum_prop.rs:5:10: 5:11 + StorageLive(_6); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageLive(_7); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageLive(_8); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageLive(_9); // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 + StorageLive(_10); // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 + StorageLive(_11); // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 + _67 = const main::promoted[3]; // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 + // mir::Constant + // + span: $DIR/enum_prop.rs:6:16: 6:20 + // + literal: Const { ty: &[&str; 2], val: Unevaluated(main, [], Some(promoted[3])) } + _11 = _67; // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 + _10 = _11; // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 + _9 = move _10 as &[&str] (Pointer(Unsize)); // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 + StorageDead(_10); // scope 2 at $DIR/enum_prop.rs:6:19: 6:20 + StorageLive(_13); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageLive(_14); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageLive(_15); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageLive(_16); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageLive(_17); // scope 2 at $DIR/enum_prop.rs:6:22: 6:23 + StorageLive(_18); // scope 2 at $DIR/enum_prop.rs:6:22: 6:23 + StorageLive(_19); // scope 2 at $DIR/enum_prop.rs:6:22: 6:23 + _19 = &_5; // scope 2 at $DIR/enum_prop.rs:6:22: 6:23 + _18 = _19; // scope 2 at $DIR/enum_prop.rs:6:22: 6:23 + StorageLive(_76); // scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _76 = _18; // scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_77); // scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _77 = as std::fmt::Display>::fmt as for<'r, 's, 't0> fn(&'r std::boxed::Box, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer)); // scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL + // + literal: Const { ty: for<'r, 's, 't0> fn(&'r Box, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error> { as std::fmt::Display>::fmt}, val: Value(Scalar()) } + StorageLive(_78); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_79); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _79 = _77; // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _78 = transmute:: fn(&'r Box, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error>>(move _79) -> [return: bb22, unwind: bb13]; // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(for<'r, 's, 't0> fn(&'r Box, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error>) -> for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error> {transmute:: fn(&'r Box, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error>>}, val: Value(Scalar()) } + } + + bb3: { + StorageDead(_13); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_9); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + _7 = _print(move _8) -> [return: bb4, unwind: bb13]; // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/std/src/macros.rs:LL:COL + // + literal: Const { ty: for<'r> fn(Arguments<'r>) {_print}, val: Value(Scalar()) } + } + + bb4: { + StorageDead(_8); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_19); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_16); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_15); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_11); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_7); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_6); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + _1 = (*_5); // scope 2 at $DIR/enum_prop.rs:7:7: 7:9 + drop(_5) -> [return: bb5, unwind: bb19]; // scope 0 at $DIR/enum_prop.rs:8:5: 8:6 + } + + bb5: { + StorageDead(_5); // scope 0 at $DIR/enum_prop.rs:8:5: 8:6 + goto -> bb18; // scope 0 at $DIR/enum_prop.rs:8:5: 8:6 + } + + bb6: { + StorageLive(_32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_32) = 0; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_33); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_34); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _34 = const core::panicking::AssertKind::Eq; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } + StorageLive(_35); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_36); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _36 = _25; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _35 = _36; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_37); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_38); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _38 = _26; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _37 = _38; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_39); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_39); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_39) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _33 = core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _35, move _37, move _39); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option>) -> ! {core::panicking::assert_failed::}, val: Value(Scalar()) } + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } + } + + bb7: { + StorageDead(_27); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_26); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_25); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_21); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_20); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_40); // scope 1 at $DIR/enum_prop.rs:14:7: 14:8 + StorageLive(_41); // scope 1 at $DIR/enum_prop.rs:14:17: 14:24 + Deinit(_41); // scope 1 at $DIR/enum_prop.rs:14:17: 14:24 + ((_41 as Some).0: i32) = const 1_i32; // scope 1 at $DIR/enum_prop.rs:14:17: 14:24 + discriminant(_41) = 1; // scope 1 at $DIR/enum_prop.rs:14:17: 14:24 + _42 = const 1_isize; // scope 1 at $DIR/enum_prop.rs:14:17: 14:24 + switchInt(const 1_isize) -> [0_isize: bb8, otherwise: bb9]; // scope 1 at $DIR/enum_prop.rs:14:11: 14:24 + } + + bb8: { + _40 = const 2_i32; // scope 1 at $DIR/enum_prop.rs:16:13: 16:14 + goto -> bb10; // scope 1 at $DIR/enum_prop.rs:16:13: 16:14 + } + + bb9: { + StorageLive(_43); // scope 1 at $DIR/enum_prop.rs:15:5: 15:21 + _65 = const main::promoted[1]; // scope 1 at $DIR/enum_prop.rs:15:5: 15:21 + // mir::Constant + // + span: $DIR/enum_prop.rs:15:5: 15:21 + // + literal: Const { ty: &Option, val: Unevaluated(main, [], Some(promoted[1])) } + _43 = _65; // scope 1 at $DIR/enum_prop.rs:15:5: 15:21 + _40 = const 1_i32; // scope 6 at $DIR/enum_prop.rs:15:25: 15:26 + StorageDead(_43); // scope 1 at $DIR/enum_prop.rs:15:25: 15:26 + goto -> bb10; // scope 1 at $DIR/enum_prop.rs:15:25: 15:26 + } + + bb10: { + StorageDead(_41); // scope 1 at $DIR/enum_prop.rs:17:4: 17:5 + StorageLive(_44); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_45); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_46); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _46 = &_40; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_47); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _64 = const main::promoted[0]; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } + _47 = _64; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_45); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_45.0: &i32) = move _46; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_45.1: &i32) = move _47; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_47); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_46); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_49); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _49 = (_45.0: &i32); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_50); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _50 = (_45.1: &i32); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_51); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_52); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_53); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _53 = (*_49); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_54); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _54 = const 1_i32; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _52 = Eq(move _53, const 1_i32); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_54); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_53); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _51 = Not(move _52); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_52); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _51) -> [false: bb12, otherwise: bb11]; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb11: { + StorageLive(_56); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_56); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_56) = 0; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_57); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_58); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _58 = const core::panicking::AssertKind::Eq; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } + StorageLive(_59); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_60); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _60 = _49; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _59 = _60; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_61); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_62); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _62 = _50; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _61 = _62; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_63); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_63); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_63) = 0; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _57 = core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _59, move _61, move _63); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option>) -> ! {core::panicking::assert_failed::}, val: Value(Scalar()) } + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } + } + + bb12: { + StorageDead(_51); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_50); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_49); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_45); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_44); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_40); // scope 1 at $DIR/enum_prop.rs:20:1: 20:2 + StorageDead(_1); // scope 0 at $DIR/enum_prop.rs:20:1: 20:2 + return; // scope 0 at $DIR/enum_prop.rs:20:2: 20:2 + } + + bb13 (cleanup): { + drop(_5) -> bb19; // scope 0 at $DIR/enum_prop.rs:8:5: 8:6 + } + + bb14 (cleanup): { + resume; // scope 0 at $DIR/enum_prop.rs:3:1: 20:2 + } + + bb15: { + _68 = const false; // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + StorageDead(_2); // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + StorageLive(_20); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_21); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_22); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _22 = &_1; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_23); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _66 = const main::promoted[2]; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[2])) } + _23 = _66; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_21); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_21.0: &i32) = move _22; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_21.1: &i32) = move _23; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_23); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_22); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_25); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _25 = (_21.0: &i32); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_26); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _26 = (_21.1: &i32); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_27); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_28); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_29); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _29 = (*_25); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_30); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _30 = const 10_i32; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _28 = Eq(move _29, const 10_i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_30); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_29); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _27 = Not(move _28); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_28); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _27) -> [false: bb7, otherwise: bb6]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb16: { + switchInt(_68) -> [false: bb15, otherwise: bb17]; // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + } + + bb17: { + drop(((_2 as Some).0: std::boxed::Box)) -> [return: bb15, unwind: bb14]; // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + } + + bb18: { + _69 = discriminant(_2); // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + switchInt(move _69) -> [1_isize: bb16, otherwise: bb15]; // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + } + + bb19 (cleanup): { + _71 = discriminant(_2); // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + goto -> bb14; // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + } + + bb20: { + _3 = ShallowInitBox(move _75, i32); // scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + (*_3) = const 10_i32; // scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_75); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageDead(_74); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageDead(_73); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageDead(_72); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + _68 = const true; // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 + Deinit(_2); // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 + ((_2 as Some).0: std::boxed::Box) = move _3; // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 + discriminant(_2) = 1; // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 + StorageDead(_3); // scope 0 at $DIR/enum_prop.rs:4:34: 4:35 +- _4 = discriminant(_2); // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 ++ _4 = const 1_isize; // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 + switchInt(move _4) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/enum_prop.rs:4:11: 4:35 + } + + bb21 (cleanup): { + resume; // scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + } + + bb22: { + StorageDead(_79); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_80); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageLive(_81); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _81 = _76; // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + _80 = transmute::<&Box, &core::fmt::Opaque>(move _81) -> [return: bb23, unwind: bb13]; // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&Box) -> &core::fmt::Opaque {transmute::<&Box, &core::fmt::Opaque>}, val: Value(Scalar()) } + } + + bb23: { + StorageDead(_81); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + Deinit(_17); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_17.0: &core::fmt::Opaque) = move _80; // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + (_17.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _78; // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_80); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_78); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_77); // scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_76); // scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL + StorageDead(_18); // scope 2 at $DIR/enum_prop.rs:6:22: 6:23 + _16 = [move _17]; // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_17); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + _15 = &_16; // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + _14 = _15; // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + _13 = move _14 as &[std::fmt::ArgumentV1] (Pointer(Unsize)); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + StorageDead(_14); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + _8 = Arguments::new_v1(move _9, move _13) -> [return: bb3, unwind: bb13]; // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/std/src/macros.rs:LL:COL + // + user_ty: UserType(1) + // + literal: Const { ty: fn(&[&'static str], &[ArgumentV1]) -> Arguments {Arguments::new_v1}, val: Value(Scalar()) } + } + } + diff --git a/src/test/mir-opt/enum_prop.rs b/src/test/mir-opt/enum_prop.rs new file mode 100644 index 0000000000000..7c7aa8333bf03 --- /dev/null +++ b/src/test/mir-opt/enum_prop.rs @@ -0,0 +1,20 @@ +// EMIT_MIR enum_prop.main.SingleEnum.diff + +fn main() { + let v = match Some(Box::new(10)) { + Some(x) => { + println!("{}", x); + *x + }, + _ => 3, + }; + assert_eq!(v,10); + + + let x = match Some(1) { + ref _y @ Some(_) => 1, + None => 2, + }; + assert_eq!(x, 1); + +} diff --git a/src/test/ui/drop/issue-90752.rs b/src/test/ui/drop/issue-90752.rs index 4395e45e7733a..d1e9742867ab1 100644 --- a/src/test/ui/drop/issue-90752.rs +++ b/src/test/ui/drop/issue-90752.rs @@ -14,14 +14,14 @@ fn test(drops: &RefCell>) { let mut foo = None; match foo { None => (), - _ => return, + _ => panic!(), } *(&mut foo) = Some((S(0, drops), S(1, drops))); // Both S(0) and S(1) should be dropped match foo { Some((_x, _)) => {} - _ => {} + _ => panic!("Should not match"), } } diff --git a/src/test/ui/let-else/let-else-run-pass.rs b/src/test/ui/let-else/let-else-run-pass.rs index 5d96623236dab..187a23a76a866 100644 --- a/src/test/ui/let-else/let-else-run-pass.rs +++ b/src/test/ui/let-else/let-else-run-pass.rs @@ -11,7 +11,7 @@ fn main() { } // ref binding to non-copy value and or-pattern let (MyEnum::A(ref x) | MyEnum::B { f: ref x }) = (MyEnum::B { f: String::new() }) else { - panic!(); + panic!("Shouldn't have matched enum"); }; assert_eq!(x, ""); @@ -25,11 +25,11 @@ fn main() { }; break; }; - panic!(); + panic!("Shouldn't have matched int"); } assert_eq!(x, 3); // else return let Some(1) = Some(2) else { return }; - panic!(); + panic!("Shouldn't have matched"); } From cd37d5c2b38054c1a3fa2d768492ed5bb8e567ce Mon Sep 17 00:00:00 2001 From: kadmin Date: Sun, 10 Jul 2022 22:46:13 +0000 Subject: [PATCH 2/2] Update with PR comments (+docs, +fixes) Add many of the additional lattice methods with comments, as well as clean up some issues which did not appear in the tests (i.e. SwitchIntEdgeEffect). --- .../src/framework/lattice.rs | 23 +- .../src/impls/single_enum_variant.rs | 83 ++- .../rustc_mir_transform/src/single_enum.rs | 8 +- .../mir-opt/enum_prop.main.SingleEnum.diff | 599 +++++++----------- src/test/mir-opt/enum_prop.rs | 1 - 5 files changed, 329 insertions(+), 385 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/framework/lattice.rs b/compiler/rustc_mir_dataflow/src/framework/lattice.rs index ddddd09e535a8..0a13ae32f0b9b 100644 --- a/compiler/rustc_mir_dataflow/src/framework/lattice.rs +++ b/compiler/rustc_mir_dataflow/src/framework/lattice.rs @@ -257,13 +257,16 @@ macro_rules! packed_int_join_semi_lattice { pub struct $name($base); impl $name { pub const TOP: Self = Self(<$base>::MAX); - // If the value is too large it will be top, which is more conservative and thus - // alright. It is only unsafe to make items bot. #[inline] pub const fn new(v: $base) -> Self { Self(v) } + /// `saturating_new` will convert an arbitrary value (i.e. u32) into a Fact which + /// may have a smaller internal representation (i.e. u8). If the value is too large, + /// it will be converted to `TOP`, which is safe because `TOP` is the most + /// conservative estimate, assuming no information. Note, it is _not_ safe to + /// assume `BOT`, since this assumes information about the value. #[inline] pub fn saturating_new(v: impl TryInto<$base>) -> Self { v.try_into().map(|v| Self(v)).unwrap_or(Self::TOP) @@ -336,6 +339,14 @@ impl MeetSemiLattice for FactArray { } } +/// FactCache is a struct that contains `N` recent facts (of type F) from dataflow analysis, +/// where a fact is information about some component of a program, such as the possible values a +/// variable can take. Variables are indexed by `I: Idx` (i.e. mir::Local), and `L` represents +/// location/recency, so that when merging two fact caches, the more recent information takes +/// precedence. +/// This representation is used because it takes constant memory, and assumes that recent facts +/// will have temporal locality (i.e. will be used closed to where they are generated). Thus, it +/// is more conservative than a complete analysis, but should be fast. #[derive(Eq, PartialEq, Copy, Clone, Debug)] pub struct FactCache { facts: [F; N], @@ -350,14 +361,16 @@ impl FactCache { { Self { facts: [empty_f; N], ord: [(empty_i, empty_l); N], len: 0 } } - /// inserts a fact into the cache, evicting the oldest one, + /// (nserts a fact into the cache, evicting the oldest one, /// Or updating it if there is information on one already. If the new fact being /// inserted is older than the previous fact, it will not be inserted. pub fn insert(&mut self, i: I, l: L, fact: F) { let mut idx = None; - for (j, (ci, cl)) in self.ord[..self.len].iter_mut().enumerate() { + for (j, (ci, _cl)) in self.ord[..self.len].iter_mut().enumerate() { if *ci == i { - assert!(*cl <= l); + // if an older fact is inserted, still update the cache: i.e. cl <= l usually + // but this is broken during apply switch int edge effects, because the engine + // may choose an arbitrary order for basic blocks to apply it to. idx = Some(j); break; } diff --git a/compiler/rustc_mir_dataflow/src/impls/single_enum_variant.rs b/compiler/rustc_mir_dataflow/src/impls/single_enum_variant.rs index ab515f6c1cfee..a23badf4a3444 100644 --- a/compiler/rustc_mir_dataflow/src/impls/single_enum_variant.rs +++ b/compiler/rustc_mir_dataflow/src/impls/single_enum_variant.rs @@ -9,7 +9,13 @@ use rustc_middle::mir::*; use crate::{Analysis, AnalysisDomain}; -/// A dataflow analysis that tracks whether an enum can hold 0, 1, or more than one variants. +/// A dataflow analysis that tracks whether an enum can hold exactly 1, or more than 1 variants. +/// +/// Specifically, if a local is constructed with a value of `Some(1)`, +/// We should be able to optimize it under the assumption that it has the `Some` variant. +/// If a local can be multiple variants, then we assume nothing. +/// This analysis returns whether or not an enum will have a specific discriminant +/// at a given time, associating that local with exactly the 1 discriminant it is. pub struct SingleEnumVariant<'a, 'tcx> { tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>, @@ -17,23 +23,19 @@ pub struct SingleEnumVariant<'a, 'tcx> { impl<'tcx> AnalysisDomain<'tcx> for SingleEnumVariant<'_, 'tcx> { /// For each local, keep track of which enum index it is, if its uninhabited, or unknown. - //type Domain = FactArray; type Domain = FactCache; const NAME: &'static str = "single_enum_variant"; fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain { - //FactArray { arr: [Fact::TOP; 128] } FactCache::new(Local::from_u32(0), Location::START, VariantIdx::MAX) } fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut Self::Domain) { - // assume everything is top initially. + // assume everything is TOP initially (i.e. it can be any variant). let local_decls = body.local_decls(); for (l, _) in local_decls.iter_enumerated() { state.remove(l); - //state.insert(l, Fact::TOP); - //state[l] = Fact::TOP; } } } @@ -57,18 +59,26 @@ impl<'tcx> SingleEnumVariant<'_, 'tcx> { if !self.is_tracked(lhs) { return; } - let lhs_local = lhs.local_or_deref_local()?; + let lhs_local = lhs.as_local()?; let new_fact = match rhs { Operand::Copy(rhs) | Operand::Move(rhs) => { - if let Some(rhs_local) = rhs.local_or_deref_local() { + if let Some(rhs_local) = rhs.as_local() { state.get(rhs_local).map(|f| f.1).copied() } else { - rhs.ty(self.body, self.tcx).variant_index.map(|var_idx| var_idx) + debug_assert!( + rhs.ty(self.body, self.tcx) + .variant_index + .map(|var_idx| var_idx) + .is_none() + ); + None } } - // Assigning a constant does not affect discriminant? - Operand::Constant(_c) => return, + // For now, assume that assigning a constant removes known facts. + // More conservative than necessary, but a temp placeholder, + // rather than extracting an enum variant from a constant. + Operand::Constant(_c) => None, }; if let Some(new_fact) = new_fact { state.insert(lhs_local, location, new_fact); @@ -86,6 +96,9 @@ impl<'tcx> Analysis<'tcx> for SingleEnumVariant<'_, 'tcx> { statement: &Statement<'tcx>, loc: Location, ) { + // (place = location which has new information, + // fact = None if we no longer know what variant a value has + // OR fact = Some(var_idx) if we know what variant a value has). let (place, fact) = match &statement.kind { StatementKind::Deinit(box place) => (place, None), StatementKind::SetDiscriminant { box place, variant_index } => { @@ -112,7 +125,7 @@ impl<'tcx> Analysis<'tcx> for SingleEnumVariant<'_, 'tcx> { if !self.is_tracked(place) { return; } - let Some(local) = place.local_or_deref_local() else { return }; + let Some(local) = place.as_local() else { return }; if let Some(fact) = fact { state.insert(local, loc, fact); } else { @@ -130,7 +143,7 @@ impl<'tcx> Analysis<'tcx> for SingleEnumVariant<'_, 'tcx> { self.assign(state, place, value, loc) } TerminatorKind::Drop { place, .. } if self.is_tracked(place) => { - let Some(local) = place.local_or_deref_local() else { return }; + let Some(local) = place.as_local() else { return }; state.remove(local); } _ => {} @@ -147,18 +160,50 @@ impl<'tcx> Analysis<'tcx> for SingleEnumVariant<'_, 'tcx> { fn apply_switch_int_edge_effects( &self, - _block: BasicBlock, + from_block: BasicBlock, discr: &Operand<'tcx>, apply_edge_effects: &mut impl SwitchIntEdgeEffects, ) { - let Some(place) = discr.place() else { return }; - if !self.is_tracked(&place) { + let Some(switch_on) = discr.place() else { return }; + + let mut src_place = None; + let mut adt_def = None; + for stmt in self.body[from_block].statements.iter().rev() { + match stmt.kind { + StatementKind::Assign(box (lhs, Rvalue::Discriminant(disc))) + if lhs == switch_on => + { + match disc.ty(self.body, self.tcx).ty.kind() { + ty::Adt(adt, _) => { + src_place = Some(disc); + adt_def = Some(adt); + break; + } + + // `Rvalue::Discriminant` is also used to get the active yield point for a + // generator, but we do not need edge-specific effects in that case. This may + // change in the future. + ty::Generator(..) => return, + + t => bug!("`discriminant` called on unexpected type {:?}", t), + } + } + StatementKind::Coverage(_) => continue, + _ => return, + }; + } + + let Some(src_place) = src_place else { return }; + let Some(adt_def) = adt_def else { return }; + if !self.is_tracked(&src_place) { return; } - let Some(local) = place.local_or_deref_local() else { return }; + let Some(local) = src_place.as_local() else { return }; + apply_edge_effects.apply(|state, target| { - // This probably isn't right, need to check that it fits. - let new_fact = target.value.map(|v| VariantIdx::from_u32(v as u32)); + let new_fact = target.value.and_then(|discr| { + adt_def.discriminants(self.tcx).find(|(_, d)| d.val == discr).map(|(vi, _)| vi) + }); if let Some(new_fact) = new_fact { let loc = Location { block: target.target, statement_index: 0 }; diff --git a/compiler/rustc_mir_transform/src/single_enum.rs b/compiler/rustc_mir_transform/src/single_enum.rs index 1b6e781e75f42..d0943c1e2532f 100644 --- a/compiler/rustc_mir_transform/src/single_enum.rs +++ b/compiler/rustc_mir_transform/src/single_enum.rs @@ -37,15 +37,17 @@ impl<'tcx> MirPass<'tcx> for SingleEnum { } for (Location { block, statement_index }, val) in discrs { - let (bbs, local_decls) = &mut body.basic_blocks_and_local_decls_mut(); + let local_decls = &body.local_decls; + let bbs = body.basic_blocks.as_mut(); + let stmt = &mut bbs[block].statements[statement_index]; let Some((lhs, rval)) = stmt.kind.as_assign_mut() else { unreachable!() }; let Rvalue::Discriminant(rhs) = rval else { unreachable!() }; - let Some(disc) = rhs.ty(*local_decls, tcx).ty.discriminant_for_variant(tcx, val) + let Some(disc) = rhs.ty(local_decls, tcx).ty.discriminant_for_variant(tcx, val) else { continue }; - let scalar_ty = lhs.ty(*local_decls, tcx).ty; + let scalar_ty = lhs.ty(local_decls, tcx).ty; let layout = tcx.layout_of(ParamEnv::empty().and(scalar_ty)).unwrap().layout; let ct = Operand::const_from_scalar( tcx, diff --git a/src/test/mir-opt/enum_prop.main.SingleEnum.diff b/src/test/mir-opt/enum_prop.main.SingleEnum.diff index 3cad6799938e8..c19488493e298 100644 --- a/src/test/mir-opt/enum_prop.main.SingleEnum.diff +++ b/src/test/mir-opt/enum_prop.main.SingleEnum.diff @@ -8,423 +8,342 @@ let mut _3: std::boxed::Box; // in scope 0 at $DIR/enum_prop.rs:4:22: 4:34 let mut _4: isize; // in scope 0 at $DIR/enum_prop.rs:5:5: 5:12 let _5: std::boxed::Box; // in scope 0 at $DIR/enum_prop.rs:5:10: 5:11 - let _6: (); // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let _7: (); // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _8: std::fmt::Arguments; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _9: &[&str]; // in scope 0 at $DIR/enum_prop.rs:6:16: 6:20 - let mut _10: &[&str; 2]; // in scope 0 at $DIR/enum_prop.rs:6:16: 6:20 - let _11: &[&str; 2]; // in scope 0 at $DIR/enum_prop.rs:6:16: 6:20 - let _12: [&str; 2]; // in scope 0 at $DIR/enum_prop.rs:6:16: 6:20 - let mut _13: &[std::fmt::ArgumentV1]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _14: &[std::fmt::ArgumentV1; 1]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let _15: &[std::fmt::ArgumentV1; 1]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let _16: [std::fmt::ArgumentV1; 1]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _17: std::fmt::ArgumentV1; // in scope 0 at $DIR/enum_prop.rs:6:22: 6:23 - let mut _18: &std::boxed::Box; // in scope 0 at $DIR/enum_prop.rs:6:22: 6:23 - let _19: &std::boxed::Box; // in scope 0 at $DIR/enum_prop.rs:6:22: 6:23 - let _20: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _21: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _22: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _6: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _7: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _8: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _9: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _10: i32; // in scope 0 at $DIR/enum_prop.rs:10:16: 10:18 + let mut _13: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _14: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _15: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _16: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _17: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _19: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _20: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _21: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _22: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _23: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _24: i32; // in scope 0 at $DIR/enum_prop.rs:11:16: 11:18 - let mut _27: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _28: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _29: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _30: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _31: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _33: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _34: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _35: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _36: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _37: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _38: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _39: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _41: std::option::Option; // in scope 0 at $DIR/enum_prop.rs:14:17: 14:24 - let mut _42: isize; // in scope 0 at $DIR/enum_prop.rs:15:14: 15:21 - let _44: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _45: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _46: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _24: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _25: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _27: std::option::Option; // in scope 0 at $DIR/enum_prop.rs:13:17: 13:24 + let mut _28: isize; // in scope 0 at $DIR/enum_prop.rs:14:14: 14:21 + let _30: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _31: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _32: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _33: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _34: i32; // in scope 0 at $DIR/enum_prop.rs:17:17: 17:18 + let mut _37: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _38: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _39: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _40: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _41: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _43: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _44: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _45: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _46: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _47: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _48: i32; // in scope 0 at $DIR/enum_prop.rs:18:17: 18:18 - let mut _51: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _52: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _53: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _54: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _55: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _57: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _58: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _59: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _60: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _61: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _62: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _63: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _68: bool; // in scope 0 at $DIR/enum_prop.rs:10:4: 10:5 - let mut _69: isize; // in scope 0 at $DIR/enum_prop.rs:10:4: 10:5 - let mut _70: isize; // in scope 0 at $DIR/enum_prop.rs:10:4: 10:5 - let mut _71: isize; // in scope 0 at $DIR/enum_prop.rs:10:4: 10:5 - let mut _72: i32; // in scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + let _48: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _49: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _53: bool; // in scope 0 at $DIR/enum_prop.rs:9:4: 9:5 + let mut _54: isize; // in scope 0 at $DIR/enum_prop.rs:9:4: 9:5 + let mut _55: isize; // in scope 0 at $DIR/enum_prop.rs:9:4: 9:5 + let mut _56: isize; // in scope 0 at $DIR/enum_prop.rs:9:4: 9:5 + let mut _57: *const i32; // in scope 0 at $DIR/enum_prop.rs:5:10: 5:11 + let mut _58: *const i32; // in scope 0 at $DIR/enum_prop.rs:5:10: 5:11 + let mut _59: i32; // in scope 0 at $DIR/enum_prop.rs:4:22: 4:34 scope 1 { debug v => _1; // in scope 1 at $DIR/enum_prop.rs:4:7: 4:8 - let _25: &i32; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _26: &i32; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _40: i32; // in scope 1 at $DIR/enum_prop.rs:14:7: 14:8 - let _43: &std::option::Option; // in scope 1 at $DIR/enum_prop.rs:15:5: 15:21 - let mut _65: &std::option::Option; // in scope 1 at $DIR/enum_prop.rs:15:5: 15:21 - let mut _66: &i32; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _11: &i32; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _12: &i32; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _26: i32; // in scope 1 at $DIR/enum_prop.rs:13:7: 13:8 + let _29: &std::option::Option; // in scope 1 at $DIR/enum_prop.rs:14:5: 14:21 + let mut _51: &std::option::Option; // in scope 1 at $DIR/enum_prop.rs:14:5: 14:21 + let mut _52: &i32; // in scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 3 { - debug left_val => _25; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - debug right_val => _26; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _32: core::panicking::AssertKind; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug left_val => _11; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _12; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _18: core::panicking::AssertKind; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 4 { - debug kind => _32; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug kind => _18; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } } scope 5 { - debug x => _40; // in scope 5 at $DIR/enum_prop.rs:14:7: 14:8 - let _49: &i32; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _50: &i32; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _64: &i32; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug x => _26; // in scope 5 at $DIR/enum_prop.rs:13:7: 13:8 + let _35: &i32; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _36: &i32; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _50: &i32; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 7 { - debug left_val => _49; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - debug right_val => _50; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _56: core::panicking::AssertKind; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug left_val => _35; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _36; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _42: core::panicking::AssertKind; // in scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 8 { - debug kind => _56; // in scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug kind => _42; // in scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } } } scope 6 { - debug _y => _43; // in scope 6 at $DIR/enum_prop.rs:15:5: 15:21 + debug _y => _29; // in scope 6 at $DIR/enum_prop.rs:14:5: 14:21 } } scope 2 { debug x => _5; // in scope 2 at $DIR/enum_prop.rs:5:10: 5:11 - let mut _67: &[&str; 2]; // in scope 2 at $DIR/enum_prop.rs:6:16: 6:20 - scope 11 (inlined ArgumentV1::new_display::>) { // at $DIR/enum_prop.rs:6:22: 6:23 - debug x => _18; // in scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _76: &std::boxed::Box; // in scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _77: for<'r, 's, 't0> fn(&'r std::boxed::Box, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - scope 12 (inlined ArgumentV1::new::>) { // at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - debug x => _76; // in scope 12 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - debug f => _77; // in scope 12 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _78: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 12 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _79: for<'r, 's, 't0> fn(&'r std::boxed::Box, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>; // in scope 12 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _80: &core::fmt::Opaque; // in scope 12 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - let mut _81: &std::boxed::Box; // in scope 12 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - scope 13 { - } - } - } } scope 9 (inlined Box::::new) { // at $DIR/enum_prop.rs:4:22: 4:34 - debug x => _72; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _73: usize; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _74: usize; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _75: *mut u8; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + debug x => _59; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _60: usize; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _61: usize; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _62: *mut u8; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _63: *const i32; // in scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL scope 10 { } } bb0: { - _68 = const false; // scope 0 at $DIR/enum_prop.rs:4:7: 4:8 + _53 = const false; // scope 0 at $DIR/enum_prop.rs:4:7: 4:8 StorageLive(_1); // scope 0 at $DIR/enum_prop.rs:4:7: 4:8 StorageLive(_2); // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 StorageLive(_3); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 - StorageLive(_72); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 - _72 = const 10_i32; // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 - StorageLive(_73); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 - StorageLive(_74); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 - StorageLive(_75); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 - _73 = const 4_usize; // scope 10 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _74 = const 4_usize; // scope 10 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _75 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> [return: bb20, unwind: bb21]; // scope 10 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageLive(_59); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + _59 = const 10_i32; // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageLive(_60); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageLive(_61); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageLive(_62); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + _60 = const 4_usize; // scope 10 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _61 = const 4_usize; // scope 10 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _62 = alloc::alloc::exchange_malloc(const 4_usize, const 4_usize) -> [return: bb17, unwind: bb18]; // scope 10 at $SRC_DIR/alloc/src/boxed.rs:LL:COL // mir::Constant // + span: $SRC_DIR/alloc/src/boxed.rs:LL:COL - // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar()) } + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value() } } bb1: { - _1 = const 3_i32; // scope 0 at $DIR/enum_prop.rs:9:10: 9:11 - goto -> bb18; // scope 0 at $DIR/enum_prop.rs:9:10: 9:11 + _1 = const 3_i32; // scope 0 at $DIR/enum_prop.rs:8:10: 8:11 + goto -> bb15; // scope 0 at $DIR/enum_prop.rs:8:10: 8:11 } bb2: { StorageLive(_5); // scope 0 at $DIR/enum_prop.rs:5:10: 5:11 - _68 = const false; // scope 0 at $DIR/enum_prop.rs:5:10: 5:11 + _53 = const false; // scope 0 at $DIR/enum_prop.rs:5:10: 5:11 _5 = move ((_2 as Some).0: std::boxed::Box); // scope 0 at $DIR/enum_prop.rs:5:10: 5:11 - StorageLive(_6); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_7); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_8); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_9); // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 - StorageLive(_10); // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 - StorageLive(_11); // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 - _67 = const main::promoted[3]; // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 - // mir::Constant - // + span: $DIR/enum_prop.rs:6:16: 6:20 - // + literal: Const { ty: &[&str; 2], val: Unevaluated(main, [], Some(promoted[3])) } - _11 = _67; // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 - _10 = _11; // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 - _9 = move _10 as &[&str] (Pointer(Unsize)); // scope 2 at $DIR/enum_prop.rs:6:16: 6:20 - StorageDead(_10); // scope 2 at $DIR/enum_prop.rs:6:19: 6:20 - StorageLive(_13); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_14); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_15); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_16); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_17); // scope 2 at $DIR/enum_prop.rs:6:22: 6:23 - StorageLive(_18); // scope 2 at $DIR/enum_prop.rs:6:22: 6:23 - StorageLive(_19); // scope 2 at $DIR/enum_prop.rs:6:22: 6:23 - _19 = &_5; // scope 2 at $DIR/enum_prop.rs:6:22: 6:23 - _18 = _19; // scope 2 at $DIR/enum_prop.rs:6:22: 6:23 - StorageLive(_76); // scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _76 = _18; // scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_77); // scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _77 = as std::fmt::Display>::fmt as for<'r, 's, 't0> fn(&'r std::boxed::Box, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error> (Pointer(ReifyFnPointer)); // scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL - // + literal: Const { ty: for<'r, 's, 't0> fn(&'r Box, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error> { as std::fmt::Display>::fmt}, val: Value(Scalar()) } - StorageLive(_78); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_79); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _79 = _77; // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _78 = transmute:: fn(&'r Box, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error>>(move _79) -> [return: bb22, unwind: bb13]; // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(for<'r, 's, 't0> fn(&'r Box, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error>) -> for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error> {transmute:: fn(&'r Box, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error>, for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut Formatter<'t0>) -> Result<(), std::fmt::Error>>}, val: Value(Scalar()) } + StorageLive(_57); // scope 2 at $DIR/enum_prop.rs:6:7: 6:9 + _57 = (((_5.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const i32); // scope 2 at $DIR/enum_prop.rs:6:7: 6:9 + _1 = (*_57); // scope 2 at $DIR/enum_prop.rs:6:7: 6:9 + StorageDead(_57); // scope 0 at $DIR/enum_prop.rs:7:5: 7:6 + drop(_5) -> [return: bb3, unwind: bb16]; // scope 0 at $DIR/enum_prop.rs:7:5: 7:6 } bb3: { - StorageDead(_13); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageDead(_9); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - _7 = _print(move _8) -> [return: bb4, unwind: bb13]; // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/std/src/macros.rs:LL:COL - // + literal: Const { ty: for<'r> fn(Arguments<'r>) {_print}, val: Value(Scalar()) } + StorageDead(_5); // scope 0 at $DIR/enum_prop.rs:7:5: 7:6 + goto -> bb15; // scope 0 at $DIR/enum_prop.rs:7:5: 7:6 } bb4: { - StorageDead(_8); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageDead(_19); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageDead(_16); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageDead(_15); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageDead(_11); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageDead(_7); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageDead(_6); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - _1 = (*_5); // scope 2 at $DIR/enum_prop.rs:7:7: 7:9 - drop(_5) -> [return: bb5, unwind: bb19]; // scope 0 at $DIR/enum_prop.rs:8:5: 8:6 - } - - bb5: { - StorageDead(_5); // scope 0 at $DIR/enum_prop.rs:8:5: 8:6 - goto -> bb18; // scope 0 at $DIR/enum_prop.rs:8:5: 8:6 - } - - bb6: { - StorageLive(_32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Deinit(_32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - discriminant(_32) = 0; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_33); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_34); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _34 = const core::panicking::AssertKind::Eq; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_18); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_18); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_18) = 0; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_19); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _20 = const core::panicking::AssertKind::Eq; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } - StorageLive(_35); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_36); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _36 = _25; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _35 = _36; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_37); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_38); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _38 = _26; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _37 = _38; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_39); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Deinit(_39); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - discriminant(_39) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _33 = core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _35, move _37, move _39); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_21); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_22); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _22 = _11; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _21 = _22; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_23); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_24); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _24 = _12; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _23 = _24; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_25); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_25); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_25) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _19 = core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _21, move _23, move _25); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL - // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option>) -> ! {core::panicking::assert_failed::}, val: Value(Scalar()) } + // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option>) -> ! {core::panicking::assert_failed::}, val: Value() } // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } } - bb7: { - StorageDead(_27); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_26); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_25); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_21); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_20); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_40); // scope 1 at $DIR/enum_prop.rs:14:7: 14:8 - StorageLive(_41); // scope 1 at $DIR/enum_prop.rs:14:17: 14:24 - Deinit(_41); // scope 1 at $DIR/enum_prop.rs:14:17: 14:24 - ((_41 as Some).0: i32) = const 1_i32; // scope 1 at $DIR/enum_prop.rs:14:17: 14:24 - discriminant(_41) = 1; // scope 1 at $DIR/enum_prop.rs:14:17: 14:24 - _42 = const 1_isize; // scope 1 at $DIR/enum_prop.rs:14:17: 14:24 - switchInt(const 1_isize) -> [0_isize: bb8, otherwise: bb9]; // scope 1 at $DIR/enum_prop.rs:14:11: 14:24 + bb5: { + StorageDead(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_12); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_11); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_7); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_6); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_26); // scope 1 at $DIR/enum_prop.rs:13:7: 13:8 + StorageLive(_27); // scope 1 at $DIR/enum_prop.rs:13:17: 13:24 + Deinit(_27); // scope 1 at $DIR/enum_prop.rs:13:17: 13:24 + ((_27 as Some).0: i32) = const 1_i32; // scope 1 at $DIR/enum_prop.rs:13:17: 13:24 + discriminant(_27) = 1; // scope 1 at $DIR/enum_prop.rs:13:17: 13:24 + _28 = const 1_isize; // scope 1 at $DIR/enum_prop.rs:13:17: 13:24 + switchInt(const 1_isize) -> [0_isize: bb6, otherwise: bb7]; // scope 1 at $DIR/enum_prop.rs:13:11: 13:24 } - bb8: { - _40 = const 2_i32; // scope 1 at $DIR/enum_prop.rs:16:13: 16:14 - goto -> bb10; // scope 1 at $DIR/enum_prop.rs:16:13: 16:14 + bb6: { + _26 = const 2_i32; // scope 1 at $DIR/enum_prop.rs:15:13: 15:14 + goto -> bb8; // scope 1 at $DIR/enum_prop.rs:15:13: 15:14 } - bb9: { - StorageLive(_43); // scope 1 at $DIR/enum_prop.rs:15:5: 15:21 - _65 = const main::promoted[1]; // scope 1 at $DIR/enum_prop.rs:15:5: 15:21 + bb7: { + StorageLive(_29); // scope 1 at $DIR/enum_prop.rs:14:5: 14:21 + _51 = const main::promoted[1]; // scope 1 at $DIR/enum_prop.rs:14:5: 14:21 // mir::Constant - // + span: $DIR/enum_prop.rs:15:5: 15:21 + // + span: $DIR/enum_prop.rs:14:5: 14:21 // + literal: Const { ty: &Option, val: Unevaluated(main, [], Some(promoted[1])) } - _43 = _65; // scope 1 at $DIR/enum_prop.rs:15:5: 15:21 - _40 = const 1_i32; // scope 6 at $DIR/enum_prop.rs:15:25: 15:26 - StorageDead(_43); // scope 1 at $DIR/enum_prop.rs:15:25: 15:26 - goto -> bb10; // scope 1 at $DIR/enum_prop.rs:15:25: 15:26 + _29 = _51; // scope 1 at $DIR/enum_prop.rs:14:5: 14:21 + _26 = const 1_i32; // scope 6 at $DIR/enum_prop.rs:14:25: 14:26 + StorageDead(_29); // scope 1 at $DIR/enum_prop.rs:14:25: 14:26 + goto -> bb8; // scope 1 at $DIR/enum_prop.rs:14:25: 14:26 } - bb10: { - StorageDead(_41); // scope 1 at $DIR/enum_prop.rs:17:4: 17:5 - StorageLive(_44); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_45); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_46); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _46 = &_40; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_47); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _64 = const main::promoted[0]; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + bb8: { + StorageDead(_27); // scope 1 at $DIR/enum_prop.rs:16:4: 16:5 + StorageLive(_30); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_31); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_32); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _32 = &_26; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_33); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _50 = const main::promoted[0]; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } - _47 = _64; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Deinit(_45); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_45.0: &i32) = move _46; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_45.1: &i32) = move _47; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_47); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_46); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_49); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _49 = (_45.0: &i32); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_50); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _50 = (_45.1: &i32); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_51); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_52); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_53); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _53 = (*_49); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_54); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _54 = const 1_i32; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _52 = Eq(move _53, const 1_i32); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_54); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_53); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _51 = Not(move _52); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_52); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - switchInt(move _51) -> [false: bb12, otherwise: bb11]; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _33 = _50; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_31); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_31.0: &i32) = move _32; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_31.1: &i32) = move _33; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_33); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_32); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _35 = (_31.0: &i32); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_36); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _36 = (_31.1: &i32); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_37); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_38); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_39); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _39 = (*_35); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_40); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _40 = const 1_i32; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _38 = Eq(move _39, const 1_i32); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_40); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_39); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _37 = Not(move _38); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_38); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _37) -> [false: bb10, otherwise: bb9]; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } - bb11: { - StorageLive(_56); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Deinit(_56); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - discriminant(_56) = 0; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_57); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_58); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _58 = const core::panicking::AssertKind::Eq; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + bb9: { + StorageLive(_42); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_42); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_42) = 0; // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_43); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_44); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _44 = const core::panicking::AssertKind::Eq; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } - StorageLive(_59); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_60); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _60 = _49; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _59 = _60; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_61); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_62); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _62 = _50; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _61 = _62; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_63); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Deinit(_63); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - discriminant(_63) = 0; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _57 = core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _59, move _61, move _63); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_45); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_46); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _46 = _35; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _45 = _46; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_47); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_48); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _48 = _36; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _47 = _48; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_49); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_49); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_49) = 0; // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _43 = core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _45, move _47, move _49); // scope 8 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL - // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option>) -> ! {core::panicking::assert_failed::}, val: Value(Scalar()) } + // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, Option>) -> ! {core::panicking::assert_failed::}, val: Value() } // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } } - bb12: { - StorageDead(_51); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_50); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_49); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_45); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_44); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_40); // scope 1 at $DIR/enum_prop.rs:20:1: 20:2 - StorageDead(_1); // scope 0 at $DIR/enum_prop.rs:20:1: 20:2 - return; // scope 0 at $DIR/enum_prop.rs:20:2: 20:2 - } - - bb13 (cleanup): { - drop(_5) -> bb19; // scope 0 at $DIR/enum_prop.rs:8:5: 8:6 + bb10: { + StorageDead(_37); // scope 7 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_36); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_35); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_31); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_30); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_26); // scope 1 at $DIR/enum_prop.rs:19:1: 19:2 + StorageDead(_1); // scope 0 at $DIR/enum_prop.rs:19:1: 19:2 + return; // scope 0 at $DIR/enum_prop.rs:19:2: 19:2 } - bb14 (cleanup): { - resume; // scope 0 at $DIR/enum_prop.rs:3:1: 20:2 + bb11 (cleanup): { + resume; // scope 0 at $DIR/enum_prop.rs:3:1: 19:2 } - bb15: { - _68 = const false; // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 - StorageDead(_2); // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 - StorageLive(_20); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_21); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_22); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _22 = &_1; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_23); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _66 = const main::promoted[2]; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + bb12: { + _53 = const false; // scope 0 at $DIR/enum_prop.rs:9:4: 9:5 + StorageDead(_2); // scope 0 at $DIR/enum_prop.rs:9:4: 9:5 + StorageLive(_6); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_7); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_8); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _8 = &_1; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_9); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _52 = const main::promoted[2]; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[2])) } - _23 = _66; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Deinit(_21); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_21.0: &i32) = move _22; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_21.1: &i32) = move _23; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_23); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_22); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_25); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _25 = (_21.0: &i32); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_26); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _26 = (_21.1: &i32); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_27); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_28); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_29); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _29 = (*_25); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_30); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _30 = const 10_i32; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _28 = Eq(move _29, const 10_i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_30); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_29); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _27 = Not(move _28); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_28); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - switchInt(move _27) -> [false: bb7, otherwise: bb6]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _9 = _52; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_7); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_7.0: &i32) = move _8; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_7.1: &i32) = move _9; // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_9); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_8); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_11); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _11 = (_7.0: &i32); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_12); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _12 = (_7.1: &i32); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_15); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _15 = (*_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_16); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _16 = const 10_i32; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _14 = Eq(move _15, const 10_i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_16); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_15); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _13 = Not(move _14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _13) -> [false: bb5, otherwise: bb4]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } - bb16: { - switchInt(_68) -> [false: bb15, otherwise: bb17]; // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + bb13: { + switchInt(_53) -> [false: bb12, otherwise: bb14]; // scope 0 at $DIR/enum_prop.rs:9:4: 9:5 } - bb17: { - drop(((_2 as Some).0: std::boxed::Box)) -> [return: bb15, unwind: bb14]; // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + bb14: { + drop(((_2 as Some).0: std::boxed::Box)) -> [return: bb12, unwind: bb11]; // scope 0 at $DIR/enum_prop.rs:9:4: 9:5 } - bb18: { - _69 = discriminant(_2); // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 - switchInt(move _69) -> [1_isize: bb16, otherwise: bb15]; // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + bb15: { + _54 = discriminant(_2); // scope 0 at $DIR/enum_prop.rs:9:4: 9:5 + switchInt(move _54) -> [1_isize: bb13, otherwise: bb12]; // scope 0 at $DIR/enum_prop.rs:9:4: 9:5 } - bb19 (cleanup): { - _71 = discriminant(_2); // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 - goto -> bb14; // scope 0 at $DIR/enum_prop.rs:10:4: 10:5 + bb16 (cleanup): { + _56 = discriminant(_2); // scope 0 at $DIR/enum_prop.rs:9:4: 9:5 + goto -> bb11; // scope 0 at $DIR/enum_prop.rs:9:4: 9:5 } - bb20: { - _3 = ShallowInitBox(move _75, i32); // scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - (*_3) = const 10_i32; // scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageDead(_75); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 - StorageDead(_74); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 - StorageDead(_73); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 - StorageDead(_72); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 - _68 = const true; // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 + bb17: { + _3 = ShallowInitBox(move _62, i32); // scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageLive(_63); // scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _63 = (((_3.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const i32); // scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + (*_63) = const 10_i32; // scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_63); // scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_62); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageDead(_61); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageDead(_60); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + StorageDead(_59); // scope 0 at $DIR/enum_prop.rs:4:22: 4:34 + _53 = const true; // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 Deinit(_2); // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 ((_2 as Some).0: std::boxed::Box) = move _3; // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 discriminant(_2) = 1; // scope 0 at $DIR/enum_prop.rs:4:17: 4:35 @@ -434,42 +353,8 @@ switchInt(move _4) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/enum_prop.rs:4:11: 4:35 } - bb21 (cleanup): { + bb18 (cleanup): { resume; // scope 9 at $SRC_DIR/alloc/src/boxed.rs:LL:COL } - - bb22: { - StorageDead(_79); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_80); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageLive(_81); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _81 = _76; // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - _80 = transmute::<&Box, &core::fmt::Opaque>(move _81) -> [return: bb23, unwind: bb13]; // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/fmt/mod.rs:LL:COL - // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(&Box) -> &core::fmt::Opaque {transmute::<&Box, &core::fmt::Opaque>}, val: Value(Scalar()) } - } - - bb23: { - StorageDead(_81); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - Deinit(_17); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_17.0: &core::fmt::Opaque) = move _80; // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - (_17.1: for<'r, 's, 't0> fn(&'r core::fmt::Opaque, &'s mut std::fmt::Formatter<'t0>) -> std::result::Result<(), std::fmt::Error>) = move _78; // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_80); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_78); // scope 13 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_77); // scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_76); // scope 11 at $SRC_DIR/core/src/fmt/mod.rs:LL:COL - StorageDead(_18); // scope 2 at $DIR/enum_prop.rs:6:22: 6:23 - _16 = [move _17]; // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageDead(_17); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - _15 = &_16; // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - _14 = _15; // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - _13 = move _14 as &[std::fmt::ArgumentV1] (Pointer(Unsize)); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageDead(_14); // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - _8 = Arguments::new_v1(move _9, move _13) -> [return: bb3, unwind: bb13]; // scope 2 at $SRC_DIR/std/src/macros.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/std/src/macros.rs:LL:COL - // + user_ty: UserType(1) - // + literal: Const { ty: fn(&[&'static str], &[ArgumentV1]) -> Arguments {Arguments::new_v1}, val: Value(Scalar()) } - } } diff --git a/src/test/mir-opt/enum_prop.rs b/src/test/mir-opt/enum_prop.rs index 7c7aa8333bf03..8d88fb7f3e825 100644 --- a/src/test/mir-opt/enum_prop.rs +++ b/src/test/mir-opt/enum_prop.rs @@ -3,7 +3,6 @@ fn main() { let v = match Some(Box::new(10)) { Some(x) => { - println!("{}", x); *x }, _ => 3,